jQuery: ฟังก์ชั่นคลิกไม่รวมลูก


144

พยายามปิดหัวของฉันรอบฟังก์ชั่น ".not ()" jQuery และพบปัญหา ฉันต้องการให้ div parent เป็น "clickable" แต่หากผู้ใช้คลิกที่องค์ประกอบย่อยสคริปต์จะไม่ถูกเรียก

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

html ที่:

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

คำตอบ:


198

หากต้องการทำสิ่งนี้ให้หยุดการคลิกที่ลูกโดยใช้. 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

สำหรับการคลิกปัญหาของคุณคือการคลิกที่ลูก ๆ ลอยอยู่กับผู้ปกครองไม่ใช่ว่าคุณได้แนบตัวจัดการการคลิกกับเด็กโดยไม่ได้ตั้งใจ


ขอบคุณ nick ฉันไม่คิดว่านี่คือสิ่งที่ฉันกำลังมองหา ฉันขอโทษที่ฉันยังไม่ชัดเจนในคำถามของฉัน ฉันต้องการให้ div.example ทั้งหมดตัวอย่าง fadeOut เฉพาะเมื่อมีการคลิกองค์ประกอบหลักไม่ใช่เมื่อมีการคลิก div ลูก เหตุผลสำหรับเรื่องนี้คือฉันต้องการให้ผู้ใช้สามารถคลิกที่ข้อความในย่อหน้าและไม่มีข้อความ fadeOut หากผู้ใช้คลิกที่ div ด้านนอก (parent div) ทุกอย่างจะหายไป
superUnt ชื่อ

@superUntitled - ขอบคุณสำหรับความกระจ่าง ... คำตอบที่อัปเดตแล้วให้ลองทำดู
Nick Craver

18
@Asaf - ใช้e.stopPropagation();แทนreturn false;กรณีนั้น
Nick Craver

2
นอกจากนี้คุณยังสามารถใช้}).find('.classes-to-ignore').click(function(e) {เพื่อเลือกองค์ประกอบของเด็ก
Paul Mason

5
ฉันไม่เข้าใจว่าทำไมคุณบอกให้เขาใช้e.stopPropagation()แล้วใช้return falseแทน return falseเทียบเท่ากับe.preventDefault(); e.stopPropagation()ดังนั้นจึงอาจมีผลข้างเคียงที่ไม่คาดคิด
Steen Schütt

183

ฉันใช้มาร์กอัปต่อไปนี้และได้เข้ารหัสปัญหาเดียวกัน:

<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");
   }
});

หวังว่าจะช่วย


28
ฉันคิดว่านี่เป็นทางออกที่ดีกว่า มันไม่ได้รบกวนเด็ก ๆ แต่อย่างใดและมันควรจะทำงานได้ดีขึ้นเพราะมันอาจจะไม่บันทึกหมายเลขโทรกลับนับพันหากมีเด็กหลายพันคน
LucasB

4
@ l2aelba - คุณควรใช้.on("click", ...)ใน jQuery เวอร์ชันล่าสุดตามที่.live()เลิกใช้แล้วตั้งแต่ v1.7 ดูapi.jquery.com/live
Chris

ใช่ @Chris ฉันโพสต์เมื่อ 16 พ.ย. 12 เวลา 10:12
l2aelba

ขออภัยอาจไม่จำเป็นต้องอ้างอิง ID ของคุณ ฉันเพิ่มความคิดเห็นส่วนใหญ่สำหรับคนอื่นที่อ่านคำตอบ
Chris

1
คำตอบนี้ดีกว่าคำตอบที่ยอมรับเนื่องจากไม่ได้ขัดขวางกิจกรรมการคลิกใด ๆ ในองค์ประกอบย่อย
cameronjonesweb

24

หรือคุณสามารถทำได้เช่นกัน:

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

   // ... //
});

คุณต้องส่งคืนค่าเท็จเพื่อหลีกเลี่ยงเหตุการณ์คลิกในองค์ประกอบลูก การแก้ไขผิด
dani24

6

ทางออกของฉัน:

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

คล้ายกับโซลูชันด้านบนของคุณ
user460114

3

โดยส่วนตัวฉันจะเพิ่มตัวจัดการการคลิกให้กับองค์ประกอบย่อยที่ไม่ได้ทำอะไรเลยยกเว้นหยุดการเผยแพร่คลิก ดังนั้นมันจะมีลักษณะดังนี้:

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

อะไรคือข้อแตกต่างระหว่างstopPropagationและผลตอบแทนที่ผิดพลาดเหมือนคำตอบอื่น ๆ ที่แนะนำ
Crashalot

ฉันเชื่อว่าในกรณีนี้พวกเขาจะทำงานเหมือนเดิม แต่ฉันคิดว่าการหยุดยั้งการเผยแพร่นั้นชัดเจนสำหรับวัตถุประสงค์ของสิ่งที่กำลังทำอยู่และทำให้มีโอกาสที่ดีกว่าในการทำความเข้าใจว่าทำไมจึงทำในภายหลัง แต่มันก็เป็นที่ถกเถียงกัน
Noahone

ขอขอบคุณสำหรับการชี้แจง. ดูเหมือนว่าstopPropagationอาจจะสะอาดกว่าเพราะจะไม่หยุดเหตุการณ์ที่เกิดขึ้นกับองค์ประกอบลูกซึ่งอาจเกิดขึ้นreturn falseได้
Crashalot

0

นี่คือตัวอย่าง สี่เหลี่ยมสีเขียวเป็นพาเรนต์และสี่เหลี่ยมสีเหลืองเป็นองค์ประกอบย่อย

หวังว่าสิ่งนี้จะช่วย

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>

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.