jQuery事件:在已有的回调函数处理程序之前添加一个回调函数。

6
在网页上有带有点击和/或按键处理程序的元素。如果我添加一个新的处理程序,它将在它们之后执行。我需要一种添加新回调的方法,该回调被预置到事件处理程序列表中,以便在此之前执行。如何使用jQuery实现这一点?
更新
为什么我不能只使用jQuery的unbind方法?我正在向任何网页注入我的jQuery代码,所以我不知道是否使用了任何JavaScript框架,也不知道使用了哪个框架。我需要一种通用的方法来检测事件处理程序并将其预置。 (在你问之前,我正在构建一个“记录器”应用程序,用于跟踪用户的操作以存储它们并稍后执行它们。)
更新2
我只使用Firefox,不需要IE兼容性。我必须等待页面完全加载,然后才会调用我的jQuery脚本。

这是一个你可以控制的脚本吗?换句话说,你能解除绑定然后重新绑定所有内容吗? - kinakuta
回调函数总是在事件发生后执行。如果您希望旧处理程序执行额外的操作,为什么不直接修改现有处理程序中的代码呢? - Benny Tjia
1
据我所知,使用.addEventListener()绑定多个处理程序的调用顺序无法保证,并且无法列出已绑定的处理程序。单个库(如jQuery)可以解决这个问题,只要您通过该库绑定事件即可,但是我不确定如何处理通过多个库和/或纯JS绑定的事件。除非您可以在页面上运行任何其他代码之前覆盖.addEventListener(),以便其他代码绑定事件通过您的代理进行? (这仍然无法帮助您更旧的IE ...) - nnnnnn
不需要IE兼容性,它只在FF中运行。我不能在开始时运行任何代码,我必须等待页面完全加载完成,然后加载我的jQuery脚本。 - Alp
2个回答

5

如果您使用事件捕获(祖先的处理程序在事件到达元素之前被调用)而不是冒泡(子级-->祖先),我认为这可能会起作用。这是在目标元素到达之前拦截事件的一种方式。

大多数事件处理程序使用事件冒泡。根据w3c,事件首先被捕获,然后从目标再次冒泡。因此,如果您使用捕获将事件绑定到文档,则会首先为页面上的每个元素执行它。

http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html#Events-flow-capture

你需要使用以下代码绑定处理程序:(第三个参数是你是否想使用事件捕获)
document.body.addEventListener('click',handler,true)

对于元素中的每次点击,在点击元素的事件处理程序执行之前,将执行此操作。但我不确定浏览器是否支持。


这似乎可行,谢谢。尽管我相信它不会涵盖所有可能的情况。 - Alp

1
我也遇到了这个需求,我想出了一种基于DOM事件冒泡的解决方法。所以主要思路是实际上要做以下几步:
  1. 在你想要添加事件的元素中插入一个额外的元素作为直接子元素。

  2. 对于点击事件,确保它占据父元素的整个宽度和高度:

    • 如果父元素有填充/边框,请向子元素添加负边距,以便它占据父元素的整个区域
  3. 将预备的点击事件添加到创建的子元素中

点击事件被预先添加,因为子元素的点击将首先执行,并且事件会冒泡到父元素。然后,父元素的现有事件将在之后执行,从而创建所需的效果。

示例:

      
      const $someButton=$('.btn')
      $someButton.click(()=> alert('default event'))
      /**
      * 1. Insert an extra element 
      * as direct child of the element 
      * you want to append the event to
      **/
      $someButton.wrapInner(
        '<div class="btn__first_event"></div>'
      )
      /**
      * 3. Add the prepended click event to 
      * the created child
      **/
      $someButton.find('.btn__first_event').click(()=>alert('Prepended Event'))
.btn{
   cursor:pointer;
   background-color: yellow;
   padding:10px;
   border-radius:3px;
   border: 1px solid;
   display: inline-block;
}
/*
 2. In the case of click event 
make sure it takes 
the full width and 
height of its parent
-------------------- 
note: some css is needed for 
offsetting padding / border
*/
.btn__first_event{
   margin: -10px;
   padding: 1px;
   border-radius:3px;
   background-color: rgba(0, 0, 255, 0.4)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="btn">Click me<div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接