【问题标题】:How to ignore click event when clicked on children单击子项时如何忽略单击事件
【发布时间】:2014-05-12 17:24:11
【问题描述】:

所以我有以下场景:

<div id="block">
Sample text.
<a href="#">Anchor link</a>
</div>

<script type="text/javascript">
    $("#block").click(function() { alert('test'); });
</script>

当我单击 div 内的任意位置时,我会收到“测试”警报。但是,当我单击“锚链接”时,我想防止这种情况发生。我该如何实现呢?

谢谢

【问题讨论】:

    标签: jquery


    【解决方案1】:

    您可以使用额外的处理程序阻止点击从链接冒泡,如下所示:

    $("#block a").click(function(e) { e.stopPropagation(); });
    

    我们在 cmets 中讨论的替代方案:

    $("#block").delegate('a', 'click', function(e){ e.stopImmediatePropagation(); })
               .click(function() { alert('test'); });​
    

    这将防止任何子链接冒泡(嗯,不是真的,但它们的处理程序不会执行),但不会为每个元素创建处理程序,这是通过.stopImmediatePropagation() 完成的。

    【讨论】:

    • 感觉有点“矫枉过正”给每个链接添加点击处理程序只是为了防止事件传播(当然这取决于链接的数量)。但这是防止任何特定元素的事件传播的好方法。
    • @Felix - 如果有很多链接,我会使用一组 .delegate() 处理程序完全采用不同的方法 :) (您可以使用上述 before 的委托版本i> 其他点击处理程序也是如此)。
    • 我刚刚尝试使用delegate(),但它对我不起作用:jsfiddle.net/cxcfA。我假设因为事件已经冒泡了。还是你的意思是别的?
    • @Felix - e.stopImmediatePropagation(); ;) jsfiddle.net/nick_craver/cxcfA/1
    • 非常好:) 好一个!你似乎总是有答案;)
    【解决方案2】:

    这就是你需要的:http://api.jquery.com/event.target/

    只需比较以检查元素是否由您想要的元素或其子元素之一触发。

    【讨论】:

      【解决方案3】:

      您可以使用事件对象的target 属性来测试点击了哪个节点:

      $("#block").click(function(event) { 
          if(event.target.nodeName != 'A') {
              alert('test');
          }
      });
      

      我建议阅读Event Properties from quirksmode.org

      【讨论】:

        【解决方案4】:
        $("#block").click(function(event) {
            if($(event.target).attr('id') == $(this).attr('id'))
            {
                alert('test');
            }
        });
        

        【讨论】:

        • 辛苦了。谢谢!
        【解决方案5】:

        这是一个演示 (jsfiddle),其中包含一个表单和两个字段:

        <div id="container">
            <form>
                <div class="field">
                    <input id="demo" type="text" name="demo" />
                </div>
                <div class="field">
                    <input id="demo2" type="text" name="demo2" />
                </div>
            </form>
        </div>
        

        代码如下所示:

        $(document).ready(function() {
            $('#container').click(function(evt) {
                if(this == evt.target) {
                    console.log('clicked container',evt.target);
                    $('#demo').focus();
                } else {
                    console.log('clicked child -> ignoring');
                }
            });
        
            $('.field').click(function(evt) {
                if(this == evt.target) {
                    console.log('clicked field div',evt.target);
                    $(this).find('input').focus();
                } else {
                    console.log('clicked child -> ignoring');
                }
            });
        });
        

        您可以单击包含表单的容器将焦点设置在第一个输入字段或输入字段后面以将焦点设置在其中。

        如果您单击该字段,则单击将被忽略。

        上述代码有效,因为jQuery在调用事件处理程序之前将DOM节点分配给this,因此您可以通过检查轻松检查当前事件是否由DOM节点发布

        this == evt.target
        

        CSS:

        #container {
            width: 600px;
            height: 600px;
            background: blue;
        }
        
        .field {
            background: green;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-11-28
          • 2016-12-16
          • 2017-10-22
          • 2017-12-31
          • 1970-01-01
          • 2010-10-07
          • 1970-01-01
          相关资源
          最近更新 更多