首页 > 解决方案 > 为什么 trigger() 会触发 select() 处理程序 3 次?

问题描述

$("#select-test").select(function(e){
    //console.log(e)
    console.log("selected")
})

$("#newTest").click(()=> {
    $("#select-test").trigger("select")
})
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>

<button id="newTest">TEST ME</button>
<input type="text", id="select-test" value="some">

这是在 Chrome 中,在 Firefox 中,它被触发了两次。

我读了这个JQuery - 为什么 Trigger 方法会调用它三次?讨论这个问题的线程,但老实说我无法理解。

有人说:

we have 1 isTrigger and 2 simple select events.

那什么意识?2个简单的select事件?在哪里?我们只有 1 个select事件,第二个在哪里?

最好的答案说这是因为冒泡而发生的,但是......如何?我的意思是,在哪里冒泡?我不明白这如何解释事件处理程序被触发 3 次。冒泡是当您定位子元素时,也会触发具有相同处理程序的父元素,但这不是我们这里所拥有的。我们只有一个select处理程序,所以.. 冒泡在哪里?为什么它会在 Firefox 中触发两次?

标签: javascript

解决方案


如果您希望在某个时候停止选择,则选择需要阻止默认值。当字段成为焦点时,选择事件不是焦点事件。选择某些内容时会触发 select 事件。

当您使用以下代码触发选择事件并打开浏览器工具时,您将看到调试器显示以下代码。当您选择调用堆栈->调度时,您可以看到触发事件的原因,并看到第三个事件是由本机事件触发的。

调用栈

var count = 0;
$("#select-test").select(function(e){
    if(count == 2) {
       debugger;
    }
    count++;
    console.log("selected")
})

$("#newTest").click(()=> {
    count = 0
    $("#select-test").trigger("select")
})
<script src="https://code.jquery.com/jquery-3.6.0.js"></script>

<button id="newTest">TEST ME</button>
<input type="text", id="select-test" value="some">

如果我们查看select 的文档,我们会看到:

此外,该字段的默认选择操作将被触发,因此将选择整个文本字段。

所以会发生什么:

  1. 您触发 select -> jquery 触发 select 到所有事件处理程序
  2. jQuery 聚焦字段,这会触发浏览器自动选择所有文本,从而触发 select 事件。
  3. jquery 选择字段中的所有文本,触发原生选择,由 jquery 包装,然后传递给处理程序。

要阻止任何这些步骤的发生,您可以event.preventDefault()在第一次触发 select 时使用,这将产生不选择文本的附带事件。

我建议您不要使用 select,而是使用focus(),除非您真的需要知道每次触发选择时选择了什么文本。


推荐阅读