【问题标题】:jQuery: click function exclude children.jQuery:点击功能排除孩子。
【发布时间】:2011-01-28 06:32:42
【问题描述】:

试图围绕 jQuery ".not()" 函数来解决问题,但遇到了问题。我想让父 div 成为“可点击”,但如果用户点击子元素,则不会调用脚本。

$(this).not(children()).click(function(){
   $(".example").fadeOut("fast");
});

html:

<div class="example">
   <div>
      <p>This content is not affected by clicks.</p>
   </div>
</div>

【问题讨论】:

    标签: jquery


    【解决方案1】:

    我个人会为子元素添加一个点击处理程序,它只会停止点击的传播。所以它看起来像:

    $('.example > div').click(function (e) {
        e.stopPropagation();
    });
    

    【讨论】:

    • stopPropagation 和像其他答案建议的那样返回 false 有什么区别?
    • 我相信在这种情况下它们的功能是相同的,但我认为停止传播更清楚地了解正在做的事情的目的,并且有更好的机会理解为什么稍后会这样做。但这值得商榷。
    • 感谢您的澄清。看起来stopPropagation 可能更干净,因为它不会阻止子元素上的事件发生,return false 可能会发生这种情况。
    【解决方案2】:

    这是一个例子。绿色方块是父元素,黄色方块是子元素。

    希望这会有所帮助。

    var childElementClicked;
    
    $("#parentElement").click(function(){
    
    		$("#childElement").click(function(){
    		   childElementClicked = true;
    		});
    
    		if( childElementClicked != true ) {
    
    			// It is clicked on parent but not on child.
          // Now do some action that you want.
          alert('Clicked on parent');
    			
    		}else{
          alert('Clicked on child');
        }
        
        childElementClicked = false;
    	
    });
    #parentElement{
    width:200px;
    height:200px;
    background-color:green;
    position:relative;
    }
    
    #childElement{
    margin-top:50px;
    margin-left:50px;
    width:100px;
    height:100px;
    background-color:yellow;
    position:absolute;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="parentElement">
      <div id="childElement">
      </div>
    </div>

    【讨论】:

      【解决方案3】:

      我的解决方案:

      jQuery('.foo').on('click',function(event){
          if ( !jQuery(event.target).is('.foo *') ) {
              // code goes here
          } 
      });
      

      【讨论】:

      • 与您上面的解决方案类似。
      【解决方案4】:

      或者你也可以这样做:

      $('.example').on('click', function(e) { 
         if( e.target != this ) 
             return false;
      
         // ... //
      });
      

      【讨论】:

      • 您必须返回false,以避免子元素中的点击事件。修改错误
      【解决方案5】:

      我正在使用以下标记并且遇到了同样的问题:

      <ul class="nav">
          <li><a href="abc.html">abc</a></li>
          <li><a href="def.html">def</a></li>
      </ul>
      

      这里我使用了以下逻辑:

      $(".nav > li").click(function(e){
          if(e.target != this) return; // only continue if the target itself has been clicked
          // this section only processes if the .nav > li itself is clicked.
          alert("you clicked .nav > li, but not it's children");
      });
      

      就确切的问题而言,我可以看到它的工作方式如下:

      $(".example").click(function(e){
         if(e.target != this) return; // only continue if the target itself has been clicked
         $(".example").fadeOut("fast");
      });
      

      当然也可以反过来:

      $(".example").click(function(e){
         if(e.target == this){ // only if the target itself has been clicked
             $(".example").fadeOut("fast");
         }
      });
      

      希望对您有所帮助。

      【讨论】:

      • 我认为这是更好的解决方案。它不会以任何方式干扰孩子,并且应该表现得更好,因为如果有数千个孩子,它不会潜在地注册数千个回调。
      • @l2aelba - 你应该在最新版本的 jQuery 中使用.on("click", ...),因为.live() 自 v1.7 以来已被弃用。见api.jquery.com/live
      • 是的,@Chris 我于 2012 年 11 月 16 日 10:12 发布
      • 抱歉,可能不需要引用您的 ID。我主要为阅读此答案的其他人添加了评论。
      • 这个答案比公认的答案更好,因为它不会中断子元素上的任何点击事件
      【解决方案6】:

      为此,请停止点击子using .stopPropagation

      $(".example").click(function(){
        $(this).fadeOut("fast");
      }).children().click(function(e) {
        return false;
      });
      

      这将阻止子点击冒泡超过他们的水平,因此父级不会收到点击。

      .not() 的用法有点不同,它会过滤掉选择器中的元素,例如:

      <div class="bob" id="myID"></div>
      <div class="bob"></div>
      
      $(".bob").not("#myID"); //removes the element with myID
      

      对于单击,您的问题是 click on a child bubbles up to the parent,而不是您无意中将单击处理程序附加到子项。

      【讨论】:

      • 感谢 nick,我认为这不是我想要的。很抱歉,我的问题不清楚。我希望整个 div.example 淡出,仅在单击父元素时,而不是在单击子 div 时。这样做的原因是我希望用户能够单击段落文本并且没有文本淡出。如果用户点击外层div(父div),那么一切都会淡出。
      • @superUntitled - 感谢您的澄清...答案已更新,请尝试一下。
      • @Asaf - 在这种情况下使用 e.stopPropagation(); 而不是 return false;
      • 您也可以使用}).find('.classes-to-ignore').click(function(e) { 选择特定的子元素
      • 我不明白你为什么告诉他使用e.stopPropagation(),然后使用return falsereturn false 等同于 e.preventDefault(); e.stopPropagation(),所以它可能会产生意想不到的副作用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-14
      • 2012-12-30
      • 2014-03-05
      • 2014-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多