2015-03-02 17 views
8
function bubble(content, triggerElm){ 
    this.element = $('<div class="bubble" />').html(content); 
    this.element.css(.....) // here is positioned based on triggerElm 
} 

bubble.prototype.show = function(){ 
    $(document).on('click', this._click.bind(this)); 
    this.element.css(....) 
}; 

bubble.prototype.hide = function(){ 
    $(document).off('click', this._click.bind(this)); 
    this.element.css(....) 
}; 

bubble.prototype._click = function(event){ 
    console.log('click', this); 

    if(this.element.is(event.target) || (this.element.has(event.target).length > 0)) 
    return true; 

    this.hide(); 
}; 

var b = new bubble(); 
b.show(); 
b.hide(); 

Tôi tiếp tục thấy nhấp chuột trong bảng điều khiển, do đó, nhấp chuột không hủy liên kết. Nhưng nếu tôi loại bỏ ràng buộc() gọi nhấp chuột là unbinded. Có ai biết tại sao không? Tôi cần một cách để có thể thay đổi "này" trong chức năng thử nghiệm của tôi, đó là lý do tại sao tôi đang sử dụng bind()jQuery off() không phải là sự kiện không liên kết khi sử dụng liên kết

Trả lời

4

Vấn đề là this._click.bind() tạo một hàm mới mỗi khi nó được gọi. Để tách một trình xử lý sự kiện cụ thể, bạn cần truyền vào hàm ban đầu được sử dụng để tạo trình xử lý sự kiện và điều đó không xảy ra ở đây, do đó trình xử lý không bị loại bỏ.

Nếu chỉ có một vài số bubble giây trong ứng dụng của bạn, bạn có thể sử dụng tuyến đường của Douglas Crockford và chỉ đơn giản là không sử dụng this. Điều đó sẽ loại bỏ rất nhiều sự nhầm lẫn về những gì this là đề cập đến và đảm bảo rằng mỗi bubble giữ một tham chiếu đến click chức năng riêng của nó có thể được sử dụng để loại bỏ sự kiện này khi cần thiết:

function bubble(content, tiggerElm) { 
    var element = $('<div class="bubble" />').html(content); 
    element.css(.....); // here is positioned based on triggerElm 

    function click(event) { 
     console.log('click', element); 
     if (element.is(event.target) || 
      element.has(event.target).length > 0) { 
      return true; 
     } 
     hide(); 
    } 

    function show() { 
     $(document).on('click', click); 
     element.css(....); 
    } 

    function hide() { 
     $(document).off('click', click); 
     element.css(....); 
    } 

    return { 
     show: show, 
     hide: hide 
    }; 
} 

var b1 = bubble(..., ...); 
b1.show(); 

var b2 = bubble(..., ...); 
b2.show(); 

Xem cách này giải phóng bạn từ việc sử dụng các contrivances như .bind() và các phương thức tiền tố dấu gạch dưới.

+0

nhưng tôi không thể truy cập vào "này" Ví dụ bên trong click – Elfy

+0

@Elfy Vâng, đó là sự thật. Mày cần nó để làm gì? – JLRishe

+0

Vâng, tôi cần phải có thể biết liệu nhấp chuột có nằm ngoài phần tử bong bóng hay không và đó là một phần của cá thể. Về cơ bản bên trong hàm click Im kiểm tra nếu e.target là this.element hoặc bên trong nó – Elfy

5

Một lựa chọn sẽ được namespace the event:

$(document).on('click.name', test.bind(this)); 
$(document).off('click.name'); 

Example Here

+0

Josh Crozier, điều đó có nghĩa là mọi sự kiện gắn với không gian tên đều bị xóa. không chắc chắn nếu đó là những gì anh ta muốn. –

+1

@NetaMeta Vì vậy, chỉ cần đặt cho nó một tên duy nhất, và nó không phải là một vấn đề. –

+1

@ Josh Crozier - thì tại sao lại sử dụng thùng hoặc tại sao làm phiền giữ toàn cầu rõ ràng - chỉ cần đặt tên cho các tên độc nhất vô nhị của bạn ... –

3

Hãy đọc https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

liên kết tạo ra một hàm mới do đó thực hiện $(document).on('click', test.bind(this)); giống như $(document).on('click', function(){}); và mỗi khi bạn thực thi nó, bạn gọi hàm ẩn danh mới, do đó bạn không có tham chiếu đến trói buộc.

Nếu bạn muốn làm điều gì đó như:

var test = function(){ 
    console.log('click'); 
}; 

var newFunct = test.bind(this); 
$(document).on('click', newFunct); 
$(document).off('click', newFunct); 

Nó sẽ làm việc tốt

ví dụ: http://jsfiddle.net/508dr0hv/

Ngoài ra - sử dụng ràng buộc không được khuyến khích, chậm và không được hỗ trợ trong một số trình duyệt.

+0

cảm ơn. nhưng nếu chức năng thử nghiệm của tôi là một phần của một đối tượng thì làm thế nào để ràng buộc nó? Tôi có nghĩa là nơi nào tôi làm điều đó :) – Elfy

+1

Elfy thêm trường hợp đó vào câu hỏi của bạn để chứng minh ý bạn là gì. –

+0

ok tôi đã thêm mã gần với tình hình thực tế của tôi – Elfy

4

hãy thử sử dụng proxy của jQuery để nhận tham chiếu duy nhất về chức năng của bạn.

Bằng cách này, khi bạn gọi $ .proxy (kiểm tra, điều này), nó sẽ kiểm tra xem chức năng này đã được tham chiếu chưa. Nếu có, proxy sẽ trả lại cho bạn tham chiếu đó, nếu không, proxy sẽ tạo một tham chiếu và trả lại cho bạn. Vì vậy, bạn luôn có thể nhận được chức năng ban đầu của bạn, thay vì tạo ra nó nhiều lần (như sử dụng liên kết).

Vì vậy, khi bạn gọi tắt() và chuyển nó tham chiếu đến hàm kiểm tra của bạn, hàm off() sẽ xóa hàm của bạn khỏi sự kiện nhấp chuột.

Đồng thời, chức năng kiểm tra của bạn phải được khai báo trước khi sử dụng.

var test = function(){ 
     console.log('click'); 
};  

$(document).on('click', $.proxy(test, this)); 
$(document).off('click', $.proxy(test, this)); 

http://jsfiddle.net/aw50yj7f/

+0

cảm ơn, điều này dường như làm việc :) – Elfy

+0

Bạn nhận ra rằng proxy chậm như địa ngục phải không? –

+0

nhưng nó chỉ được gọi là hiển thị/ẩn – Elfy

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