Javascript添加事件跨浏览器功能实现:使用attachEvent/addEventListener vs inline events

IT技术 javascript events javascript-events event-handling
2021-03-08 11:31:32

为了添加事件,我们可以使用这个简单的第一个解决方案

function AddEvent(html_element, event_name, event_function) 
{       
   if(html_element.attachEvent) //Internet Explorer
      html_element.attachEvent("on" + event_name, function() {event_function.call(html_element);}); 
   else if(html_element.addEventListener) //Firefox & company
      html_element.addEventListener(event_name, event_function, false); //don't need the 'call' trick because in FF everything already works in the right way          
} 

第二个解决方案(添加内联事件):

function AddEvent(html_element, event_name, event_function) 
{       
   var old_event = html_element['on' + event_name];
   if(typeof old_event !== 'function')
      html_element['on' + event_name] = function() { event_function.call(html_element); };
   else
      html_element['on' + event_name] = function() { old_event(); event_function.call(html_element); };
}

这些都是跨浏览器,可以这样使用:

AddEvent(document.getElementById('some_div_id'), 'click', function() 
{             
   alert(this.tagName); //shows 'DIV'
});  

由于我感觉attachEvent/addEventListener在事件处理实现中使用得更多,我想知道:

使用我可能更清楚的第二个解决方案是否有任何缺点/缺点?

我可以看到两个,但我对更多(如果有)感兴趣:

  1. 第二个解决方案通过添加内联事件来破坏元素的innerHTML
  2. 使用第二个解决方案,我可以轻松删除与特定事件类型 ( html_element['on' + event_name] = null)关联的所有函数,但我不能detachEvent/removeEventListener用来完全删除特定函数。

任何诸如“使用 jQuery”或任何其他 FW 之类的答案都是毫无意义的!

2个回答

使用第二个解决方案,您必须手动调用之前的函数,从而很难删除特定的侦听器(对我来说,这听起来像是您宁愿想要而不是清除所有侦听器的东西),而在第一个解决方案中,您只能同时清除它们,除非您想模拟第一个功能。

就我个人而言,我总是使用第一种解决方案,因为它的优点是不必担心清除可能的其他事件侦听器。

Mozilla的维基还列出了第一个解决方案工作于任何DOM元素,而不仅仅是HTML元素上的优势,而且它允许细粒度的控制时,听众被激活的阶段(捕获与冒泡)与第三个参数。

+1 我阅读了您建议的链接,但 Mozilla 网站解释的三点并非如此:“1. 它允许为事件添加多个处理程序” 是的,但是我在回答中编写的这两个函数可以添加多个单个事件处理程序。“2. 当监听器被激活(捕获与冒泡)时,它可以让你对阶段进行更细粒度的控制” 是的,但是添加 stopEvent 函数来防止默认和停止冒泡很容易,而且 attachEvent 没有这样的行为,所以会anyayw 必须创建一个跨浏览器功能。
2021-04-23 11:31:32
(续)“3。它适用于任何 DOM 元素,而不仅仅是 HTML 元素。”,有趣,但我没有看到一个真实的例子,我可能需要将一个事件添加到一个不是 HTML 的 dom 节点元素。
2021-04-27 11:31:32
@Marco Demaio:1. 是的。但是您的函数是非本地函数,任何其他想要注册事件的人都会清除整个加载。2. 对 3. SVG 标签?
2021-04-30 11:31:32
我认为您在前两段中将第一件事和第二件事倒退了。
2021-05-01 11:31:32

我会像这样使用这两个代码

function addEvent(html_element, event_name, event_function) {
    if (html_element.addEventListener) { // Modern
        html_element.addEventListener(event_name, event_function, false);
    } else if (html_element.attachEvent) { // Internet Explorer
        html_element.attachEvent("on" + event_name, event_function);
    } else { // others
        html_element["on" + event_name] = event_function;
    }
};