jQuery 事件:在已经存在的事件之前添加一个回调处理程序

Alp*_*Alp 6 javascript jquery click callback jquery-events

在网页上是带有点击和/或按键处理程序的元素。如果我添加一个新的,它将在它们之后执行。我需要一种方法来添加一个新的回调,它被添加到事件处理程序列表中,以便预先执行。jQuery 怎么可能呢?

更新

为什么我不能只使用 jQuery 的 unbind 方法?我正在将我的 jQuery 代码注入任何网页,因此我不知道是否使用了任何 JavaScript 框架以及使用了哪个 JavaScript 框架。我需要一种通用的方法来检测事件处理程序并预先添加我的。(在您提问之前,我正在构建一个“记录器”应用程序,用于跟踪用户操作以存储它们并在以后执行它们。)

更新 2

我只使用 Firefox,不需要兼容 IE。我必须等待页面完全加载,然后我的 jQuery 脚本将被调用。

Roe*_*oel 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)
Run Code Online (Sandbox Code Playgroud)

在执行被单击元素的事件处理程序之前,这将在元素中的每次单击时执行。我不确定浏览器是否支持。


And*_*eas 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'))
Run Code Online (Sandbox Code Playgroud)
.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)
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="btn">Click me<div>
Run Code Online (Sandbox Code Playgroud)