无论添加事件的顺序如何,您如何强制首先运行javascript事件?

Sco*_*ott 19 javascript jquery javascript-events

我有javascript,人们在他们的页面中包括.在我的javascript中,我有一个jQuery版本(1.8为了方便参考),它被划分为自己的命名空间,并通过全局变量引用(但不是"$"或"jQuery"的两个默认变量之一) .这允许用户在他们的页面中使用jQuery并且不会干扰我在函数内部执行的操作.

所以我们有一个页面已经有jQuery(1.4),并且一切正常,除了用户和我的代码都在元素上监听"点击"事件,他们的第一个,所以在他们这样做的少数事件上return false,jQuery停止传播,我的事件永远不会被触发.我需要先举办活动.用户希望我的onClick功能仍然有效.

现在我知道jQuery在内部通过_data()对象保持自己的事件顺序,通过它可以取消绑定现有事件,绑定我的事件,然后重新绑定现有事件,但这只适用于通过该实例绑定的对象的jQuery.我宁愿不盲目地寻找jQuery对象,希望冲突是由用户自己的jQuery版本引入的.毕竟当用户不通过jQuery绑定事件时会发生什么?试图操纵页面中现有的jQuery对象不是一个好的解决方案.

我知道,根据浏览器,他们使用addEventListener/removeEventListener或attachEvent/detachEvent.如果我只能获得已添加事件的列表,我可以按照我想要的顺序重新绑定它们,但我无法找到方法.通过chrome检查来查看DOM我看不到任何地方的onclick绑定(不在对象上,也不在窗口或文档上).

我正试着弄清楚jQuery绑定其监听的确切位置.为了能够控制自己事件的顺序,jQuery必须全面地听某个地方,然后开启它自己的功能吗?如果我能弄明白在哪,我可以深入了解如何确保我的活动始终是第一位的.或者也许有一些我在谷歌上找不到的JavaScript API.

有什么建议?

Chr*_*ald 21

我们通过添加一个在事件链的头部插入事件的jQuery扩展来解决这个问题:

$.fn.bindFirst = function(name, fn) {
  var elem, handlers, i, _len;
  this.bind(name, fn);
  for (i = 0, _len = this.length; i < _len; i++) {
    elem = this[i];
    handlers = jQuery._data(elem).events[name.split('.')[0]];
    handlers.unshift(handlers.pop());
  }
};
Run Code Online (Sandbox Code Playgroud)

然后,绑定您的事件:

$(".foo").bindFirst("click", function() { /* Your handler */ });
Run Code Online (Sandbox Code Playgroud)

十分简单!

  • 嗯,我错过了.这可能是正确的.您是否有理由在同一页面中使用多个并发版本的jQuery?据我所知,您无法直接从浏览器获取绑定事件列表. (2认同)

Sco*_*ott 5

正如Bergi和Chris Heald在评论中所说,事实证明,没有办法从DOM中获取现有事件,也没有方法可以“首先”插入事件。按照设计插入的顺序将它们发射,并按设计隐藏它们。如前所述,您可以访问通过jQuery数据通过相同jQuery实例添加的海报,仅此而已。

在另一种情况下,您可以在代码运行之前绑定的事件之前运行,即它们是否使用了“ onclick” HTML属性。在这种情况下,您可以编写包装函数,正如在下面的相当高调的注释中没有指出的那样。虽然这在我提出的原始问题中无济于事,并且现在以这种方式绑定事件已经非常罕见了(大多数人和框架现在都在下面使用addEvent或attachEventListener),但是在这种情况下,您可以解决“首先运行”的问题,由于许多人现在都在访问此问题以寻找答案,所以我认为我将确保答案是完整的。