使用JavaScript根据浏览器为CSS属性添加前缀

有时候,你想要使用一种CSS属性,但并不是所有浏览器都支持它。浏览器通常通过使用厂商前缀来支持这些属性,厂商前缀是一个字符串,会添加到属性名称之前。例如,Safari使用-webkit-,Firefox使用-moz-等。

但是,你如何检测浏览器是否支持某个CSS属性?以及如何根据当前浏览器为CSS属性添加前缀?幸运的是,CSSStyleDeclaration接口为所有支持的CSS属性提供了带有连字符和驼峰命名的属性。

为了使用这个接口,你可以访问Document.body对象的style属性。然后,你可以检查属性是否定义为原样或带有厂商前缀。

// 检查 'appearance' 属性是否定义
typeof document.body.style.appearance !== 'undefined';

// 显式检查 'webkitAppearance' 属性
typeof document.body.style.webkitAppearance !== 'undefined';

这对于检查特定属性或浏览器环境非常简单,但是对于多个属性和浏览器来说,这样做很麻烦。由于浏览器前缀是众所周知的,你可以使用一个前缀数组来逐个检查它们。

// 已知的浏览器前缀(默认属性为空字符串)
const prefixes = ['', 'webkit', 'moz', 'ms', 'o'];

可以使用CSSStyleDeclaration接口的驼峰命名属性来检查带前缀的属性。你可以使用String.prototype.charAt()String.prototype.toUpperCase()将属性名称首字母大写,然后将其附加到厂商前缀字符串上。

const prop = 'appearance';
const prefixes = ['', 'webkit', 'moz', 'ms', 'o'];
const capitalizedProp = prop.charAt(0).toUpperCase() + prop.slice(1);

最后,你可以使用`Array.prototype.findIndex()`来检查`Document.body`是否具有在其`CSSStyleDeclaration`对象中定义的带前缀的属性。如果有,你可以返回带前缀的属性,否则返回`null`。

```js
const prefix = prop => {
  const capitalizedProp = prop.charAt(0).toUpperCase() + prop.slice(1);
  const prefixes = ['', 'webkit', 'moz', 'ms', 'o'];
  const i = prefixes.findIndex(
    prefix =>
      typeof document.body.style[prefix ? prefix + capitalizedProp : prop] !==
      'undefined'
  );
  return i !== -1 ? (i === 0 ? prop : prefixes[i] + capitalizedProp) : null;
};

prefix('appearance');
// 在支持的浏览器上返回'appearance',否则返回'webkitAppearance'、'mozAppearance'、'msAppearance'或'oAppearance'