javascript - 触发事件的顺序

标签 javascript jquery dom-events

有一个<div>有两个类。对于每个类别,单击时都会触发一个事件,每个类别都有单独的事件。有没有办法确保类(class)的事件class_one总是会首先被触发并且总是 console.log("First")将首先被解雇。

$('body').on('click', '.class_one', function() {
  console.log("First")
})

$('body').on('click', '.class_two', function() {
  console.log("Second")
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="class_one class_two">Click me</div>

最佳答案

事件不在类上触发,而是在元素上触发。如果在同一元素上设置类“class_one”和“class_two”,则事件将按照它们绑定(bind)的顺序调用。然而,事件会冒泡,这意味着“click”事件首先在单击的元素上触发,然后是其父元素,依此类推。

这意味着如果您有能力更改 DOM,则可以强制首先触发类为“class_one”的元素上的事件。这可以通过从元素中删除“class_two”类并将其包装在“class_one”元素周围来完成。

此行为可以在 jQuery on 中找到描述。文档:

When a selector is provided, the event handler is referred to as delegated. The handler is not called when the event occurs directly on the bound element, but only for descendants (inner elements) that match the selector. jQuery bubbles the event from the event target up to the element where the handler is attached (i.e., innermost to outermost element) and runs the handler for any elements along that path matching the selector.

$('body').on('click', '.class_one', function() {
  console.log("First")
})

$('body').on('click', '.class_two', function() {
  console.log("Second")
})

$('body').on('click', '.class_one', function() {
  console.log("Third")
})

$('body').on('click', '.class_two', function() {
  console.log("Fourth")
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="class_two">
  <div class="class_one">Click me</div>
</div>


就像上面已经说过的:如果在同一元素上设置类“class_one”和“class_two”,则事件将以它们绑定(bind)的顺序调用。

也可以在 on 中找到文档:

Event handlers bound to an element are called in the same order that they were bound.

此属性可用于注册两个充当“寄存器”的事件,并触发添加到此“寄存器”(示例中的简单数组)的所有事件。

此解决方案不需要您更改 DOM,而是要求您更改 JavaScript 中的事件注册。

const class_one_click_fns = [],
      class_two_click_fns = [];

$('body').on('click', '.class_one', function(...args) {
  class_one_click_fns.forEach(fn => fn.call(this, ...args))
})

$('body').on('click', '.class_two', function(...args) {
  class_two_click_fns.forEach(fn => fn.call(this, ...args))
})

class_one_click_fns.push(function () {
  console.log("First")
})

class_two_click_fns.push(function () {
  console.log("Second")
})

class_one_click_fns.push(function () {
  console.log("Third")
})

class_two_click_fns.push(function () {
  console.log("Fourth")
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="class_one class_two">Click me</div>

关于javascript - 触发事件的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61519258/

相关文章:

javascript - 如何通过数字键盘输入验证小数点后两位的输入值?

javascript - "this"嵌套原型(prototype)内部未指向实例

javascript - 如何使用切换 slider js

jquery - blueimp jQuery文件上传没有被触发

javascript - 如何让 jQuery .change() 引用 Handsontable 上的单元格?

javascript - 将 DOM 鼠标事件从子 <object> 传递到父页面的选项

javascript - 如何从 Ant design 的 Select/Option 组件中获取值

javascript - 为什么我的捕获括号之外的字符包含在我的正则表达式的匹配中?

jquery - 类型错误 : Image is not a constructor

javascript - 如何在 Angular 5 中执行 "onload"事件?