Làm thế nào để ngăn chặn sự kiện sủi bọt trên hộp kiểm bấm


182

Tôi có một hộp kiểm mà tôi muốn thực hiện một số hành động Ajax trong sự kiện nhấp chuột, tuy nhiên hộp kiểm cũng nằm trong một thùng chứa có hành vi nhấp chuột riêng mà tôi không muốn chạy khi nhấp vào hộp kiểm. Mẫu này minh họa những gì tôi muốn làm:

$(document).ready(function() {
  $('#container').addClass('hidden');
  $('#header').click(function() {
    if ($('#container').hasClass('hidden')) {
      $('#container').removeClass('hidden');
    } else {
      $('#container').addClass('hidden');
    }
  });
  $('#header input[type=checkbox]').click(function(event) {
    // Do something
  });
});
#container.hidden #body {
  display: none;
}
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<div id="container">
  <div id="header">
    <h1>Title</h1>
    <input type="checkbox" name="test" />
  </div>
  <div id="body">
    <p>Some content</p>
  </div>
</div>

Tuy nhiên, tôi không thể tìm ra cách ngăn chặn sự kiện sủi bọt mà không khiến hành vi nhấp mặc định (hộp kiểm bị kiểm tra / không được chọn) không chạy.

Cả hai điều sau đây đều dừng sự kiện sủi bọt nhưng cũng không thay đổi trạng thái hộp kiểm:

event.preventDefault();
return false;

2
Tôi tìm thấy một bài viết về vấn đề này có thể hữu ích cho các Overflowers Stack khác. Mẹo nhanh: Nhấp vào Hàng Bảng để Kích hoạt Hộp kiểm Nhấp vào
Peder Rice

Câu trả lời:


340

thay thế

event.preventDefault();
return false;

với

event.stopPropagation();

event.stopPropagation ()

Dừng việc tạo bọt của một sự kiện cho các phần tử cha, ngăn bất kỳ trình xử lý cha mẹ nào được thông báo về sự kiện đó.

event.preventDefault ()

Ngăn chặn trình duyệt thực hiện hành động mặc định. Sử dụng phương thức isDefaultPrevented để biết liệu phương thức này có được gọi hay không (trên đối tượng sự kiện đó).


4
vì một số lý do, điều này không hiệu quả với tôi, nhưng trả lại sai.
Randy L

3
Nếu bạn đang ràng buộc sự kiện bằng .live()phương pháp thì điều này sẽ không hoạt động. Bạn sẽ phải sử dụng return false;chính nó.
rahul

2
Công việc này sử dụng .on()phương thức của jQuery (trực tiếp hiện không được chấp nhận). Tôi không thể hiểu tại sao trả về false không hoạt động.
styfle

tôi đã dành khá nhiều thời gian để tìm ra event.preventDefault () không hiển thị dấu kiểm trong IE8, nhưng hoạt động tốt trong các trình duyệt khác. Tôi đã tìm thấy câu trả lời này sau khi tôi sửa và sau đó googling với ngăn chặnDefault, IE8, hộp kiểm dưới dạng từ khóa, đưa tôi đến đây.
Signonsridhar

did'nt làm việc cho .. nhưng hai dòng này đã làm (không trả về false) -> event.preventDefault (); event.stopPropagation ();
Kugan Kumar


29

Đừng quên IE:

if (event.stopPropagation) {    // standard
        event.stopPropagation();
    } else {    // IE6-8
        event.cancelBubble = true;
}

23
Câu trả lời này là từ năm 2012. Trong năm 2015, xin vui lòng quên IE.
Taylan

8
Điều này cũng áp dụng cho IE9. Máy kiểm tra IE9 của tôi bị kẹt trên stopPropagation (), nhưng thích hủyBubble (). Và một số người / org vẫn đang sử dụng IE9 vào năm 2016, thật đáng buồn. Những người trong chúng ta với khách hàng doanh nghiệp không thể bỏ qua điều đó.
Chris Cober

tôi yêu eg5 vào năm 2019
SuperUberDuper

5

Như những người khác đã đề cập, hãy thử stopPropagation().

Và có một trình xử lý thứ hai để thử: event.cancelBubble = true;Đó là trình xử lý cụ thể của IE, nhưng nó được hỗ trợ trong ít nhất FF. Đừng thực sự biết nhiều về nó, vì tôi đã không sử dụng nó cho mình, nhưng nó có thể đáng để thử, nếu tất cả những thứ khác đều thất bại.


5

Đây là một ví dụ tuyệt vời để hiểu khái niệm bong bóng sự kiện. Dựa trên các câu trả lời ở trên, mã cuối cùng sẽ trông giống như được đề cập dưới đây. Khi người dùng Nhấp vào hộp kiểm, việc truyền bá sự kiện đến phần tử chính 'tiêu đề' của nó sẽ bị dừng sử dụng event.stopPropagation();.

$(document).ready(function() {
            $('#container').addClass('hidden');
            $('#header').click(function() {
                if($('#container').hasClass('hidden')) {
                    $('#container').removeClass('hidden');
                } else {
                    $('#container').addClass('hidden');
                }
            });
          $('#header input[type=checkbox]').click(function(event) {
              if (event.stopPropagation) {    // standard
                   event.stopPropagation();
               } else {    // IE6-8
                    event.cancelBubble = true;
               }
          });     
  });

5

Khi sử dụng jQuery, bạn không cần phải gọi hàm dừng riêng biệt.

Bạn chỉ có thể quay lại falsetrong xử lý sự kiện

Điều này sẽ dừng sự kiện và hủy bỏ bong bóng ..

Đồng thời xem event.preventDefault () so với return false

Từ các tài liệu jQuery:

Do đó, các trình xử lý này có thể ngăn trình xử lý được ủy quyền kích hoạt bằng cách gọi event.stopPropagation()hoặc trả lại false.


1

Tín dụng cho @mehras cho mã. Tôi chỉ tạo một đoạn trích để chứng minh điều đó bởi vì tôi nghĩ rằng nó sẽ được đánh giá cao và tôi muốn một cái cớ để thử tính năng đó.

$(document).ready(function() {
  $('#container').addClass('hidden');
  $('#header').click(function() {
    if ($('#container').hasClass('hidden')) {
      $('#container').removeClass('hidden');
    } else {
      $('#container').addClass('hidden');
    }
  });
  $('#header input[type=checkbox]').click(function(event) {
    if (event.stopPropagation) { // standard
      event.stopPropagation();
    } else { // IE6-8
      event.cancelBubble = true;
    }
  });
});
div {
  text-align: center;
  padding: 2em;
  font-size: 1.2em
}

.hidden {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="header"><input type="checkbox" />Checkbox won't bubble the event, but this text will.</div>
<div id="container">click() bubbled up!</div>


Mã thực sự chỉ ra cách sử dụng biến sự kiện, cảm ơn.
Moshe Binieli

-1

Trong angularjs điều này sẽ hoạt động:

event.preventDefault(); 
event.stopPropagation();
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.