Как через js установить css-свойства с префиксами?
Мне через JS нужно задать css-свойства и свойство transition в том числе. Хочу добавить через JS вендорные префиксы. С использованием cssText скрипт не работает, а без них добавляется просто transition без префиксов. Как мне через JS добавить transition с префиксами?
document.addEventListener('DOMContentLoaded', () => {
class MenuToggler{
constructor(data){
this.menuTriggerSelector = data.menuTriggerSelector;
this.menuSelector = data.menuSelector;
this.type = data.type || 'appear'; //type of Apperance
this.menuTrigger = document.querySelector(`${this.menuTriggerSelector}`);
this.menu = document.querySelector(`${this.menuSelector}`);
this.transitionTime = data.transitionTime || '.25s';
this.init();
}
init(){
if (this.type == 'appear'){
// add first styles, makes elem invisible and untouchuble
this.menu.style.height = '0px';
this.menu.style.opacity = '0';
this.menu.style.transition = `opacity ${this.transitionTime} linear ${this.transitionTime}, height 0s linear 0s`;
this.menu.style.cssText = `-webkit-transition: opacity ${this.transitionTime} linear ${this.transitionTime}, height 0s linear 0s`;
this.menu.style.cssText = `-o-transition: opacity ${this.transitionTime} linear ${this.transitionTime}, height 0s linear 0s`;
}
}
}
const menuToggler1 = new MenuToggler({
menuTriggerSelector: '.burger',
menuSelector: '.links-wrapper'
});
});
Ответы (2 шт):
С помощью kebab-case -> camelCase
-webkit-transition превращается в webkitTransition
// Можно посмотреть как это выглядит на примере всех стилей,
// которые начинаются с align...
const div = document.createElement('div')
document.body.appendChild(div)
Object.entries(getComputedStyle(div))
.filter(([p, v]) => (p.startsWith('align') || v.startsWith('align')))
.forEach(([p, v]) => console.log(`${p} -> ${v}`))
UPDATE: Вышеуказанные свойства не могут существовать во всех браузерах сразу
- -webkit- (Chrome, Safari, iOS Safari / iOS WebView, Android)
- -moz- (Fire Fox)
- -ms- (Edge, Internet Explorer)
- -o- (Opera, Opera Mini)
... и, соответственно, установить их и просмотреть в консоли нет возможности.
Если есть желание устанавливать префикс через JS, необходимо проверять наличие искомого свойства. Делать это в каждой строчке кода неразумно.
Пишем небольшую библиотеку. Наша задача делегировать корректную установку префиксов для любого браузера, без использования этих самых префиксов.
// Определение всех доступных префиксов
const stylePrefix = (() => {
const prefix = ['webkit', 'moz', 'ms', 'o'].join('|')
const replace = new RegExp(`^(${prefix})([A-Z])`)
// Создадим карту соответствия имен
const sp = new Map( /* "appRegion" => "webkitAppRegion", ... и т.д. */ )
const all = Object.keys(window.getComputedStyle(document.createElement('div')))
.filter((v) => !/[0-9]/.test(v))
for (let s of all) {
if (!replace.test(s)) {
continue
}
// Некоторые стили повторяются и могут быть доступны как с префиксами, так и без
// ... те что доступны не устанавливаем в sp:Map
// webkitTransition => transition
let pr = s.replace(replace, (_, __, ch) => ch.toLowerCase())
if (!all.includes(pr))
sp.set(pr, s)
}
// Кому интересно, можете скопировать участок кода "const stylePrefix = (...)()"
// в консоль браузера и расскоментить эту строку
// console.log(sp)
return {
has(s) {
return sp.has(s)
},
get(s) {
return sp.has(s) ? sp.get(s) : null
}
}
})()
// Пихаем это в нашу библиотеку
const myLib = {
// Тут мы будем управлять стилями
style: {
set(element, styles) {
for (let [s, v] of Object.entries(styles)) {
element.style[stylePrefix.get(s) || s] = v
} //, ...
}
},
//...
}
// Далее используем в коде
const p = document.querySelector('p')
myLib.style.set(p,
// Вот так удобнее использовать в любом участке кода,
// и нет необходимости указывать префиксы
{
border: 'solid 10px #9e9e9e',
borderStartColor: 'red' // НЕподдерживаемый стиль -webkit-border-start-color
}
)
// Смотрим что реально установилось
console.log(`borderStartColor: ${p.style.borderStartColor}`)
console.log(`webkitBorderStartColor: ${p.style.webkitBorderStartColor}`)
<p>Этому параграфу будет установлен -webkit-border-start-color</p>
this.menu.style.MozTransition = '...';
this.menu.style.WebkitTransition = '...';
this.menu.style.transition = '...';
Также обратите внимание на порядок свойств, свойство без префиксов нужно всегда давать в последнюю очередь. Иначе может быть так, что браузер поддерживает transition и -webkit-transition, но последним у Вас указан именно -webkit-*, то применится именно он. А это в свою очередь может повлечь ряд проблем с производительностью, как так префиксные свойства "под капотом" могут работать с багами.