js判斷並告知支持css屬性(值)的何種狀況

前言

當咱們想用某個css新特性時,老是會在乎它的兼容性狀況,或許咱們會去搜索它的兼容性,哪些瀏覽器合適哪些不合適,在這些已知的狀況下再選擇是否是使用或如何使用,這是一個已知咱們即將用於什麼瀏覽器下做出的選擇。css

但咱們每每不知道本身開發的頁面用戶會在哪一個瀏覽器上進行打開,這時咱們須要根據實際使用瀏覽器狀況來判斷採用何策略。這時就須要用js來判斷,咱們要使用css屬性可否起效。es6

css屬性的兼容性,是有兩類的,一類是,css屬性自己,如position;另外一類是,css屬性值,如,對於position屬性的stickyweb

目標

咱們想知道某個css屬性(值)是否起效,通常被告知結果是「起效」或「不起效」。可是css屬性存在瀏覽器私有屬性一說,即會有加了瀏覽器前綴纔會生效的css屬性。瀏覽器

因此你更加須要知道,對於目前瀏覽器來講,哪一個前綴或不須要前綴的css屬性纔會起效,而不單單是知道起效與否(本身每一個前綴做爲輸入值進行校驗,是繁瑣的!網絡上的不少資料每每會告訴你是否支持你指定的css,返回的boolean值)網絡

因此下面的方法,只須要你把css屬性(值)做爲輸入值,不須要帶上前綴,便能告知你,當前使用的瀏覽器支持哪一個前綴的用法或壓根不須要前綴。性能

檢查css屬性名

該方法檢查的是css的屬性自己,即屬性名,即寫css的時候:的左側。若是返回值是空,那麼證實瀏覽器不支持該屬性。ui

/** * 告知瀏覽器支持的指定css屬性狀況 * @param {String} key - css屬性,是屬性的名字,不須要加前綴 * @returns {String} - 支持的屬性狀況 */
function validateCssKey(key) {
    const jsKey = toCamelCase(key); // 有些css屬性是連字符號造成
    if (jsKey in document.documentElement.style) {
        return key;
    }
    let validKey = '';
    // 屬性名爲前綴在js中的形式,屬性值是前綴在css中的形式
    // 經嘗試,Webkit 也但是首字母小寫 webkit
    const prefixMap = {
        Webkit: '-webkit-',
        Moz: '-moz-',
        ms: '-ms-',
        O: '-o-'
    };
    for (const jsPrefix in prefixMap) {
        const styleKey = toCamelCase(`${jsPrefix}-${jsKey}`);
        if (styleKey in document.documentElement.style) {
            validKey = prefixMap[jsPrefix] + key;
            break;
        }
    }
    return validKey;
}

/** * 把有連字符號的字符串轉化爲駝峯命名法的字符串 */
function toCamelCase(value) {
    return value.replace(/-(\w)/g, (matched, letter) => {
       return letter.toUpperCase();
   });
}
複製代碼

檢查css屬性值

該方法檢查的是css的屬性的值,即寫css的時候:的右側。若是返回值是空,那麼證實瀏覽器不支持該屬性值。spa

這裏分爲兩個版本,一個是es6版本,一個是基礎的js版本。code

純屬本身多餘寫了兩個版本regexp

/** * 檢查瀏覽器是否支持某個css屬性值(es6版) * @param {String} key - 檢查的屬性值所屬的css屬性名 * @param {String} value - 要檢查的css屬性值(不要帶前綴) * @returns {String} - 返回瀏覽器支持的屬性值 */
function valiateCssValue (key, value) {
    const prefix = ['-o-', '-ms-', '-moz-', '-webkit-', ''];
    const prefixValue = prefix.map(item => {
        return item + value;
    });
    const element = document.createElement('div');
    const eleStyle = element.style;
    // 應用每一個前綴的狀況,且最後也要應用上沒有前綴的狀況,看最後瀏覽器起效的何種狀況
    // 這就是最好在prefix裏的最後一個元素是''
    prefixValue.forEach(item => {
        eleStyle[key] = item;
    });
    return eleStyle[key];
}

/** * 檢查瀏覽器是否支持某個css屬性值 * @param {String} key - 檢查的屬性值所屬的css屬性名 * @param {String} value - 要檢查的css屬性值(不要帶前綴) * @returns {String} - 返回瀏覽器支持的屬性值 */
function valiateCssValue (key, value) {
    var prefix = ['-o-', '-ms-', '-moz-', '-webkit-', ''];
    var prefixValue = [];
    for (var i = 0; i < prefix.length; i++) {
        prefixValue.push(prefix[i] + value)
    }
    var element = document.createElement('div');
    var eleStyle = element.style;
    for (var j = 0; j < prefixValue.length; j++) {
         eleStyle[key] = prefixValue[j];
    }
    return eleStyle[key];
}
複製代碼

總結

咱們能夠簡單地上述對於兩種形式的css兼容性進行合併,不用顯式地採用調用檢查屬性名仍是屬性值的方法,直接傳入css,告知瀏覽器支持的狀況。

function validCss (key, value) {
    const validCss = validateCssKey(key);
    if (validCss) {
        return validCss;
    }
    return valiateCssValue(key, value);
}
複製代碼

未經容許,請勿私自轉載

相關文章
相關標籤/搜索