Câu hỏi Làm thế nào để phát hiện một nhấp chuột bên ngoài một phần tử?


Tôi có một số menu HTML, mà tôi hiển thị hoàn toàn khi người dùng nhấp vào phần đầu của các trình đơn này. Tôi muốn ẩn các yếu tố này khi người dùng nhấp vào bên ngoài khu vực của menu.

Là một cái gì đó như thế này có thể với jQuery?

$("#menuscontainer").clickOutsideThisElement(function() {
    // Hide the menus
});

2027


gốc


Đây là một ví dụ về chiến lược này: jsfiddle.net/tedp/aL7Xe/1 - Ted
Như Tom đã đề cập, bạn sẽ muốn đọc css-tricks.com/dangers-stopping-event-propagation trước khi sử dụng phương pháp này. Công cụ jsfiddle đó là khá mát mẻ mặc dù. - Jon Coombs
lấy một tham chiếu đến phần tử và sau đó event.target, và cuối cùng! = hoặc == cả hai đều sau đó thực thi mã cho phù hợp .. - Rohit Kumar
Tôi khuyên bạn nên sử dụng github.com/gsantiago/jquery-clickout :) - Rômulo M. Farias
Thử sử dụng event.path. http://stackoverflow.com/questions/152975/how-do-i-detect-a-click-outside-an-element/43405204#43405204 - Dan Philip


Các câu trả lời:


LƯU Ý: Sử dụng stopEventPropagation() là một thứ cần tránh vì nó phá vỡ luồng sự kiện bình thường trong DOM. Xem bài viết này để biết thêm thông tin. Cân nhắc sử dụng phương pháp này thay thế.

Đính kèm sự kiện nhấp chuột vào phần thân tài liệu để đóng cửa sổ. Đính kèm một sự kiện nhấp chuột riêng biệt vào vùng chứa ngăn chặn việc truyền đến cơ thể tài liệu.

$(window).click(function() {
//Hide the menus if visible
});

$('#menucontainer').click(function(event){
    event.stopPropagation();
});

1620



Điều này phá vỡ hành vi tiêu chuẩn của nhiều thứ, bao gồm các nút và liên kết, chứa trong #menucontainer. Tôi ngạc nhiên câu trả lời này rất phổ biến. - Art
Điều này không phá vỡ hành vi của bất cứ điều gì bên trong #menucontainer, vì nó ở dưới cùng của chuỗi tuyên truyền cho bất cứ điều gì bên trong của nó. - Eran Galperin
nó rất đẹp nhưng bạn nên sử dụng $('html').click() không phải cơ thể. Thân thể luôn có chiều cao của nội dung. Nó không có nhiều nội dung hoặc màn hình rất cao, nó chỉ hoạt động trên phần được lấp đầy bởi cơ thể. - meo
Tôi cũng ngạc nhiên rằng giải pháp này có rất nhiều phiếu bầu. Điều này sẽ không thành công cho bất kỳ phần tử nào bên ngoài có stopPropagation jsfiddle.net/Flandre/vaNFw/3 - Andre
Philip Walton giải thích rất rõ tại sao câu trả lời này không phải là giải pháp tốt nhất: css-tricks.com/dangers-stopping-event-propagation - Tom


Bạn có thể nghe một nhấp chuột sự kiện trên document và sau đó đảm bảo #menucontainer không phải là tổ tiên hoặc mục tiêu của phần tử được nhấp bằng cách sử dụng .closest().

Nếu không, thì phần tử được nhấp nằm ngoài #menucontainer và bạn có thể giấu nó một cách an toàn.

$(document).click(function(event) { 
    if(!$(event.target).closest('#menucontainer').length) {
        if($('#menucontainer').is(":visible")) {
            $('#menucontainer').hide();
        }
    }        
});

Chỉnh sửa - 2017-06-23

Bạn cũng có thể dọn dẹp sau khi người nghe sự kiện nếu bạn có kế hoạch loại bỏ trình đơn và muốn ngừng nghe các sự kiện. Chức năng này sẽ chỉ dọn dẹp người nghe mới được tạo ra, giữ lại bất kỳ trình nghe nhấp chuột nào khác document. Với cú pháp ES2015:

export function hideOnClickOutside(selector) {
  const outsideClickListener = (event) => {
    if (!$(event.target).closest(selector).length) {
      if ($(selector).is(':visible')) {
        $(selector).hide()
        removeClickListener()
      }
    }
  }

  const removeClickListener = () => {
    document.removeEventListener('click', outsideClickListener)
  }

  document.addEventListener('click', outsideClickListener)
}

Chỉnh sửa - 2018-03-11

Đối với những người không muốn sử dụng jQuery. Đây là đoạn mã trên trong vanillaJS đơn giản (ECMAScript6).

function hideOnClickOutside(element) {
    const outsideClickListener = event => {
        if (!element.contains(event.target)) { // or use: event.target.closest(selector) === null
            if (isVisible(element)) {
                element.style.display = 'none'
                removeClickListener()
            }
        }
    }

    const removeClickListener = () => {
        document.removeEventListener('click', outsideClickListener)
    }

    document.addEventListener('click', outsideClickListener)
}

const isVisible = elem => !!elem && !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ) // source (2018-03-11): https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js 

CHÚ THÍCH: Điều này được dựa trên Alex bình luận để chỉ sử dụng !element.contains(event.target) thay vì phần jQuery.

Nhưng element.closest() bây giờ cũng có sẵn trong tất cả các trình duyệt chính (phiên bản W3C khác một chút so với phiên bản jQuery). Polyfills có thể được tìm thấy ở đây: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest


1127



Tôi đã thử nhiều câu trả lời khác, nhưng chỉ có một câu trả lời. Cảm ơn. Mã tôi đã sử dụng cuối cùng là: $ (document) .click (function (event) {if ($ (event.target) .closest ('. Window'). Length == 0) {$ ('. Window' ) .fadeOut ('fast');}}); - Pistos
Tôi thực sự đã kết thúc với giải pháp này bởi vì nó hỗ trợ tốt hơn nhiều menu trên cùng một trang, nơi nhấp vào menu thứ hai trong khi lần đầu tiên mở sẽ để mở đầu tiên trong giải pháp stopPropagation. - umassthrower
Đây là một giải pháp rất tốt cho nhiều mục trên trang. - jsgroove
Câu trả lời tuyệt vời. Đây là cách để đi khi bạn có nhiều mục mà bạn muốn đóng. - John
Không có jQuery - - !element.contains(event.target) sử dụng Node.contains () - Alex Ross


Làm thế nào để phát hiện một nhấp chuột bên ngoài một phần tử?

Lý do mà câu hỏi này rất phổ biến và có rất nhiều câu trả lời là nó phức tạp một cách phức tạp. Sau gần tám năm và hàng chục câu trả lời, tôi thực sự ngạc nhiên khi thấy sự chăm sóc ít được đưa đến khả năng tiếp cận.

Tôi muốn ẩn các yếu tố này khi người dùng nhấp vào bên ngoài khu vực của menu.

Đây là một nguyên nhân cao quý và là thực tế vấn đề. Tiêu đề của câu hỏi - đó là những gì hầu hết các câu trả lời xuất hiện để cố gắng giải quyết - có một cá trích đỏ không may.

Gợi ý: đó là từ "nhấp chuột"!

Bạn thực sự không muốn ràng buộc các trình xử lý nhấp chuột.

Nếu bạn đang ràng buộc xử lý nhấp chuột để đóng hộp thoại, bạn đã thất bại. Lý do bạn đã thất bại là không phải mọi người đều kích hoạt click sự kiện. Người dùng không sử dụng chuột sẽ có thể thoát khỏi hộp thoại của bạn (và trình đơn bật lên của bạn được cho là một loại hộp thoại) bằng cách nhấn Chuyển hướngvà sau đó họ sẽ không thể đọc nội dung phía sau hộp thoại mà không kích hoạt click biến cố.

Vì vậy, hãy lặp lại câu hỏi.

Làm cách nào để đóng hộp thoại khi người dùng kết thúc bằng hộp thoại?

Đây là mục tiêu. Thật không may, bây giờ chúng ta cần phải ràng buộc userisfinishedwiththedialog sự kiện và ràng buộc đó không đơn giản như vậy.

Vậy làm thế nào chúng ta có thể phát hiện ra rằng một người dùng đã hoàn thành bằng cách sử dụng một hộp thoại?

focusout biến cố

Một khởi đầu tốt là xác định xem trọng tâm đã rời khỏi hộp thoại chưa.

Gợi ý: hãy cẩn thận với blur biến cố, blur không tuyên truyền nếu sự kiện đã bị ràng buộc với pha sủi bọt!

jQuery focusout sẽ làm tốt. Nếu bạn không thể sử dụng jQuery, thì bạn có thể sử dụng blur trong giai đoạn chụp:

element.addEventListener('blur', ..., true);
//                       use capture: ^^^^

Ngoài ra, đối với nhiều hộp thoại, bạn sẽ cần cho phép vùng chứa lấy tiêu điểm. Thêm vào tabindex="-1" để cho phép hộp thoại tự động nhận tiêu điểm mà không làm gián đoạn luồng tabbing.

$('a').on('click', function () {
  $(this.hash).toggleClass('active').focus();
});

$('div').on('focusout', function () {
  $(this).removeClass('active');
});
div {
  display: none;
}
.active {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#example">Example</a>
<div id="example" tabindex="-1">
  Lorem ipsum <a href="http://example.com">dolor</a> sit amet.
</div>


Nếu bạn chơi với bản demo đó trong hơn một phút, bạn sẽ nhanh chóng bắt đầu thấy các vấn đề.

Đầu tiên là liên kết trong hộp thoại không thể nhấp được. Việc cố gắng nhấp vào tab hoặc tab đó sẽ dẫn đến hộp thoại đóng trước khi tương tác diễn ra. Điều này là do việc tập trung phần tử bên trong kích hoạt focusout sự kiện trước khi kích hoạt focusin sự kiện một lần nữa.

Sửa chữa là xếp hàng thay đổi trạng thái trên vòng lặp sự kiện. Điều này có thể được thực hiện bằng cách sử dụng setImmediate(...), hoặc là setTimeout(..., 0) cho các trình duyệt không hỗ trợ setImmediate. Sau khi xếp hàng, nó có thể bị hủy bởi một focusin:

$('.submenu').on({
  focusout: function (e) {
    $(this).data('submenuTimer', setTimeout(function () {
      $(this).removeClass('submenu--active');
    }.bind(this), 0));
  },
  focusin: function (e) {
    clearTimeout($(this).data('submenuTimer'));
  }
});

$('a').on('click', function () {
  $(this.hash).toggleClass('active').focus();
});

$('div').on({
  focusout: function () {
    $(this).data('timer', setTimeout(function () {
      $(this).removeClass('active');
    }.bind(this), 0));
  },
  focusin: function () {
    clearTimeout($(this).data('timer'));
  }
});
div {
  display: none;
}
.active {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#example">Example</a>
<div id="example" tabindex="-1">
  Lorem ipsum <a href="http://example.com">dolor</a> sit amet.
</div>

Vấn đề thứ hai là hộp thoại sẽ không đóng khi liên kết được nhấn lần nữa. Điều này là do hộp thoại mất tiêu điểm, kích hoạt hành vi đóng, sau đó nhấp vào liên kết sẽ kích hoạt hộp thoại mở lại.

Tương tự như vấn đề trước, trạng thái lấy nét cần phải được quản lý. Cho rằng sự thay đổi trạng thái đã được xếp hàng đợi, nó chỉ là vấn đề xử lý các sự kiện tập trung vào các kích hoạt hộp thoại:

Cái này trông quen thuộc
$('a').on({
  focusout: function () {
    $(this.hash).data('timer', setTimeout(function () {
      $(this.hash).removeClass('active');
    }.bind(this), 0));
  },
  focusin: function () {
    clearTimeout($(this.hash).data('timer'));  
  }
});

$('a').on('click', function () {
  $(this.hash).toggleClass('active').focus();
});

$('div').on({
  focusout: function () {
    $(this).data('timer', setTimeout(function () {
      $(this).removeClass('active');
    }.bind(this), 0));
  },
  focusin: function () {
    clearTimeout($(this).data('timer'));
  }
});

$('a').on({
  focusout: function () {
    $(this.hash).data('timer', setTimeout(function () {
      $(this.hash).removeClass('active');
    }.bind(this), 0));
  },
  focusin: function () {
    clearTimeout($(this.hash).data('timer'));  
  }
});
div {
  display: none;
}
.active {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#example">Example</a>
<div id="example" tabindex="-1">
  Lorem ipsum <a href="http://example.com">dolor</a> sit amet.
</div>


Esc Chìa khóa

Nếu bạn nghĩ rằng bạn đã được thực hiện bằng cách xử lý các trạng thái tập trung, có nhiều bạn có thể làm để đơn giản hóa trải nghiệm người dùng.

Đây thường là một tính năng "rất hay để có", nhưng thông thường là khi bạn có một phương thức hoặc cửa sổ bật lên của bất kỳ loại nào Esc sẽ đóng nó ra.

keydown: function (e) {
  if (e.which === 27) {
    $(this).removeClass('active');
    e.preventDefault();
  }
}

$('a').on('click', function () {
  $(this.hash).toggleClass('active').focus();
});

$('div').on({
  focusout: function () {
    $(this).data('timer', setTimeout(function () {
      $(this).removeClass('active');
    }.bind(this), 0));
  },
  focusin: function () {
    clearTimeout($(this).data('timer'));
  },
  keydown: function (e) {
    if (e.which === 27) {
      $(this).removeClass('active');
      e.preventDefault();
    }
  }
});

$('a').on({
  focusout: function () {
    $(this.hash).data('timer', setTimeout(function () {
      $(this.hash).removeClass('active');
    }.bind(this), 0));
  },
  focusin: function () {
    clearTimeout($(this.hash).data('timer'));  
  }
});
div {
  display: none;
}
.active {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="#example">Example</a>
<div id="example" tabindex="-1">
  Lorem ipsum <a href="http://example.com">dolor</a> sit amet.
</div>


Nếu bạn biết bạn có các phần tử có thể đặt tiêu điểm trong hộp thoại, bạn sẽ không cần phải tập trung trực tiếp hộp thoại. Nếu bạn đang xây dựng một menu, bạn có thể tập trung vào mục menu đầu tiên thay thế.

click: function (e) {
  $(this.hash)
    .toggleClass('submenu--active')
    .find('a:first')
    .focus();
  e.preventDefault();
}

$('.menu__link').on({
  click: function (e) {
    $(this.hash)
      .toggleClass('submenu--active')
      .find('a:first')
      .focus();
    e.preventDefault();
  },
  focusout: function () {
    $(this.hash).data('submenuTimer', setTimeout(function () {
      $(this.hash).removeClass('submenu--active');
    }.bind(this), 0));
  },
  focusin: function () {
    clearTimeout($(this.hash).data('submenuTimer'));  
  }
});

$('.submenu').on({
  focusout: function () {
    $(this).data('submenuTimer', setTimeout(function () {
      $(this).removeClass('submenu--active');
    }.bind(this), 0));
  },
  focusin: function () {
    clearTimeout($(this).data('submenuTimer'));
  },
  keydown: function (e) {
    if (e.which === 27) {
      $(this).removeClass('submenu--active');
      e.preventDefault();
    }
  }
});
.menu {
  list-style: none;
  margin: 0;
  padding: 0;
}
.menu:after {
  clear: both;
  content: '';
  display: table;
}
.menu__item {
  float: left;
  position: relative;
}

.menu__link {
  background-color: lightblue;
  color: black;
  display: block;
  padding: 0.5em 1em;
  text-decoration: none;
}
.menu__link:hover,
.menu__link:focus {
  background-color: black;
  color: lightblue;
}

.submenu {
  border: 1px solid black;
  display: none;
  left: 0;
  list-style: none;
  margin: 0;
  padding: 0;
  position: absolute;
  top: 100%;
}
.submenu--active {
  display: block;
}

.submenu__item {
  width: 150px;
}

.submenu__link {
  background-color: lightblue;
  color: black;
  display: block;
  padding: 0.5em 1em;
  text-decoration: none;
}

.submenu__link:hover,
.submenu__link:focus {
  background-color: black;
  color: lightblue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="menu">
  <li class="menu__item">
    <a class="menu__link" href="#menu-1">Menu 1</a>
    <ul class="submenu" id="menu-1" tabindex="-1">
      <li class="submenu__item"><a class="submenu__link" href="http://example.com/#1">Example 1</a></li>
      <li class="submenu__item"><a class="submenu__link" href="http://example.com/#2">Example 2</a></li>
      <li class="submenu__item"><a class="submenu__link" href="http://example.com/#3">Example 3</a></li>
      <li class="submenu__item"><a class="submenu__link" href="http://example.com/#4">Example 4</a></li>
    </ul>
  </li>
  <li class="menu__item">
    <a  class="menu__link" href="#menu-2">Menu 2</a>
    <ul class="submenu" id="menu-2" tabindex="-1">
      <li class="submenu__item"><a class="submenu__link" href="http://example.com/#1">Example 1</a></li>
      <li class="submenu__item"><a class="submenu__link" href="http://example.com/#2">Example 2</a></li>
      <li class="submenu__item"><a class="submenu__link" href="http://example.com/#3">Example 3</a></li>
      <li class="submenu__item"><a class="submenu__link" href="http://example.com/#4">Example 4</a></li>
    </ul>
  </li>
</ul>
lorem ipsum <a href="http://example.com/">dolor</a> sit amet.


Vai trò WAI-ARIA và Hỗ trợ trợ năng khác

Câu trả lời này hy vọng bao gồm những điều cơ bản về hỗ trợ bàn phím và chuột có thể truy cập cho tính năng này, nhưng vì nó đã khá lớn, tôi sẽ tránh bất kỳ cuộc thảo luận nào về Vai trò và thuộc tính WAI-ARIA, Tuy nhiên, tôi cao khuyên các nhà triển khai tham khảo thông số để biết chi tiết về vai trò nào họ nên sử dụng và bất kỳ thuộc tính thích hợp nào khác.


188



Đây là câu trả lời hoàn chỉnh nhất, với các giải thích và khả năng truy cập trong tâm trí. Tôi nghĩ rằng đây sẽ là câu trả lời được chấp nhận vì hầu hết các câu trả lời khác chỉ xử lý nhấp chuột và chỉ là đoạn mã được thả mà không có bất kỳ giải thích nào. - Cyrille
Tuyệt vời, cũng được giải thích. Tôi chỉ sử dụng phương pháp này trên một thành phần React và làm việc một cách hoàn hảo nhờ - David Lavieri
@zzzzBov cảm ơn cho câu trả lời sâu sắc, tôi đang cố gắng để đạt được nó trong JS vanilla, và tôi là một chút bị mất với tất cả các công cụ jquery. có gì tương tự trong vanilla js không? - HendrikEng
@zzzzBov không có tôi không tìm kiếm cho bạn để viết một phiên bản jQuery-miễn phí của khóa học, tôi sẽ cố gắng để làm điều đó và tôi đoán là tốt nhất là để hỏi một câu hỏi mới ở đây nếu tôi thực sự gặp khó khăn. Cảm ơn rất nhiều lần nữa. - HendrikEng
Mặc dù đây là một phương pháp tuyệt vời để phát hiện việc nhấp vào các trình đơn thả xuống tùy chỉnh hoặc các yếu tố đầu vào khác, nó không bao giờ là phương thức ưa thích cho các phương thức hoặc quảng cáo vì hai lý do. Phương thức sẽ đóng khi người dùng chuyển sang tab hoặc cửa sổ khác hoặc mở menu ngữ cảnh, điều này thực sự gây phiền toái. Ngoài ra, sự kiện 'nhấp vào' kích hoạt khi di chuột lên, trong khi sự kiện 'tập trung' kích hoạt tức thì bạn nhấn chuột xuống. Thông thường, một nút chỉ thực hiện một hành động nếu bạn nhấn nút chuột và sau đó thả. Cách thích hợp, dễ tiếp cận để thực hiện việc này đối với các phương thức là thêm một nút đóng tabbable. - Kevin


Các giải pháp khác ở đây không hiệu quả với tôi vì vậy tôi phải sử dụng:

if(!$(event.target).is('#foo'))
{
    // hide menu
}

127



Tôi đã đăng một ví dụ thực tế khác về cách sử dụng event.target để tránh kích hoạt tiện ích Jquery UI khác bên ngoài trình xử lý html khi nhúng chúng vào hộp pop-over của riêng bạn: Cách tốt nhất để có được Mục tiêu ban đầu - Joey T
Điều này làm việc cho tôi, ngoại trừ tôi đã thêm && !$(event.target).parents("#foo").is("#foo") bên trong IF tuyên bố sao cho mọi phần tử con sẽ không đóng menu khi được nhấp. - honyovk
@Frug Câu trả lời của bạn có thể có giá trị để bạn có 5, nhưng tôi đã nhầm lẫn bởi câu trả lời của bạn. và ai là MBJ. Tôi đang tìm cách tạo ra giải pháp tốt hơn dựa trên câu trả lời của bạn. - Satya Prakash
MBJ có lẽ là tên cũ của người đã đăng bình luận ngay phía trên của tôi. Người dùng thay đổi tên, nó có thể làm cho nó khó khăn nhưng nhận thấy bình luận ở trên tôi đã thêm .parents("#foo") - Frug
Việc cải tiến ngắn gọn để xử lý sâu làm tổ là sử dụng .is('#foo, #foo *'), nhưng Tôi không khuyên bạn nên sử dụng trình xử lý nhấp chuột ràng buộc để giải quyết vấn đề này. - zzzzBov


Tôi có một ứng dụng hoạt động tương tự như ví dụ của Eran, ngoại trừ tôi đính kèm sự kiện bấm vào phần thân khi tôi mở menu ... Kinda như thế này:

$('#menucontainer').click(function(event) {
  $('html').one('click',function() {
    // Hide the menus
  });

  event.stopPropagation();
});

Thêm thông tin về jQuery one() chức năng


118



nhưng sau đó nếu bạn bấm vào trình đơn chính nó, sau đó bên ngoài, nó sẽ không hoạt động :) - vsync
Nó giúp đặt event.stopProgagantion () trước khi gắn trình nghe click vào phần thân. - Jasper Kennis
Vấn đề với điều này là "một" áp dụng cho phương thức jQuery thêm các sự kiện vào một mảng nhiều lần. Vì vậy, nếu bạn nhấp vào trình đơn để mở nó nhiều lần, sự kiện sẽ bị ràng buộc với cơ thể một lần nữa và cố gắng ẩn menu nhiều lần. Bạn nên áp dụng một failsafe để khắc phục sự cố này. - marksyzm
Sau khi ràng buộc sử dụng .one - bên trong của $('html') xử lý - viết một $('html').off('click'). - Cody
@ Tôi không nghĩ điều đó có ích. Các one xử lý sẽ tự động gọi off (như được hiển thị trong tài liệu jQuery). - Mariano Desanze


$("#menuscontainer").click(function() {
    $(this).focus();
});
$("#menuscontainer").blur(function(){
    $(this).hide();
});

Làm việc cho tôi tốt.


32



Đây là cái tôi muốn dùng. Nó có thể không hoàn hảo, nhưng là một lập trình viên sở thích, nó đủ đơn giản để hiểu rõ ràng. - kevtrout
mờ là một động thái bên ngoài #menucontainer câu hỏi là về một cú nhấp chuột - borrel
@borrel blur là không phải di chuyển ra ngoài thùng chứa. Blur là đối diện của tập trung, bạn đang nghĩ đến mouseout. Giải pháp này làm việc đặc biệt tốt cho tôi khi tôi đang tạo văn bản "nhấp để chỉnh sửa" nơi tôi đổi chỗ qua lại giữa các trường văn bản thuần túy và các trường nhập khi nhấp chuột. - parker.sikand
Tôi phải thêm tabindex="-1" đến #menuscontainer Để làm cho nó hoạt động. Có vẻ như nếu bạn đặt một thẻ đầu vào bên trong vùng chứa và nhấp vào nó, vùng chứa sẽ bị ẩn. - tyrion
sự kiện mouseleave là phù hợp hơn cho các menu và container (ref: w3schools.com/jquery/…) - Evgenia Manolova


Bây giờ có một plugin cho rằng: sự kiện bên ngoài (bài viết trên blog)

Điều sau xảy ra khi clickoutside Trình xử lý (WLOG) được ràng buộc với một phần tử:

  • phần tử được thêm vào một mảng chứa tất cả các phần tử clickoutside người xử lý
  • a (không gian tên) nhấp chuột handler bị ràng buộc vào tài liệu (nếu chưa có)
  • trên bất kỳ nhấp chuột trong tài liệu, clickoutside sự kiện được kích hoạt cho những yếu tố trong mảng đó không bằng hoặc cha mẹ của nhấp chuộtmục tiêu
  • ngoài ra, mục tiêu sự kiện cho clickoutside sự kiện được đặt thành phần tử mà người dùng đã nhấp vào (để bạn thậm chí biết những gì người dùng đã nhấp vào, không chỉ là anh ta đã nhấp vào bên ngoài)

Vì vậy, không có sự kiện nào bị dừng lại do tuyên truyền và bổ sung nhấp chuột xử lý có thể được sử dụng "trên" các yếu tố với bên ngoài xử lý.


31



Plugin đẹp. Liên kết trên "sự kiện bên ngoài" đã chết, trong khi liên kết bài đăng trên blog vẫn còn hoạt động và cung cấp một plugin rất hữu ích cho các sự kiện loại "nhấp chuột". Nó cũng được cấp phép MIT. - TechNyquist
Plugin tuyệt vời. Làm việc hoàn hảo. Cách sử dụng giống như vậy: $( '#element' ).on( 'clickoutside', function( e ) { .. } ); - Gavin