2011-11-30 23 views
5

Tôi đã thực hiện mã kiểm tra này cho câu hỏi: http://jsfiddle.net/5phqm/1/Tại sao triggerHandler của jQuery() không ngăn các sự kiện nội tuyến?

Theo như tôi hiểu, nếu jQuery triggerHandler() ngăn chặn hành vi duyệt mặc định, sau đó có nguồn gốc sự kiện JavaScript sẽ không được kích hoạt và xử lý (và đó là sự thật cho addEventListener() trong tôi mã), nhưng sự kiện nội tuyến, được thêm vào thông qua thuộc tính của thẻ onclick="" sẽ được kích hoạt bất kỳ lúc nào! Tại sao nó xảy ra? Tôi có hiểu nhầm điều gì đó về các sự kiện kích hoạt trong trình duyệt không?

+0

Đối với những gì đáng giá, tôi luôn nghĩ về điều này như sau mẫu hành vi quy tắc CSS: mã nội dòng sẽ ghi đè mã được tìm thấy trong 'đầu', điều này sẽ ghi đè mã được tìm thấy trong tập lệnh bên ngoài. Bạn có thể chỉ đơn giản là 'removeAttr ('onclick')'. –

+2

Đây không phải là câu trả lời trực tiếp nhưng tại trang web của jQuery, họ tuyên bố họ không dành nhiều công sức cho các vấn đề với trình xử lý sự kiện nội tuyến: http://docs.jquery.com/Won't_Fix#Inline_Event_Handlers. Tôi muốn được quan tâm để biết tại sao mã của bạn cư xử như nó, nhưng tôi không nghĩ rằng sẽ có một sửa chữa cho nó (trong trường hợp bạn tìm thấy nó một lỗi). – pimvdb

Trả lời

2

Có thể khẳng định rằng xử lý inline được chạy bởi vì nó là explicitly coded:

handle = ontype && cur[ ontype ]; 
if (handle && jQuery.acceptData(cur) && handle.apply(cur, data) === false) { 
    event.preventDefault(); 
} 

nơi ontype là trong trường hợp này "onclick". Vì vậy, nó lấy tài sản onclick của phần tử và sau đó thực hiện nó. Mã này luôn được gọi, bất kể .trigger/.triggerHandler.

hành động

Native Tuy nhiên, giống như elem.click(), chỉ được thực hiện inside an if block:

if (!onlyHandlers && !event.isDefaultPrevented()) { 
    // ... 
    elem[ type ](); 

nơi onlyHandlerstrue cho triggerHandlefalse cho .trigger, và do đó triggerHandler không thực hiện ví dụ elem.click() (trong khi .trigger không). Như vậy, hành động gốc được ngăn chặn.

Trình xử lý nội tuyến và hành động gốc là những điều riêng biệt và cũng được xử lý riêng. Chỉ các hành động gốc được ngăn chặn bởi .triggerHandler.

0

Tôi nghĩ (nhưng nó đoán, tôi đã đưa ra một cái nhìn thoáng qua mã nguồn jQuery và điều này có thể là hoàn toàn sai) rằng jQuery lấy những sự kiện gắn liền với yếu tố trong jQuery.trigger.event bằng cách gọi một cái gì đó giống như

$(elem).data("events"); 

và sau đó quyết định xem có nên kích hoạt/dừng chúng hay không. Các sự kiện nội tuyến không thể được thu thập theo cách này và do đó chúng không thể dừng lại được.