jQuery: nhấp vào chức năng loại trừ trẻ em.


144

Cố gắng quấn đầu tôi quanh hàm ".not ()" của jQuery và gặp vấn đề. Tôi muốn có div cha là "có thể nhấp" nhưng nếu người dùng nhấp vào phần tử con, tập lệnh sẽ không được gọi.

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

html:

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

Câu trả lời:


198

Để làm điều này, dừng nhấp chuột vào đứa trẻ bằng cách sử dụng .stopPropagation :

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

Điều này sẽ ngăn các nhấp chuột của trẻ vượt qua mức của chúng để phụ huynh không nhận được nhấp chuột.

.not() được sử dụng một chút khác nhau, nó lọc các thành phần ra khỏi bộ chọn của bạn, ví dụ:

<div class="bob" id="myID"></div>
<div class="bob"></div>

$(".bob").not("#myID"); //removes the element with myID

Để nhấp chuột, vấn đề của bạn là nhấp chuột vào một đứa trẻ bong bóng lên cha mẹ , không phải là bạn đã vô tình gắn một trình xử lý nhấp chuột cho trẻ.


cảm ơn nick, tôi không nghĩ rằng đây là những gì tôi đang tìm kiếm. Tôi xin lỗi vì tôi đã không rõ ràng trong câu hỏi của tôi. Tôi muốn toàn bộ div.example thành fadeOut, chỉ khi nhấp vào phần tử cha chứ không phải khi div con được nhấp. Lý do cho điều này là tôi muốn người dùng có thể nhấp vào văn bản đoạn văn và không có văn bản fadeOut. Nếu người dùng nhấp vào div ngoài (div cha), thì mọi thứ sẽ mờ dần.
superUntitle

@superUntitle - Cảm ơn bạn đã làm rõ ... câu trả lời được cập nhật để làm điều này, hãy thử xem.
Nick Craver

18
@Asaf - sử dụng e.stopPropagation();thay vì return false;cho trường hợp đó.
Nick Craver

2
Bạn cũng có thể sử dụng }).find('.classes-to-ignore').click(function(e) {để chọn các yếu tố con cụ thể
Paul Mason

5
Tôi không hiểu tại sao bạn bảo anh ta sử dụng e.stopPropagation()và sau đó sử dụng return false. return falsetương đương với e.preventDefault(); e.stopPropagation()vì vậy nó có thể có tác dụng phụ không mong muốn.
Steen Schütt

183

Tôi đang sử dụng đánh dấu sau đây và đã gặp phải vấn đề tương tự:

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

Ở đây tôi đã sử dụng logic sau:

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

Về câu hỏi chính xác, tôi có thể thấy rằng hoạt động như sau:

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

hoặc tất nhiên theo cách khác:

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

Mong rằng sẽ giúp.


28
Tôi nghĩ rằng đây là giải pháp tốt hơn. Nó không can thiệp vào trẻ em bằng mọi cách và nó sẽ hoạt động tốt hơn vì nó không có khả năng đăng ký hàng ngàn cuộc gọi lại nếu có hàng ngàn trẻ em.
LucasB

4
@ l2aelba - bạn nên sử dụng .on("click", ...)trong các phiên bản gần đây của jQuery vì .live()đã bị từ chối kể từ v1.7. Xem api.jquery.com/live
Chris

Có, @Chris Tôi đã đăng vào ngày 16 tháng 11 '12 lúc 10:12
l2aelba

Xin lỗi, có lẽ không cần tham khảo ID của bạn. Tôi đã thêm phần bình luận cho bất cứ ai khác đọc câu trả lời này.
Chris

1
Câu trả lời này tốt hơn câu trả lời được chấp nhận vì nó không làm gián đoạn bất kỳ sự kiện nhấp chuột nào trên các phần tử con
cameronjonesweb

24

Hoặc bạn cũng có thể làm:

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

   // ... //
});

Bạn phải trả về false, để tránh sự kiện nhấp chuột trong các phần tử con. Bản sửa đổi đã sai
dani24

6

Giải pháp của tôi:

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

Tương tự như giải pháp trên của bạn.
dùng460114

3

Cá nhân tôi sẽ thêm một trình xử lý nhấp chuột vào phần tử con mà không làm gì ngoài việc ngăn chặn sự lan truyền của nhấp chuột. Vì vậy, nó sẽ trông giống như:

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

sự khác biệt giữa stopPropagationvà trả về sai như các câu trả lời khác gợi ý gì?
Crashalot

Tôi tin rằng trong trường hợp này chúng sẽ hoạt động giống nhau, nhưng tôi nghĩ rằng việc truyền bá dừng lại rõ ràng hơn với mục đích của những gì đang được thực hiện và để lại cơ hội tốt hơn để hiểu tại sao nó lại được thực hiện sau đó. Nhưng nó gây tranh cãi.

Cảm ơn bạn đã làm rõ. có vẻ như stopPropagationcó thể sạch hơn vì nó sẽ không ngăn các sự kiện trên các phần tử con xảy ra, điều này có thể xảy ra với return false.
Crashalot

0

Đây là một ví dụ. Hình vuông màu xanh lá cây là cha mẹ và hình vuông màu vàng là yếu tố con.

Hy vọng rằng điều này sẽ giúp.

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>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.