我有以下 HTML 内容:
<span onclick="alert('Boem')">
<button id="test1">test</button>
</span>
当我调用以下 JavaScript 代码时:
$('#test1').trigger('click');
onclick 事件被触发两次,而我希望它只触发一次。因为 jQuery 应该在 DOM 树中查找并只找到一个 onclick。
我无法控制跨度,它是在第三方工具中生成的。我确实可以控制按钮及其参数。
您可以在这里找到 JSFiddle 示例: http://jsfiddle.net/Voga/v4100zke/
我不知道span的onclick监听器的内容。这也是由第三方工具生成的。我希望点击触发器像现在一样执行这个 onclick,但只执行一次。
它调用了两次,因为按钮位于跨度内,并且跨度具有
onclick="alert('Boem')"
,因此当您触发单击按钮时,它会显示一个警报,并且相同的单击事件传播到跨度并再次显示警报。
您需要使用以下代码停止按钮的默认行为:
$(function(){
$('#test1').click(function(e){e.preventDefault();}).click();
});
我也遇到了类似的问题,我必须下载一个 pdf 文件,但该文件被下载了两次。我使用了 jQuery 的 stopImmediatePropagation 方法。
$( "#test1" ).on("click", function(e) {
e.stopImmediatePropagation();
});
$('#test1').trigger('click');
stopImmediatePropagation 将阻止任何父处理程序以及任何其他处理程序执行。请参阅此处了解更多详情。
要停止事件传播,请使用: stopPropagation
$( "#test1" ).on( "click", function(ev) {
ev.stopPropagation();
});
$('#test1').trigger('click');
请注意订单事件是在 DOM 中分配的。
冒泡。子级上的点击事件也会发生在父级(跨度)上。
我在 Modal 上也面临这个问题
通过以下技巧解决 -
$('#saveButton').off('click').on('click', { modal: modal }, save)
这里
off('click')
可以防止 save 方法多次触发。
这也应该有效:
$($('#test1').parent()).trigger('click');
这里
button click is triggered
。由于 button
位于 span
内部,并且为 onclick
定义了 span
事件,因此发生了 two alert
。
One is by the button
和
other by its parent
(父级有onclick事件并触发按钮点击)。
为了避免出现两个警报,请使用此功能
<span>
<button onclick="alert('Boem')" id="test1">test</button>
</span>
我也有同样的问题。 我的事实是,我使用的是
.trigger('.element')
并且该 element
类有两个元素。
因此,我变得更具体,并使用
.trigger('.parent .element')
来确保单个元素上只发生一次单击事件,而不是两个元素上发生一次单击事件。
这是由于冒泡而发生的。这是因为,正如 javascript.info 所说:“事件从内部元素向上通过父级“冒泡”,就像水中的气泡”。
如果您的第三方工具生成包含
<span></span>
属性的 onclick
元素,这可能意味着您的工具希望您直接将 span 视为按钮,而无需像您一样创建额外的按钮正在处理您的 <button></button>
元素。
在这里,要修复此错误,最好的方法是以编程方式单击包含处理程序的 same 元素以避免传播:
$('#test1').trigger('click');
/* Now, you can take #test1 and make it look and function as a button */
#test1 {
padding: 10px 20px;
color: white;
background-color: #0078d7;
font-size: 2rem;
font-family: Helvetica;
}
#test1:hover {
cursor: pointer;
background-color: blue;
transition: all 0.25s;
}
<!-- Script to include jQuery v3.3.1 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span id="test1" onclick="alert('Boem')">test</span>
注意你使用了jQuery的click方法。它将发出 DOM's 鼠标单击事件和 jQuery 的单击事件。然后 jQuery 的单击事件和 DOM 的鼠标单击事件都会传播到 span 元素,并且它的 onclick 侦听器被触发两次,因此它会发出两次警报。
查看这个演示来弄清楚。
至于如何处理,只需像之前的答案一样使用stopPropagation即可。
$('#test1').click(function() {
// comment this line and run, 'parent' will be alerted TWICE!!! since both mouseEvent and jQuery.Event trigger the onclick listener
$('#children').click(function(e) {e.stopPropagation()})
});
这个问题将有助于回答“为什么”。
更好的方法是为元素分配一个点击处理程序,以便将 JavaScript 代码从 HTML 中抽象出来:
http://jsfiddle.net/v4100zke/3/
$('#test1').click(function() {
alert('Boem')
});
就我而言,没有嵌套按钮,但我遇到了同样的问题。我解决了添加“return false;”的问题活动结束时。
$('#test1').click(function() {
alert('Boem');
return false;
});
在我的例子中,我在父 div 上添加事件监听器来触发点击事件。在此事件侦听器中,我需要触发隐藏输入上的单击事件。所以第二次点击呼叫第一个,我接到了两个电话。为了避免这种行为,我在输入上添加了事件侦听器以停止传播事件。
item.addEventListener('click', (event) => {
event.stopPropagation();
event.preventDefault();
var checkbox = item.querySelector('input[type="checkbox"]');
if (checkbox) {
checkbox.click();
item.classList.toggle('is-selected');
}
});
item.querySelector('input').addEventListener('click', function (event) {
// Avoid that the click on checkbox trigger parent event.
event.stopPropagation();
})
});