2012-05-07 32 views
5

Tôi đang viết một kịch bản mà tôi muốn xử lý các sự kiện chuột chỉ khi chúng chưa được xử lý bởi bất kỳ phần tử nào khác trước đây.Xử lý các sự kiện Javascript không được xử lý bởi các thành phần khác

Tôi có thể đính kèm trình xử lý sự kiện vào đối tượng tài liệu, nhưng nó sẽ nhận tất cả các sự kiện bất kể chúng có được xử lý hay không.

Tôi không kiểm soát được các thành phần trong trang HTML vì vậy tôi không thể dừngPropagation thủ công() khi sự kiện được xử lý.

Bất kỳ ý tưởng nào?

+1

Các sự kiện nhấp mà bạn không kiểm soát bị ràng buộc như thế nào? –

+0

Tôi thực sự không thể biết, vì đây là một phần của thư viện có thể được sử dụng với các loại trang khác nhau. Có thể là addEventListener hoặc onXXX. – Grodriguez

+1

Vâng, 'addEventListener' làm cho nó khó hơn. Đối với các kiểu [event], bạn có thể có nó để handler của bạn liên kết với tài liệu bắt đầu với 'e.target', và kiểm tra nó và tổ tiên của nó để xem cái nào có handler, sau đó bọc nó với một hàm gọi 'stopPropagation'. Nhưng 'addEventListener' sẽ không cho phép bạn làm điều đó. –

Trả lời

1

Từ bài viết này here.

Có vẻ như chưa thể thực hiện điều này.

Trình xử lý sự kiện nào được đăng ký?

Một vấn đề về việc triển khai đăng ký sự kiện hiện tại của W3C là mô hình là bạn không thể tìm hiểu xem có bất kỳ trình xử lý sự kiện nào đã được đăng ký một thành phần hay không. Trong mô hình truyền thống bạn có thể làm:

alert(element.onclick)

và bạn thấy chức năng đó là đăng ký nó, hoặc không xác định nếu không có gì được đăng ký. Chỉ trong rất gần đây DOM Cấp của 3 sự kiện W3C thêm một

eventListenerList

để lưu trữ một danh sách các sự kiện xử lý hiện đang đăng ký trên một phần tử. Chức năng này chưa được bất kỳ trình duyệt nào hỗ trợ, quá mới. Tuy nhiên, vấn đề đã được giải quyết.

May mắn thay

removeEventListener() 

không đưa ra bất cứ lỗi nếu sự kiện nghe bạn muốn xóa vẫn chưa được thêm vào nguyên tố này, vì vậy khi nghi ngờ bạn luôn có thể sử dụng removeEventListener ().

+0

OK .. (mặc dù tôi không thực sự cần một danh sách người nghe). Hãy xem nếu tôi có thể tìm thấy một số cách khác. – Grodriguez

1

Vì vậy, bạn có thể thực hiện điều gì đó giống như bạn muốn trong một số trường hợp nhất định. Cụ thể, nếu

  • Bạn có thể tải riêng của bạn JavaScript trước bản gốc
  • Bạn biết yếu tố nào bạn đang lắng nghe người khác để ném các sự kiện trên

có hiệu quả, những gì bạn làm là thay thế bản gốc phương thức addEventListener trên phần tử target với một phần tử tùy chỉnh chặn cuộc gọi, thực hiện một số xử lý đặc biệt, và sau đó cho phép nó tiếp tục bình thường. 'Xử lý đặc biệt' này là một hàm mới kết thúc cuộc gọi lại ban đầu và đánh dấu các đối số sự kiện với một số trạng thái để cho bạn biết người khác đã trao đổi sự kiện này. Đây là một bằng chứng của khái niệm (với một jsFiddle)

Target HTML:

<div id='asdf'>asdf</div>​ 

JavaScript:

var target = document.getElementById('asdf'); 
var original = target.addEventListener; 

var updated = function(){ 
    // Grab the original callback, so we can use it in our wrapper 
    var originalFunc = arguments[1]; 

    // Create new function for the callback, that lets us set a state letting us know it has been handled by someone 
    // Finish the callback by executing the original callback 
    var newFunc = function(e){ 
     console.log('haha, intercepted you'); 
     e.intercepted = true; 
     originalFunc.call(this, e); 
    }; 

    // Set the new function in place in the original arguments 'array' 
    arguments[1] = newFunc; 

    // Perform the standard addEventListener logic with our new wrapper function 
    original.apply(this, arguments); 
}; 

// Set the addEventListener on our target to our modified version 
target.addEventListener = updated; 

// Standard event handling 
target.addEventListener('click', function(e){ 
    console.log('original click'); 
    console.log('intercepted?', e.intercepted); 
}) 
+0

Đây là một ý tưởng thú vị. Tôi có thể đảm bảo rằng JS của tôi sẽ chạy trước bản gốc. Tuy nhiên tôi không có cách nào để biết những yếu tố nào sẽ thêm một người nghe sự kiện. Có cách nào để làm điều này nhưng theo một cách toàn cầu? (tức là thay thế toàn bộ mã addEventListener bằng phiên bản đã sửa đổi) – Grodriguez

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