zoukankan      html  css  js  c++  java
  • 检测浏览器对事件的支持程度

    自从jQuery搞出特性侦探这东东,西方从来没有如此狂热研究浏览器。在以前javascript与DOM遍地是bug,美工主宰前端的年代,人们只有两种极端方式,用户禁止脚本运行,浏览器商狂升级(IE6之前也很积极的)。这年头,也就Base2与Prototype2做得最好,当然dojo与YUI也不错。不过最近五年,Opera与Safari都建立了对DOM完整的支持后,世界分两半,一半是IE统治的混乱世界,它是拥有如此丰富的私有特征,CSS表达式,HTC,CSS滤镜,VML,userData,XML数据岛,最早的AJAX支持,以及DHTML最好的支持API(innerHTML,innerText,outerHTML,outerText,insertAdjactentXXX,offsetXXX,clientXXX,scrollXXX,Range,designMode,sertRow和insertCell等动态操作表格API……),难怪IE会赢的!不过IE也埋下了许多地雷,加之IE不会其他游览器升级那么快,许多Bug都要我们亲手修正。这么多浏览器,这么多版本,特性侦探是很有必要。现在我们看到那一套关于事件的API,基本上是微软从桌面搬过来,后来W3C又加一大堆与DOM开头的事件,不过除了DOMMouseScroll基本没什么人用。N多事件,与逐个嗅探浏览器那样成了个头痛的问题。

    John Resig说过类库就是用来屏蔽浏览器的差异的。在国外这篇文章中,就有对事件支持的详尽分析(注,那个博客是John Resig经常去的,你可以把它当成的jQuery核心小组的酒吧,他们与其他高手经常在那里讨论浏览器的天方夜谭,研究javascript的炼金术)。在事件系统中,很明显的几个,IE支持mouseenter与mouseleave,Opera支持右键菜单但不允许你用contextmenu类似的API操作它,还有onbeforepaste, onbeforecut这些与input元素相关的事件,IE与WebKit支持,但FF不支持……非常混乱。一般我们可以用for...in循环把它遍历一下,或者像以下简单地检测:

      'onclick' in document.documentElement; // true
      'onclick2' in document.documentElement; // false
    

    很不幸,这不准确,因为我们可以添加一些同名的自定义属性。有人说,赶在用户添加之前检测它们,但也行不通,因此有些事件是只有特定元素才有的。

      'onreset' in document.documentElement; // false
      'onreset' in document.createElement('input'); // true
    

    在标准浏览器我们可以用setAttrubute为元素赋以已知事件名一个值,这个值会自动包装成一个函数,如果非事件名,则不会改变其类型。那么我检测它是否为函数就是!

     var el = document.createElement('div');
    
      el.setAttribute('onclick', 'return;');
      alert(typeof el.onclick); // "function"
    
      el.setAttribute('onclick2', 'return;');
      alert(typeof el.onclick2); // "undefined"
    

    同样很不幸,基于众所周知的原因,IE的setAttribute与W3C是有很大的差别,IE会原样输出,加之,IE不存在所谓的泛化函数(原生对象的方法),它的API没有name,call,apply与toString,因此也无法判定它们是否为函数。综合以上两种方式,看看外国人搞出什么怪物来……

      var isEventSupported = (function(){//使用模块模式
    
              var TAGNAMES = {//特定元素上的特定事件
                'select':'input','change':'input',
                'submit':'form','reset':'form',
                'error':'img','load':'img','abort':'img'
              }
    
              function isEventSupported(eventName, element) {
    
                element = element || document.createElement(TAGNAMES[eventName] || 'div');
                eventName = 'on' + eventName;
    
                // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
                var isSupported = (eventName in element);//DOM0
    
                if (!isSupported) {
                  // if it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
                  if (!element.setAttribute) {
                    element = document.createElement('div');
                  }
                  if (element.setAttribute && element.removeAttribute) {
                    element.setAttribute(eventName, '');
                    isSupported = typeof element[eventName] == 'function';
    
                    // if property was created, "remove it" (by setting value to `undefined`)
                    if (typeof element[eventName] != 'undefined') {
                      element[eventName] = void 0;
                    }
                    element.removeAttribute(eventName);
                  }
                }
    
                element = null;
                return isSupported;
              }
              return isEventSupported;
            })();
    
    

    连HTML5与iPhone touch的一些专有事件也能检测到。

    在jQuery1.4α2中也支持这种特性侦探了,不过用的是早期版本,不如上面写出来的那个!

    //jQuery1.4α2
    	var eventSupported = function( eventName ) { 
    		var el = document.createElement("div"); 
    		eventName = "on" + eventName; 
    
    		var isSupported = (eventName in el); 
    		if ( !isSupported ) { 
    			el.setAttribute(eventName, "return;"); 
    			isSupported = typeof el[eventName] === "function"; 
    		} 
    		el = null; 
    
    		return isSupported; 
    	};
    
  • 相关阅读:
    POJ 1141 括号匹配 DP
    881. Boats to Save People
    870. Advantage Shuffle
    874. Walking Robot Simulation
    文件操作
    861. Score After Flipping Matrix
    860. Lemonade Change
    842. Split Array into Fibonacci Sequence
    765. Couples Holding Hands
    763. Partition Labels
  • 原文地址:https://www.cnblogs.com/rubylouvre/p/1628095.html
Copyright © 2011-2022 走看看