HTML元素上可用的Javascript检测事件处理程序

HTML元素上可用的Javascript检测事件处理程序,javascript,dom,events,dom-events,onload,Javascript,Dom,Events,Dom Events,Onload,有没有一种方法可以检测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 var el = document.

有没有一种方法可以检测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
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)
理想情况下,我希望在脚本中执行功能检测,如果元素可以使用
onload
,否则就回退。目前我不得不使用浏览器分叉(基于IE),这很烦人,因为IE可能开始支持
script.onload
,而Webkit/Firefox可能开始支持
link.onload

不幸的是,分配
元素。onload
使事件不再是“未定义的”,不管它最终是否会触发。

编辑见下文,这不起作用。)您可以检查元素是否具有
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
获取
true
,为
脚本获取
false


编辑这不适用于Firefox。让其他人不要走同一条路。

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

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");
}

编辑:重新处理答案以显示示例。

我以前做过类似的事情;在iphone上为phone gap编写内容时,根据您是在模拟器中运行应用程序还是在不同版本的设备上运行应用程序,您通常有不同的处理程序来处理输入按钮的点击(以及大多数其他事情)——因此在我的脚本顶部,我只需进行快速检查

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) { ... });

下面是一个事件检测方法的示例:

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

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

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
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)
瞧!现在您知道可以在该元素上注册哪些事件处理程序了

试试这个:

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
    }
}
您可以在上查看更多关于hasOwnProperty的信息

即使是像…这样的老兵也有关于此事件支持的错误报告,我们不必提及姓名-但不明显的是,onload事件很可能不会在IMG元素脚本元素和类似元素上触发,因为源已经被兑现,并且从现金中提取资源的元素不会触发onload事件


例外:document元素将触发onload事件,即使在处理现金文件时也是如此,因为它取决于readystate complete。

谢谢,这是一个新颖的测试,但正如您所说:没有香蕉@木乃伊伯特:是的,我被解封了-(还有许多其他的东西可以用类似的方式进行测试,但显然不是这样。你可以通过临时添加元素并查看它们是否触发事件来测试,但这可能有点过分了。同样令人担忧的是,你必须假设,如果被测元素在一段不确定的时间后没有触发,那么它就会被触发。)因此不支持onload。你将无法检查服务器是否宕机或互联网是否运行缓慢。此外,这将增加相当大的延迟…gah:(@mummybot:我在考虑从数据URI加载(不涉及“网络延迟”)。现在几乎所有浏览器都支持数据URI。()谢谢John,但不是。我特别想检测DOM对象是否有特定的方法(load),而不是一般的javascript对象。我很确定这是不可能的。我修改了我的答案,以表明它在对象中找到了方法或属性,而不是对象是否存在。嗨,Shawson,谢谢你的回答,不幸的是,对于onload处理程序,似乎没有这个选项(这是我最初的问题)——“不幸的是,分配element.onload会使事件不再是‘未定义的’,不管它最终是否会触发。”我不确定这是否有效,因为您已经将它复制到了那里。Firefox控制台中的以下代码表示元素cheese将有一个onload事件:var tmp=document.createElement('cheese'));tmp.setAttribute('onload','');console.log(tmp,tmp.onload);isSupported=typeof tmp.onload=='function';console.log(isSupported);有趣。也许Firefox在所有元素上都支持'load'事件侦听器,尽管无法加载内容并因此触发它;)实际上,我认为这是Firefox中的一个bug。该代码在Chrome和Opera中运行良好。