2011-08-27 35 views
15

tôi nhận được một Uncaught TypeError: Illegal invocation cho cả hai phiên bản của nỗ lực này để đặt xuống một EventListener: (tôi nhận được báo lỗi khi người nghe nên được bổ sung, không phải khi tôi bấm vào mục tiêu)lỗi chưa gặp: gọi trình bất hợp pháp trên addEventListener

ronan.addEventListener("click", alert, false);

addEventListener.apply(ronan, ["click", alert, false]);

ronan là một yếu tố div được trả về thành công của giao diện điều khiển vì vậy tôi không nghĩ đó là vấn đề. Bất kỳ ý tưởng tại sao tôi nhận được lỗi này? Tôi đọc số this và tôi không thể tìm ra nó.

+0

có lẽ tôi phải đợi đến sáng để gửi –

+1

Đây có thể là 'cảnh báo' ... hàm gốc. Có một 'hàm'() {} 'trống có hoạt động đúng chỗ không? – James

+0

@ J-P không, điều đó đã không giúp được –

Trả lời

29

Bạn cần quấn alert trong một hàm. Điều này sẽ hoạt động:

ronan.addEventListener("click", function() { alert('Hi'); }, false); 

Dưới đây là fiddle để làm bằng chứng. Chỉ sử dụng alert vì không có người nghe được thực hiện giá trị this trong hàm đó được đặt thành đối tượng mà nó đang nghe. Ví dụ: nếu bạn đặt người nghe trên ronan, trong người nghe đó this === ronan. Điều này trình bày sự cố cho alert vì chức năng đó mong đợi this tương đương với window. Bạn có thể làm việc xung quanh này (không có ý định chơi chữ) bằng cách gói các chức năng trong chức năng khác hoặc bằng cách gắn nó vào bất cứ điều gì họ hy vọng this là:

document.body.addEventListener('click', alert.bind(window), false); 

Đừng quên rằng trong IE < 9 bạn cần phải sử dụng attachEvent thay vì addEventListener.


Một lưu ý về việc sử dụng apply/call với addEventListener

nỗ lực thứ hai của bạn sẽ không hoạt động bởi vì bạn đang cố gắng áp dụng đối số của bạn để window.addEventListener, như trái ngược với HTMLElement.prototype.addEventListener, mà là một khác nhau chức năng hoàn toàn:

// This won't work 
addEventListener.apply(ronan, ["click", alert.bind(window), false]); 

// This will work 
HTMLElement.prototype.addEventListener.apply(ronan, ['click', alert.bind(window), false]); 
+1

Ồ, từ, bạn nói đúng. Tôi thậm chí không sử dụng đối tượng nguyên mẫu, chỉ là cơ sở, nhưng phương pháp của bạn vẫn hoạt động mà không có phần nguyên mẫu. Tôi có lẽ nên biết về bind() vì JS của tôi tập trung vào DOM. Cảm ơn rất nhiều thời gian của bạn! –

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