zoukankan      html  css  js  c++  java
  • 使用javascript判断浏览器对css3的支持情况【译】

    Quick Tip: Detect CSS3 Support in Browsers with JavaScript

    步骤 1

    首先我们要确定我们想如何调用 函数。在这里我们会简化我们的方法调用如下:

    if ( supports('textShadow') ) {     
        document.documentElement.className += ' textShadow';  
    }  

    这应是最终的函数调用方式,即当我们给supports()函数传递一个CSS属性名称的时候,它会返回一个boolean。如果为true,则将classname附加到documentElement 或<html>上。这样我们就有了一个新的可用类名。


    步骤 2

    下一步,构建supports()函数。

    1. var supports = (function() {  
        
      })();  

    我们为什么不把supports函数构建成标准函数的样子呢?——因为我们需要先做一些准备工作,而我们显然不应当每次调用函数的时候,都去重复这些准备工作。因此,最好使supports函数等于它自己执行的函数所返回的内容(it’s best to make supports equal to whatever is returned from the self-executing function)。


    步骤 3

    为了测试浏览器是否支持特定的属性,我们需要创建一个“哑巴”元素,这个动态创建的哑巴元素实际上不会插入到DOM中。

    1. var div = document.createElement('div'); 

    相信你已经注意到,当使用CSS3新属性时,我们有很多可以使用的代理前缀:

    • -moz
    • -webkit
    • -o
    • -ms
    • -khtml

    我们的函数需要过滤并检测这些前缀,所以让我们把这些前缀放到一个数组里,数组名为vendors:

    1. var div = document.createElement('div'),  
          vendors = 'Khtml Ms O Moz Webkit'.split(' ');  

    的确,使用split()函数从字符串中创建数组比较懒,但是确实很节省时间~~嘿嘿

    我们即将通过这个数组来进行过滤,同时也存储一下这个数组的长度。

    1. var div = document.createElement('div'),  
        vendors = 'Khtml Ms O Moz Webkit'.split(' '),  
        len = vendors.length;  

    以上就是supports()的准备工作,因为它是静态的,所以不需要每次调用supports()的时候都执行一次。这也是为什么当页面加载时,我们只执行一次。 现在让我们return实际赋值给supports变量的函数吧。

    1. return function(prop) {  
        
      };  

    闭包的魅力在于,即使supports()函数与返回的函数一样,它还是可以使用div,vendors和len变量。


    步骤 4

    快速检测:如果传递的属性是有效的div style属性,那么浏览器支持这个属性,返回true:

    1. return function(prop) {  
         if ( prop in div.style ) return true;  
      };  

    比如CSS3属性 text-shadow,大多数的现代浏览器都默认支持它,不需要给它添加代理前缀。所以我们没有必要给所有的属性都添加一个代理前缀,也因此我们无需在一开始就检测代理前缀。

     

    步骤 5

    你可能喜欢这样写CSS3的属性名称,如 -moz-box-shadow,然而如果在Firebug中查看类型对象(style object),你会发现它拼作MozBoxShadow。因此,如果我们这样检测:

    1. 'mozboxShadow' in div.style // false  

    它会返回false,这个值是大小写敏感的。

    Case Sensitive

    这就意味着,如果用户给supprots()函数传参boxShadow会检测失败。所以我们要先检查参数的第一个字母是不是小写。如果是小写,就要转成大写。

    return function(prop) {  
       if ( prop in div.style ) return true;  
      
       prop = prop.replace(/^[a-z]/, function(val) {  
          return val.toUpperCase();  
       });  
      
    };  

    这里我们使用了正则表达式来修正它。在上面这段代码中,我们检查了首字母是否是小写(^),如果是小写我们就用toUpperCase()将其转换为大写字母。


    步骤 6

    下一步我们来用vendors数组进行过滤,检测是否存在匹配的项;比如,如果我们传递box-shadow,我们需要检查div的style属性是否包含以下中的一个:

    • MozBoxShadow
    • WebkitBoxShadow
    • MsBoxShadow
    • OBoxShadow
    • KhtmlBoxShadow

    如果有匹配项,就返回true,因为浏览器本身提供了对box shadows的支持。

    return function(prop) {  
       if ( prop in div.style ) return true;  
      
       prop = prop.replace(/^[a-z]/, function(val) {  
          return val.toUpperCase();  
       });  
      
       while(len--) {  
          if ( vendors[len] + prop in div.style ) {  
                return true;         
          }   
       }    
    };  

    尽管我们可以对数组进行for循环来过滤匹配项,但是在这个问题中上我们没必要这么做,因为:

    • array元素的顺序并不重要
    • while语句写起来更快速并且写的字符也更少
    • 有一点点的性能提高

    不要被vendors[len] + prop这个语句所迷惑,只要把那些名称替换为真实的值就可以了:MozBoxShadow


    步骤 7

    但是,如果以上的值全都不匹配呢?这种情况下,浏览器很有可能不支持这个属性,那么就应该返回false。

    1. while(len--) {  
         if ( vendors[len] + prop in div.style ) {  
               return true;         
         }   
      }   
      return false; 

    That should do it for our function! Let’s test it out, by applying a className to the html element, if the browser supports, say, the text-stroke property (which only webkit does).

    好啦,现在我们来测试一下我们的函数吧! 通过给html元素添加一个类名称(className),如text-stroke(仅webkit支持),来测试一下吧!

    if ( supports('textStroke') ) {  
       document.documentElement.className += ' textStroke';  
    }  

    步骤8: 用法

    现在我们可以检测类名了,让我们一起测试一下。

    /* fallback */  
    h1 {  
       color: black;  
    }     
      
    /* text-stroke支持 */  
    .textStroke h1 {  
      color: white;  
      -webkit-text-stroke: 2px black;  
    }  

    最终源代码

    var supports = (function() {  
       var div = document.createElement('div'),  
          vendors = 'Khtml Ms O Moz Webkit'.split(' '),  
          len = vendors.length;  
      
       return function(prop) {  
          if ( prop in div.style ) return true;  
      
          prop = prop.replace(/^[a-z]/, function(val) {  
             return val.toUpperCase();  
          });  
      
          while(len--) {  
             if ( vendors[len] + prop in div.style ) {  
                // 浏览器支持box-shadow,做你需要的操作吧!
                // 或如果浏览器不支持,就用使用叹号(!)检测 Or use a bang (!) to test if the browser doesn't.  
                return true;  
             }   
          }  
          return false;  
       };  
    })();  
      
    if ( supports('textShadow') ) { 
       document.documentElement.className += ' textShadow';  
    }  

    如若获取更广泛的解决方案,请参考Modernizr library.

  • 相关阅读:
    elasticsearch如何设计索引
    LinkedList 的实现原理
    聊聊elasticsearch7.8的模板和动态映射
    elasticsearch7.8权限控制和规划
    cloudera manager server迁移
    2020年终总结
    工作两年半的一次复盘
    聊聊数据结构和算法
    AutoMapper源码解析
    [源码解析] 并行分布式框架 Celery 之 worker 启动 (2)
  • 原文地址:https://www.cnblogs.com/zldream1106/p/test-css3-support.html
Copyright © 2011-2022 走看看