简体   繁体   English

如何停止从子 select 的父 div 传播事件

[英]How to stop propagating event from parent div in child select

There's a div element that contains 1 or more child elements of type select. When the div (my_title) is clicked, sort() has to run (OK).有一个 div 元素包含 1 个或多个类型为 select 的子元素。单击 div (my_title) 时,sort() 必须运行 (OK)。 If a value is selected from the select (my_select), sort() is executed as well but it shouldn't.如果从 select (my_select) 中选择了一个值,sort() 也会被执行,但它不应该被执行。 I tried to add a click handler and call stopPropagation() but sort() is still called.我试图添加一个点击处理程序并调用 stopPropagation() 但 sort() 仍然被调用。 In fact, sort() is called first and only then stopPropagation().事实上,首先调用 sort(),然后才调用 stopPropagation()。

<div id="my_title" onclick="sort(&quot;sf&quot;, &quot;2&quot;, event)" style="top: 0px; left: 1px; width: 300px; height: 50px; text-align: center; position: absolute;">
   Column 2
   <select id="my_select" style="top: 1px; left: 0px; width: 297px; position: relative;" >
      <option value="1">1</option>
      <option value="2">2</option>
   </select>
</div>

JavaScript: JavaScript:

function sort() {
    console.log('sort');
}

$('#my_title').on('click', '> select', function(event) {
    console.log('stopPropagation');
    event.stopPropagation();
    // event.cancelBubble = true;
    // event.stopImmediatePropagation();
});

Fiddle: https://jsfiddle.net/Smolo/34nh6Lwb/小提琴: https://jsfiddle.net/Smolo/34nh6Lwb/

Seems that that behavior happens when you use onclick="..."似乎当您使用 onclick="..." 时会发生这种行为

Try using this instead:尝试改用这个:

$('#my_title').on('click', function(event) {
  sort()
})

You cannot stop event propagation between the target element and the delegated parent when using a delegated event handler.使用委托事件处理程序时,您无法停止目标元素与委托父元素之间的事件传播。 This is because the event needs to propagate up the DOM from the element that raises the event to the one which the handler is bound to.这是因为事件需要将 DOM 从引发事件的元素向上传播到处理程序绑定到的元素。

A better solution in this case is to determine which element raised the click event handler and then only call sort() if it was the #my_title element.在这种情况下,更好的解决方案是确定哪个元素引发了click事件处理程序,然后仅在它是#my_title元素时才调用sort()

Also note that your JS can be improved.另请注意,您的 JS 可以改进。 Firstly, you should not bind JS event handlers or add styling in to the HTML. They should be placed in external JS and CSS files, respectively.首先,你不应该在 HTML 中绑定 JS 事件处理程序或添加样式。它们应该分别放在外部 JS 和 CSS 文件中。

In addition, event handlers should be bound unobtrusively (as you do for the select element) not using outdated onX attributes which are bad practice.此外,事件处理程序应该不显眼地绑定(就像您对select元素所做的那样),不要使用过时的onX属性,这是不好的做法。

Finally, use the change event on the select to listen for updates, not the click event.最后,使用select上的change事件来监听更新,而不是click事件。

With all those points addressed, your code should look like this:解决了所有这些问题后,您的代码应如下所示:

 jQuery($ => { $('#my_title').on('click', e => { let $el = $(e.target); if ($el.is('#my_title')) sort($el.data('sort-key'), $el.data('sort-value')); }); $('#my_title').on('change', '> select', function(event) { // change handler logic here... console.log('change'); }); }); let sort = (key, value) => { // your sort logic here... console.log(key, value); }
 #my_title { top: 0px; left: 1px; width: 300px; height: 50px; text-align: center; position: absolute; } #my_select { top: 1px; left: 0px; width: 297px; position: relative; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <div id="my_title" data-sort-key="sf" data-sort-value="2"> Column 2 <select id="my_select"> <option value="1">1</option> <option value="2">2</option> </select> </div>

Change your sort to something like this:将您的排序更改为如下所示:

function sort(a, b, e) {
        if (e.target.id === 'my_title') { // or use more generic comparison
            console.log('sort');
    }
}

It will only run for elements that much your comparison (eg your Label/Title它只会运行与您比较多的元素(例如您的标签/标题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM