2012-07-06 31 views
6

Tôi không chắc chắn chính xác làm thế nào để cụm từ câu hỏi của tôi, vì vậy hãy để tôi trình bày một ví dụ:Làm cách nào để thêm chức năng mẫu vào trình xử lý sự kiện trong chức năng khởi tạo?

function foo() { 
    window.addEventListener("keydown", function(event) { 
     bar(event.keycode); 
} 

foo.prototype.bar = function (keycode) { 
//code 
} 

Tôi đã cố gắng sử dụng this.bar(), nhưng mà kết quả trong việc sử dụng window như this. Có cách nào để làm điều này, hoặc tôi sẽ phải gọi một phương pháp khởi tạo thủ công?

Trả lời

7

Bind this.bar đến this trước khi bạn vượt qua.

function foo() { 
    window.addEventListener("keydown", this.bar.bind(this), false); 
} 


foo.prototype.bar = function (event) { 
    console.log(event.keyCode); 
} 

bản demo http://jsfiddle.net/2tee4/

+0

Tại sao ràng buộc? 'window.addEventListener (" keydown ", this.bar, false);'? –

+1

@SheikhHeera, để 'bar' được gọi trong ngữ cảnh' this', nếu không nó sẽ được thực thi trong phạm vi toàn cục và sẽ không có lợi thế nào khi có một hàm nguyên mẫu bị ràng buộc. – zzzzBov

+0

@SheikhHeera '.bind' sửa chữa giá trị' này' luôn giống nhau bất kể hàm bị ràng buộc được gọi như thế nào. Trong trường hợp này, nó sẽ luôn là đối tượng 'foo'. – Esailija

5

Một giải pháp thay thế nếu bạn không có Function.prototype.bind * có sẵn, và bạn không muốn thêm chức năng bổ sung để Function.prototype sẽ được đóng trên lời kêu gọi this.bar:

function foo() { 
    var self; 
    self = this; 
    window.addEventListener('keydown', function (e) { 
     self.bar(e); 
    }, false); 
} 
foo.prototype.bar = function (e) { 
    console.log(e.keyCode); 
} 

* mặc dù bạn sử dụng addEventListener mà không cần attachEvent dẫn tôi tin rằng Function.prototype.bind sẽ là một acce lựa chọn ptable


Ngoài ra, thư viện như jQuery có thể bao gồm hình thức riêng của họ về bind, jQuery là jQuery.proxy.

+0

Cảm ơn các tùy chọn bổ sung, nó luôn luôn tốt đẹp để có thêm thông tin. Thậm chí nhiều hơn, khi điều này trở thành kết quả tìm kiếm trên Google cho người khác ... – Bloodyaugust

4

Nếu ý định của bạn là thêm một người biết lắng nghe mới cho mỗi foo tạo ra, tùy chọn khác là để làm cho foo thực hiện EventListener giao diện , và chỉ cần vượt qua this ở vị trí của điều khiển.

function Foo() { 
    window.addEventListener("keydown", this, false); 
} 

Foo.prototype.bar = "foobar"; 

Foo.prototype.handleEvent = function(e) { 
    console.log(e.type); // "mousedown" (for example) 
    console.log(this.bar); // "foobar" 
}; 

new Foo(); 

Lưu ý rằng thao tác này chỉ hoạt động với addEventListener().

DEMO:http://jsfiddle.net/k93Pr/

+2

+1, nó sẽ là tuyệt vời nếu jQuery hỗ trợ điều này, sẽ loại bỏ rất nhiều '$ .proxy' boilerplate cho tôi :) – Esailija

+0

Kể từ khi nhận xét trên đã được upvoted tôi sẽ liên kết vé của tôi: http://bugs.jquery.com/ticket/12031: P – Esailija

+1

@Esailija: Nó sẽ là thú vị để xem nếu họ thực hiện nó. Tôi sẽ không chờ đợi cho jQuery mặc dù. Chỉ cần làm cho nó một plugin. Đây là một thực hiện ban đầu đơn giản và có lẽ ngây thơ. Chỉ cần thêm hỗ trợ cho các chữ ký khác của '.on()'. http://jsfiddle.net/suQEZ/ * (Tôi biết bạn không cần tôi để cho bạn thấy làm thế nào. Nó là nhiều hơn vì lợi ích của người khác.) * –

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