【问题标题】:Javascript detect event handlers available on HTML elementJavascript 检测 HTML 元素上可用的事件处理程序
【发布时间】:2011-02-21 07:16:43
【问题描述】:

有没有办法检测 HTML 元素原生可用的事件处理程序?

例如:

isAvailable(img.onload) === true;    // All browsers
isAvailable(script.onload) === true; // Non-IE only (Webkit, Firefox, Opera)
isAvailable(link.onload) === true;   // IE (and I think Opera) only

理想情况下,我想在我的脚本中进行特征检测,如果onload 可用于元素使用它,否则回退。目前我不得不做浏览器分支(基于 IE),这很烦人,因为 IE 可能开始支持script.onload,而 Webkit/Firefox 可能开始支持link.onload

不幸的是,分配element.onload 使事件不再“未定义”,无论它最终是否会触发。

【问题讨论】:

    标签: javascript dom events dom-events onload


    【解决方案1】:

    编辑见下文,这不起作用。)您可以检查元素是否具有onload属性:

    var img = document.createElement('img');
    alert("img onload? " + ('onload' in img));
    var script = document.createElement('script');
    alert("script onload? " + ('onload' in script));
    

    在 IE7 上,img 得到 truescript 得到 false

    编辑 这不适用于 Firefox。离开这个只是为了让其他人不要走同样的路。

    【讨论】:

    • 谢谢,这是一个新颖的测试,但正如你所说:没有香蕉!
    • @mummybot:是的,我很失望。 :-( 你可以用类似的方式测试很多其他的东西,但显然不是这样。你总是可以通过临时添加元素并查看它们是否触发事件来进行功能测试,但这很可能是矫枉过正。
    • 同样令人担忧,因为您必须假设如果测试的元素在不确定的时期后没有触发,那么它因此不支持 onload。您将无法检查服务器是否出现故障或互联网是否变慢。另外,这会增加相当长的延迟...... gah :(
    • @mummybot:我在考虑从数据 URI 加载(不涉及“网络延迟”)。现在几乎所有的浏览器都支持数据 URI。 (html5readiness.com)
    【解决方案2】:

    我不确定这是否是您所要求的,但这会让您知道您是否有可用于给定对象的特定方法或属性。

    var apple = new Object;
        apple.load = function() { alert("I am a method.") };
        apple.color = "red"
    
    function isAvailable(obj, mp) { 
        // obj = element to test for method or property. 
        // mp = name of method or property. 
    
        if (obj[mp]) {
            return true;
        } else {
            return false;
        }
    }
    
    if (isAvailable(apple, "color")) {
        alert("apple object has a 'color' property");
    }
    
    if (isAvailable(apple, "load")) {
        alert("apple object has a 'load' method");
    }
    

    编辑:重新设计答案以显示示例。

    【讨论】:

    • 谢谢约翰,但没有。我特别想检测 DOM 对象是否具有特定的方法(加载),而不是一般的 javascript 对象。我很确定这是不可能的。
    • 我修改了我的答案以表明它在对象中找到方法或属性,而不是对象是否存在。
    【解决方案3】:

    我以前做过这样的事情;在 iphone 上为电话间隙编写东西时,取决于您是在模拟器中运行应用程序还是在不同版本的设备上运行应用程序,您通常有不同的处理程序来处理输入按钮的点击(以及大多数其他事情) - 所以在顶部我只是快速检查一下我的脚本;

    var m_clickEvent = ''; 
    
    if ( $('input').click != 'undefined')
       m_clickEvent = 'click'
    else if ( $('input').tap != 'tap')
       m_clickEvent = 'tap'
    else if ( $('input').touchstart!= 'touchstart')
       m_clickEvent = 'touchstart'
    else 
       // some kind of error handling..
    

    然后我可以继续绑定我的事件处理程序;

    $('.myButton').bind(m_clickEvent, function(e) { ... });
    

    【讨论】:

    • 嗨,Shawson,感谢您的回复,不幸的是,onload 处理程序似乎没有该选项(这是我最初的问题)-“不幸的是,分配 element.onload 使事件不再'未定义' ,无论它最终是否会触发。”
    【解决方案4】:

    这是一个从 Modernizr 进行事件检测的方式中提取的示例:

    var tmp = document.createElement('script'); 
    tmp.setAttribute('onload', '');
    isSupported = typeof tmp.onload == 'function';
    

    【讨论】:

    • 我不确定这是否有效,因为您已将其复制到那里。 Firefox 控制台中的以下代码表示元素 cheese 将有一个 onload 事件: var tmp = document.createElement('cheese'); tmp.setAttribute('onload', '');控制台.log(tmp,tmp.onload); isSupported = typeof tmp.onload === 'function'; console.log(isSupported);
    • 有趣。好吧,也许 Firefox 支持所有元素上的“加载”事件侦听器,尽管没有办法加载内容并因此触发它;)。实际上,我将其称为 Firefox 中的错误。该代码在 Chrome 和 Opera 中运行良好。
    【解决方案5】:

    我过去这样做的一种方法是使用旧的“for in”循环,并检查每个键值是否以“on”开头(我见过的每个本机事件处理程序都会启动这个方式...)所以,例如:

    var el = document.querySelector("*"), //this is the element (use whatever selector text)
    elEventHandlers = [];                 //set up an array to hold 'em all
    
    for (var prop in el)                  //loop through each prop of the element
        if (prop.substring(0,2)=="on")    //if the prop starts with "on" it's an event handler
            elEventHandlers.push(prop);   //so, add it to the array
    
    console.log(elEventHandlers);         //then dump the array to the console (or whatever)
    

    瞧!现在您知道可以在该元素上注册哪些事件处理程序了!

    【讨论】:

      【解决方案6】:

      试试这个:

      var d = document.createElement('div');
      
      if(d.hasOwnProperty('onclick')) {
          //then onclick is supported
      }
      

      您还可以循环遍历 div(或获取任何其他 HTML 元素)的属性来动态检查它:

      var d = document.createElement('div'),
         el = 0;
      
      for(el in d) {
          if(d.hasOwnProperty(el)) {
              console.log(d[el]); //or do anything else you like
          }
      }
      

      您可以在 mozilla's dev blog 上查看有关 hasOwnProperty 的更多信息

      【讨论】:

        【解决方案7】:
        isEventSupported =
            function(tag, event){
            return document.createElement(tag)[event]===null;
            };
        
        >> isEventSupported("script", "onload"); 
        true //on my current browser
        

        即使是来自像...这样的退伍军人,也有关于此事件支持的虚假报告,更不用说名字了 - 但很明显 onload 事件很可能不会在 IMG 元素 SCRIPT 元素和类似元素上触发,因为源已经兑现并且从现金中提取资源的元素不会触发 onload 事件。

        例外:文档元素将触发 onload 事件,即使在处理已兑现的文件时也是如此,因为它依赖于 readystate 完成。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-10-19
          • 2022-12-01
          • 2013-06-15
          • 1970-01-01
          相关资源
          最近更新 更多