2012-02-02 20 views
20

Tôi đang cố gắng tìm ra cách liên kết sự kiện với các phần tử được tạo động. Tôi cần sự kiện này để tồn tại trên phần tử ngay cả sau khi nó bị phá hủy và được tái sinh.Triển khai trình kết nối "trực tiếp" của jQuery với Javascript nguyên bản

Rõ ràng với chức năng trực tiếp của jQuery dễ dàng, nhưng chúng trông như thế nào được triển khai với Javascript gốc?

+1

Bạn luôn có thể đọc nguồn jQuery: p. Bạn không chắc chắn nó sẽ đến từ JS gốc như thế nào, vì tôi chắc chắn nó sẽ phụ thuộc rất nhiều vào chính nó vào thời điểm đó (về mặt sử dụng các bộ chọn và không biết). – Corbin

+0

Chỉ một lưu ý: '.live()' không được chấp nhận trong một thời gian dài. Nó được thay thế bởi '.delegate()', được thay thế bởi '.on()', vì vậy hãy sử dụng cái cuối cùng. Hơn nữa, điều cuối cùng cho thấy sự khác biệt giữa ràng buộc và ủy quyền, vì vậy bạn có thể muốn xem xét. Điều quan trọng nhất là kiểm tra mục tiêu sự kiện. – Tadeck

+0

Câu trả lời này của tôi có thể giúp http://stackoverflow.com/a/27373951/1385441 –

Trả lời

21

Dưới đây là một ví dụ đơn giản:

function live(eventType, elementId, cb) { 
    document.addEventListener(eventType, function (event) { 
     if (event.target.id === elementId) { 
      cb.call(event.target, event); 
     } 
    }); 
} 

live("click", "test", function (event) { 
    alert(this.id); 
}); 

Ý tưởng cơ bản là bạn muốn đính kèm một event handler vào tài liệu và để cho các bong bóng sự kiện lên DOM. Sau đó, kiểm tra thuộc tính event.target để xem nó có khớp với tiêu chí mong muốn hay không (trong trường hợp này, chỉ cần id của phần tử).

Edit:

@shabunc phát hiện ra một vấn đề khá lớn với các sự kiện solution-- tôi trên yếu tố con sẽ không được phát hiện một cách chính xác. Một cách để khắc phục điều này là nhìn vào các yếu tố tổ tiên để xem nếu có có các quy định id:

function live (eventType, elementId, cb) { 
    document.addEventListener(eventType, function (event) { 
     var el = event.target 
      , found; 

     while (el && !(found = el.id === elementId)) { 
      el = el.parentElement; 
     } 

     if (found) { 
      cb.call(el, event); 
     } 
    }); 
} 
+0

Để tài liệu hoặc - hiệu quả hơn - đến vùng chứa bên ngoài mà bạn không mong đợi các yếu tố mà bạn quan tâm. – Tadeck

+0

Vì vậy, đây là lắng nghe chỉ bất kỳ sự kiện nhấp chuột và khi sự kiện nhấp chuột xảy ra, nó sẽ kiểm tra xem id của đối tượng có khớp với id đã cho hay không và thực hiện chức năng gọi lại. Khá thú vị :) – InspiredJW

+0

Phải. Và như @ Tadeck chỉ ra, bạn có thể giới hạn sự sủi bọt với một yếu tố chứa khác cho một người nghe hiệu quả hơn. –

14

Ngoài bài của Andrew và bình luận Binyamin của, có lẽ đây là một lựa chọn:

Với điều này bạn có thể sử dụng 'nav .item a' làm công cụ chọn. Dựa trên mã của Andrew.

function live (eventType, elementQuerySelector, cb) { 
    document.addEventListener(eventType, function (event) { 

     var qs = document.querySelectorAll(elementQuerySelector); 

     if (qs) { 
      var el = event.target, index = -1; 
      while (el && ((index = Array.prototype.indexOf.call(qs, el)) === -1)) { 
       el = el.parentElement; 
      } 

      if (index > -1) { 
       cb.call(el, event); 
      } 
     } 
    }); 
} 



live('click', 'nav .aap a', function(event) { console.log(event); alert('clicked'); }); 
+0

Cảm ơn rất nhiều. Một điều tôi đề nghị mặc dù là hỗ trợ 'e.preventDefault()' bên trong 'addEventListener'. Nếu được sử dụng, sau đó bạn sẽ cần phải thay đổi nó thành 'document.querySelector (elementQuerySelector) .addEventListener (eventType, function (event) {' else nó sẽ ngăn cản bạn nhấp vào bất kỳ phần tử nào khác trên trang – Lodder

0

Cách thay thế để gắn kết sự kiện với yếu tố cụ thể có thể là trình xử lý sự kiện toàn cầu. Vì vậy, mỗi khi bạn cập nhật DOM với một sự kiện phần tử mới trên phần tử đó cũng sẽ là "bắt". Một ví dụ:

var mybuttonlist = document.getElementById('mybuttonlist'); 
 

 
mybuttonlist.addEventListener('click', e=>{ 
 
    if(e.target.nodeName == 'BUTTON'){ 
 
    switch(e.target.name){ 
 
     case 'createnewbutton': 
 
     mybuttonlist.innerHTML += '<li><button name="createnewbutton">Create new button</button></li>'; 
 
     break; 
 
    } 
 
    } 
 
}, false);
ul { 
 
    list-style: none; 
 
    padding: 0; 
 
    margin: 0; 
 
}
<ul id="mybuttonlist"> 
 
    <li><button name="createnewbutton">Create new button</button></li> 
 
</ul>

Trong ví dụ này, tôi có một người biết lắng nghe sự kiện trên <ul> cho các sự kiện nhấp chuột. Vì vậy, một sự kiện xảy ra cho tất cả các phần tử con. Từ trình xử lý sự kiện đơn giản mà tôi đã tạo, bạn có thể thấy rằng việc thêm nhiều logic hơn, nhiều nút hơn (với các tên khác nhau hoặc lặp lại), các neo, v.v.

Đi vào, bạn có thể thêm trình xử lý sự kiện vào tài liệu thay vì phần tử danh sách, bắt tất cả các sự kiện nhấp chuột trên trang và sau đó xử lý các sự kiện nhấp chuột trong trình xử lý sự kiện.

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