2008-12-04 38 views
34

Tôi đang làm việc với một chút mã html và Javascript mà tôi đã tiếp quản từ người khác. Trang tải lại một bảng dữ liệu (thông qua một yêu cầu không đồng bộ) sau mỗi mười giây và sau đó xây dựng lại bảng bằng cách sử dụng một số mã DOM. Các mã trong câu hỏi trông giống như sau:Trình xử lý sự kiện bên trong vòng lặp Javascript - cần đóng cửa?

var blah = xmlres.getElementsByTagName('blah'); 
for(var i = 0; i < blah.length; i++) { 
    var td = document.createElement('td'); 
    var select = document.createElement('select'); 
    select.setAttribute("...", "..."); 
    select.onchange = function() { 
     onStatusChanged(select, callid, anotherid); 
    }; 
    td.appendChild(select); 
} 

Khi sự kiện onchange được sa thải vì một yếu tố <select> tuy nhiên, nó có vẻ như cùng một giá trị đang được truyền cho phương thức onStatusChanged() cho mỗi <select> trong bảng (Tôi đã xác minh rằng trong mỗi lần lặp của vòng lặp, callidanotherid đang được cung cấp các giá trị mới, riêng biệt).

Tôi nghi ngờ điều này xảy ra do bản chất của cách tôi thiết lập trình xử lý sự kiện, với cú pháp select.onchange = function(). Nếu tôi hiểu cách thức này hoạt động chính xác, cú pháp này thiết lập một đóng cho sự kiện onchange là một hàm tham chiếu đến hai tham chiếu này, kết thúc có giá trị cuối cùng của bất kỳ thứ gì được đặt vào vòng lặp cuối cùng của vòng lặp. Khi sự kiện xảy ra, giá trị được tham chiếu bởi callidanotherid là giá trị được đặt trong lần lặp cuối cùng, không phải giá trị được đặt ở lần lặp riêng lẻ.

Có cách nào để tôi có thể sao chép giá trị của các tham số mà tôi đang chuyển đến onStatusChanged() không?

Tôi đã thay đổi tiêu đề để phản ánh tốt hơn câu hỏi và câu trả lời được chấp nhận.

Trả lời

49

Bạn thực sự cần thực hiện đóng cửa tại đây. Điều này nên công việc (cho tôi biết - Tôi không thử nghiệm)

var blah = xmlres.getElementsByTagName('blah'); 
for(var i = 0; i < blah.length; i++) { 
    var td = document.createElement('td'); 
    var select = document.createElement('select'); 
    select.setAttribute("...", "..."); 
    select.onchange = function(s,c,a) 
    { 
     return function() 
     { 
      onStatusChanged(s,c,a); 
     } 
    }(select, callid, anotherid); 
    td.appendChild(select); 
} 
+1

điều này thực sự hoạt động - cảm ơn! –

+0

Cũng là một giải pháp khác mà tôi phát hiện - một giải pháp, thực sự - sẽ lưu trữ callid và anotherid dưới dạng thuộc tính trong phần tử DOM, và bên trong eventhandler chỉ tham khảo thông qua this.getAttribute() –

+0

Tôi sẽ không gọi nó là giải pháp thay thế. Những gì tôi mong đợi là phải có trình xử lý được thiết lập một lần (không phải mọi lần trong vòng lặp) và làm cho nó tự khám phá các biến. – dkretz

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