2011-12-26 26 views
5

Tôi có vòng lặp for chạy trong javascript. Trong vòng lặp này, tôi đang tạo một mục danh sách và ràng buộc một sự kiện bấm vào nó. Khi tôi bấm vào mục danh sách này, tôi muốn nó gọi một hàm với dữ liệu từ đối tượng vòng lặp hiện tại làm tham số.Vòng lặp Javascript với sự kiện nhấp được ràng buộc luôn trả lại kết quả cuối cùng

Vấn đề là, bất kể mục danh sách tôi nhấp vào là gì. Dữ liệu đang được truyền dưới dạng tham số là phần tử cuối cùng của đối tượng mà tôi đang lặp thay vì dữ liệu hiện tại đang được nhấp.

for(e in data) { 

    var suggestItem = $('<li>'+ data[e]['name'] +'</li>'); 

    suggestItem.click(function() { 
     $(this).addClass('activeSuggestion'); 
     suggestSelect(suggestField, data[e]);  
    }); 

    suggestList.append(suggestItem); 

} 

Tôi nghĩ rằng tôi hiểu tại sao điều này xảy ra nhưng không chắc chắn cách xử lý.

+1

bản sao có thể có của [Trình xử lý sự kiện jQuery được tạo trong vòng lặp] (http://stackoverflow.com/questions/7774636/jquery-event-handler-created-in-loop) – Pointy

Trả lời

3

Bạn cần phải ngắt đóng cửa trên e.

Vì bạn đang sử dụng jQuery, cách dễ nhất là lưu giá trị hiện tại của e bằng chức năng data của jQuery. Vì tất cả các tham số hàm trong JavaScript được truyền theo giá trị, điều này có hiệu quả phá vỡ sự đóng cửa; bây giờ trình xử lý nhấp chuột của bạn sẽ hoạt động với giá trị của e là khi trình xử lý được tạo và không phải giá trị e giữ khi kết thúc vòng lặp.

for(e in data) { 

    var suggestItem = $('<li>'+ data[e]['name'] +'</li>'); 

    suggestItem.data('savedE', e).click(function() { 
     $(this).addClass('activeSuggestion'); 
     suggestSelect(suggestField, data[$(this).data('savedE')]); 
    }); 

    suggestList.append(suggestItem); 

} 
+0

Điều đó đã xảy ra. Cảm ơn –

+0

@JustinCarlson - niềm vui của tôi - chúc may mắn! –

5

Đây là câu hỏi đóng Javascript cổ điển. Khi sự kiện nhấp được kích hoạt (khi bạn nhấp vào một cái gì đó), vòng lặp đã kết thúc thực hiện. Giá trị của e là bất kỳ phím cuối cùng nào trong số data là. Giải pháp cho vấn đề là tạo ra một phạm vi mới bên trong vòng lặp của bạn.

for(var e in data) { 
    (function(datum) { 
     suggestList.append(
      $('<li>' + datum.name + '</li>') 
      .click(function() { 
       $(this).addClass('activeSuggestion'); 
       suggestSelect(suggestField, datum);  
      }); 
     ); 
    })(data[e]); 
} 

Javascript là chức năng bị xáo trộn, vì vậy bất cứ khi nào có chức năng mới, phạm vi mới được tạo. Đoạn mã trên "bẫy" giá trị của data[e] thành datum vì nó chuyển nó thành tham số cho hàm. Một cách khác để mã hóa nó mà có thể ít gây nhầm lẫn:

for(var e in data) { 
    (function() { 
     var datum = data[e]; 
     suggestList.append(
      $('<li>' + datum.name + '</li>') 
      .click(function() { 
       $(this).addClass('activeSuggestion'); 
       suggestSelect(suggestField, datum);  
      }); 
     ); 
    })(); 
} 

Nó không vượt qua trong một tham số cho hàm, nhưng vì Javascript là chức năng scoped, mỗi lần sự kiện click được kích hoạt nó sẽ tìm kiếm nơi datum Đã được chuyển nhượng.

Cũng xin lưu ý rằng for(VAR e in data) sẽ dừng e để trở thành biến toàn cầu.

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