2012-12-17 12 views
9

Tôi đã đấu tranh với điều này trong một vài giờ đồng hồ.Thêm người nghe sự kiện vào nhiều yếu tố

Tôi muốn nghe thêm một sự kiện cho tất cả các <select> s trên một trang và tôi đã có đoạn mã này cho đến nay:

onload = function(e) { 
    sels = document.getElementsByTagName('select'); 
    for(i=0; i<sels.length; i++) { 
     sels[i].addEventListener('change', alert('test!'), false); 
    } 
} 

này chỉ kích hoạt thông báo khi trang web được tải và không phải khi Tôi thay đổi giá trị trong bất kỳ số nào trong số <select> s của mình.

Tôi có thể hướng dẫn đúng hướng không? :-)

Trả lời

9

Bạn cần có có chức năng ẩn danh cho rằng khi bạn gọi alert() chức năng ngay trong ví dụ của bạn:

... .addEventListener('change', function() { alert('test!')}, false ... 

Còn bây giờ theo mã của bạn addEventListener cố gắng để thêm kết quả của undefined (trở lại của alert() chức năng).

Hoặc bạn chỉ có thể vượt qua chức năng xử lý cho rằng:

function alertMe() { 
    alert('test!'); 
} 
... 

... .addEventListener('change', alertMe, false ... 

Lưu ý: đó bằng cách làm cho somefunction(arg[, arg...]) gọi cho bạn tham khảo không thực hiện chức năng, nhưng để trở về chức năng gì.

+1

Oh. Tôi đã tích cực tôi đã cố gắng đó, nhưng dường như không. Cảm ơn bạn! Chỉnh sửa: Tôi hiểu. Bây giờ bạn đề cập đến nó nó có ý nghĩa với tôi. –

+0

@Perplexor Bạn có chắc chắn không? Tôi không thấy lỗi khác trong mã của bạn. – antyrat

+0

Tất nhiên tôi đã thử nó trong một số trường hợp khác, đó là lý do tại sao nó không hoạt động tại thời điểm đó. Nhưng bây giờ nó hoạt động với giải pháp của bạn! –

0

Bạn đang thực hiện các cảnh báo() chức năng ngay lập tức, bạn cần phải vượt qua chức năng addEventListener một hàm thay vào đó, như vậy:

onload = function(e) { 
    sels = document.getElementsByTagName('select'); 
    for(i=0; i<sels.length; i++) { 
     document.getElementsByTagName('select')[i].addEventListener('change', function() { alert('test!'); }, false); 
    } 
} 
5

Bên cạnh gói các alert trong một chức năng, như đã đề cập trước, không sử dụng getElementsByTagName cho mỗi lần lặp của vòng lặp:

onload = function(e) { 
    sels = document.getElementsByTagName('select'); 
    for(i=0; i<sels.length; i++) { 
     sels[i].addEventListener('change', function(){alert('test!')}, false); 
    } 
} 

Bạn có danh sách các yếu tố select lưu vào một biến, nó không cần thiết, chưa kể đến hiệu quả để get tất cả những các phần tử, mỗi vòng lặp lặp lại.

+0

Điểm tốt! Tôi thực sự chỉ sử dụng "thử và sai" để có được kết quả mà tôi muốn. Đó là lý do tại sao tôi đã làm như thế. Cảm ơn bạn! –

+0

Không có vấn đề gì, "Thử và Lỗi", theo ý kiến ​​của tôi, cách duy nhất để thực sự học lập trình, vì vậy tốt công việc: P – Cerbrus

+0

Câu trả lời hữu ích, Bạn có biết cách nào nhanh hơn không? Ý tôi là getElementByTagName có thể hơi chậm – M98

1

Tôi đã tạo hàm đơn giản sau, lặp lại trên tất cả các phần tử khớp với selector và thêm trình xử lý sự kiện cho event với số handler được chuyển.

Đây là chức năng tương tự cho jQuery $(selector).on(event, handler)

function addEventListeners(selector, event, handler, useCapture){ 

    useCapture = useCapture || false; 

    Array.prototype.forEach.call(
     document.querySelectorAll(selector) 
     ,function(el, ix) { 
      el.addEventListener(event, handler, useCapture); 
     } 
    ); 
} 

Vì vậy, cho OP cách sử dụng chức năng này sẽ là như vậy:

addEventListeners("select", "change", function(evt){ console.log(evt); }); 

Xem thêm câu trả lời của tôi cho Event listener for current and future elements

0

Sự kiện Bubbling là khái niệm quan trọng trong javascript, vì vậy nếu bạn có thể thêm sự kiện trên DOM trực tiếp, bạn có thể lưu một số dòng mã:

document.addEventListener('change', function(e){ 
    if(e.target.tagName=="SELECT"){ 
    alert('SELECT CHANGED'); 
    } 
})