2009-07-21 48 views
12

Tương tự như this question, nhưng tiến thêm một bước nữa. Tôi muốn phát hiện nhấp chuột bên ngoài một bộ mặt hàng, mà tôi đang xử lý theo cách sau:Phát hiện nhấp vào phần tử bên ngoài?

$('#menu div').live('click', function() { 
    // Close other open menu items, if any. 
    // Toggle the clicked menu item. 

    $('body').one('click', function(event) { 
     // Hide the menu item. 
     event.stopPropagation(); 
    }); 
}); 

này hoạt động như một nét duyên dáng, thật không may, khi một mục menu được mở và một giây được nhấp, nó đòi hỏi hai lần nhấp chuột để mở mục thứ hai. Nhấp chuột đầu tiên ẩn mục menu đầu tiên đã mở, mục thứ hai hiển thị menu thứ hai mục.

"đúng" hành vi làm theo cách sau:

  • Nhấp chuột vào một mục trình đơn mở ra nó.
  • Nhấp vào cùng một mục menu (hoặc là con của nó).
  • Nhấp vào một mục menu khác để đóng mục đầu tiên, mở mục thứ hai.
  • Cách xa các mục menu (mở) đóng chúng.

Tôi đã thử những điều sau ở vị trí của $('body').one() trật tự trên để bỏ qua nhấp chuột vào các mục menu với rất ít thành công:

// Captures click on menu items in spite of the not. 
$('*').not('#menu *').one('click', function() { // Hide menu } 
$('*:not(#menu)').one('click', function() { // Hide menu } 

Như mọi khi, nhờ sự giúp đỡ nào!

Trả lời

29

Chỉ cần di chuyển xử lý cơ thể nhấp chuột bên ngoài và làm một cái gì đó như thế này:

$('body').bind('click', function(e) { 
    if($(e.target).closest('#menu').length == 0) { 
     // click happened outside of menu, hide any visible menu items 
    } 
}); 

Nó được sai chỉ ra trong các ý kiến ​​rằng e.target không làm việc trong IE; điều này không đúng khi jQuery's Event object khắc phục những mâu thuẫn này khi cần thiết (IE, Safari).

+0

mục đích di chuyển 'body' bấm điều khiển bên ngoài xử lý nhấp chuột đơn là gì? Nó xuất hiện để thực hiện nhiệm vụ tương tự (không có chi phí đánh bắt mỗi nhấp chuột cơ thể nếu trình đơn không bao giờ được mở) bằng cách áp dụng nó sau khi một mục trình đơn được mở ra. Hay tôi đang thiếu một cái gì đó? – chuckg

+0

Đó là một điểm công bằng; Tôi xem xét các chi phí của ràng buộc và unbinding một sự kiện bất cứ khi nào người dùng nhấp vào một mục trình đơn không cần thiết. Thông thường sẽ không có nhiều nhấp chuột vào một trang sang một bên để đi đến một trang khác, trong trường hợp xử lý bấm thêm là hoàn toàn không liên quan. Vào cuối ngày cả hai đều ổn tùy thuộc vào nhu cầu của bạn, vì vậy bạn có thể dính vào một xử lý nếu nó phù hợp với nhu cầu của bạn. –

+0

e.target không hoạt động trên IE ... –

15

tôi đã viết này một thời gian dài trước đây, trước khi những ngày vinh quang của jQuery ...

function clickedOutsideElement(elemId) { 
    var theElem = getEventTarget(window.event); 
    while(theElem != null) { 
    if(theElem.id == elemId) 
     return false; 
    theElem = theElem.offsetParent; 
    } 
    return true; 
} 

function getEventTarget(evt) { 
    var targ = (evt.target) ? evt.target : evt.srcElement; 
    if(targ != null) { 
    if(targ.nodeType == 3) 
     targ = targ.parentNode; 
    } 
    return targ; 
} 

document.onclick = function() { 
    if(clickedOutsideElement('divTest')) 
    alert('Outside the element!'); 
    else 
    alert('Inside the element!'); 
} 
+0

jQuery sửa chữa e.target để vượt qua trình duyệt, do đó hiển thị tất cả điều này không cần thiết. :) –

+0

Tất cả điều này là tranh luận nếu bạn chỉ hỗ trợ IE9 +, hiện tại đã được sửa http://msdn.microsoft.com/en-us/library/ie/ff974946%28v=vs.85%29.aspx – Gabe

Các vấn đề liên quan