2012-01-30 1 views
6

Tôi cần phải liên kết hai sự kiện trong backbone.js -view để chuyển đổi menu. Ý tưởng là nếu một nút có id #toggler được nhấp vào trình đơn ứng dụng và bất kỳ nhấp chuột nào bên ngoài phần tử #menu sẽ ẩn menu.Nhấp chuột ràng buộc sự kiện với backbone.js & jQuery

Thật không may tôi không thể làm việc này với sự kiện ràng buộc của xương sống mà không có số outsideMenuHandler() được gọi cho mỗi nhấp chuột bất kể tôi có nhấp vào thành phần #menu hay không.

Tôi nên thay đổi điều gì để thực hiện công việc này?

Đây là những gì tôi đã làm trong backbone.js, mà không làm việc như mong đợi:

myView = Backbone.View.extend({ 

    events: { 
     'click #menu': 'insideMenuHandler', 
     'click':  'outsideMenuHandler' 
    } 

    insideMenuHandler: function(e) {}, // Called when clicking #menu 
    outsideMenuHandler: function(e) {} // Called on every click both on and off #menu 

} 

Cũng giống như một tài liệu tham khảo, đây là những gì tôi sẽ làm bằng jQuery một mình:

$(document).click(function(event) { 
    if ($(event.target).closest('#menu').get(0) == null) { 
     $("#menu").slideUp(); 
    } 
}); 

Trả lời

14

Có một vài điều bạn cần sắp xếp.

Trước hết, nếu insideMenuHandler lợi nhuận của bạn false hoặc gọi e.stopPropogation() sau đó bạn outsideMenuHandler sẽ không được gọi cho các nhấp chuột trên #menu. Ví dụ:

http://jsfiddle.net/ambiguous/8GjdS/

Nhưng đó không phải là toàn bộ vấn đề của bạn. outsideMenuHandler của bạn sẽ chỉ được gọi cho các nhấp chuột trên chế độ xem của bạn; vì vậy, nếu ai đó nhấp vào trang bên ngoài chế độ xem của bạn, thì outsideMenuHandler của bạn sẽ không được gọi và menu của bạn sẽ không bị hỏng. Nếu bạn muốn menu xuống khi ai đó nhấp vào bất kỳ nơi nào bên ngoài #menu, thì bạn sẽ phải liên kết theo cách thủ công với body và hủy liên kết theo cách thủ công khi chế độ xem của bạn bị hủy. Một cái gì đó như thế này:

var myView = Backbone.View.extend({ 
    events: { 
     'click #menu': 'insideMenuHandler' 
    }, 

    initialize: function() { 
     _.bindAll(this, 'insideMenuHandler', 'outsideMenuHandler'); 
    }, 

    render: function() { 
     // Both <body> and <html> for paranoia. 
     $('body, html').on('click', this.outsideMenuHandler); 
     // ... 
     return this; 
    }, 

    remove: function() { 
     // Clean up after ourselves. 
     $('body, html').off('click', this.outsideMenuHandler); 
     // ... 
    }, 

    // ... 
    outsideMenuHandler: function(e) { 
     // ... 
     return false; 
    } 
}); 

và sau đó đảm bảo xóa đúng chế độ xem của bạn. Ví dụ:

http://jsfiddle.net/ambiguous/MgkWG/1/

+0

Cảm ơn rất nhiều cho câu trả lời của bạn. Rất được đánh giá cao! Một câu hỏi nhanh - như tôi hiểu, cho phép một sự kiện nhấp chuột trả về 'false' sẽ ngăn chặn bất kỳ" sự kiện mặc định "nào xảy ra, có nghĩa là tất cả các nhấp chuột khác sẽ bị tắt khi' externalMenuHandler' trả về 'false'. Tôi có gặp rắc rối không nếu tôi để 'externalMenuHandler' trả về' true' sau khi thực hiện logic của mình (ẩn menu của tôi)? – Industrial

+1

@Industrial: Bạn sẽ kết thúc với các cuộc gọi kép tới 'externalMenuHandler' từ liên kết' body, html' nhưng điều đó có thể không thành vấn đề. Bạn có thể có thể lấy đi với chỉ ràng buộc 'externalMenuHandler' để' html' nhưng bạn muốn trình duyệt kiểm tra để đảm bảo nó hoạt động đúng trong tất cả các trình duyệt mà bạn quan tâm. –

-1

Vấn đề là, bạn ràng buộc sự kiện của mình với phần tử DOM mà bạn xác định làm lượt xem. Vì vậy, nếu đây không phải là window.document như trong ví dụ jquery của bạn, bạn không thể nhận thấy bất kỳ nhấp chuột bên ngoài chúng. Cách dễ nhất trong ví dụ của bạn là thêm các sự kiện theo cách thủ công với jquery chứ không phải với xương sống.