2012-06-08 59 views
11

Làm cách nào để duy trì quyền truy cập vào biến số i bên trong vòng lặp của tôi bên dưới? Tôi đang cố gắng để tìm hiểu, không chỉ nhận được câu trả lời, do đó, một chút giải thích sẽ rất hữu ích. Cảm ơn bạn!Phạm vi biến Javascript bên trong cho vòng lặp

var el, 
    len = statesPolyStrings.length; 

for (var i = 0; i < len; i++) { 
    el = document.getElementById(statesPolyStrings[i]); 

    google.maps.event.addDomListener(el, 'mouseover', function() { 
     $("#"+statesPolyStrings[i]).addClass("highlight"); 
     statesPolyObjects[i].setOptions({ strokeWeight: '2' }); 
    }); 
} 
+1

Bạn muốn truy cập vào 'i' bên ngoài vòng lặp for? Bạn đã có quyền truy cập vào 'i' bên trong vòng lặp for. –

+0

Tôi muốn truy cập nó trong hàm addDomListener trong vòng lặp for. Bất cứ nơi nào bạn nhìn thấy một i trong đoạn mã trên tôi muốn sử dụng i như được định nghĩa và tăng lên trong vòng lặp for. –

+1

có thể trùng lặp của [Javascript đóng bên trong vòng - ví dụ đơn giản thực tế] (http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) –

Trả lời

28

Tất cả các cuộc gọi lại của bạn chia sẻ cùng một biến số i.
Khi trình xử lý sự kiện thực sự chạy, i là sau khi kết thúc mảng.

Bạn cần phải quấn thân vòng lặp trong một chức năng tự gọi mất i làm tham số.
Bằng cách này, mỗi lần lặp sẽ có biến số riêng, không thay đổi, i.

Ví dụ:

for (var i = 0; i < statesPolyStrings.length; i++) { 
    (function(i) { 
     ... 
    })(i); 
} 
+0

Bạn có thể cung cấp một ví dụ bằng cách sửa đổi của tôi mã? Tôi không chắc ý bạn là gì. –

+0

OK và bây giờ đã hiểu. Cảm ơn bạn. –

1
for (var i = 0; i < statesPolyStrings.length; i++) { 
    (function(i){ 
     google.maps.event.addDomListener(document.getElementById(statesPolyStrings[i]), 'mouseover', function() { 
     $("#"+statesPolyStrings[i]).addClass("highlight"); 
     statesPolyObjects[i].setOptions({ strokeWeight: '2' }); 
     }); 
    })(i) 
} 
2

Thách thức đối với chức năng tự gọi hoạt động tốt: nó tạo ra một phạm vi mới (có thể google cho 'phạm vi chức năng javascript') và do đó xử lý i như một khác nhau biến và cung cấp giá trị phù hợp cho chức năng gọi lại của trình nghe sự kiện của bạn.

Nhưng bạn thực sự không cần phải tìm nguyên tố của bạn lại với jQuery như bạn đã phân công một event listener với nó và bên trong chức năng của bạn, bạn có một tham chiếu đến phần tử của bạn với this.

Và như bạn đang sử dụng jQuery dù sao đi nữa, đó là sau đó dễ dàng để tìm thấy những chỉ số chính xác (bạn i) của statesPolyObjects với $.inArray() qua id của nguyên tố của bạn và statesPolyStrings mảng (giả sử bạn đang làm việc với ID duy nhất. Nếu không, $("#"+statesPolyStrings[i]) cũng sẽ không thành công, vì nó sẽ phát hiện lần đầu tiên).

var el; 

for (var i = 0, len = statesPolyStrings.length; i < len; i++) { 
    el = document.getElementById(statesPolyStrings[i]); 

    google.maps.event.addDomListener(el, 'mouseover', function(event) { 
     $(this).addClass("highlight"); 
     statesPolyObjects[$.inArray(this.id, statesPolyStrings)]. 
      setOptions({ strokeWeight: '2' }); 
    }); 
} 

Nếu bạn vẫn muốn gắn bó với chức năng tự thực thi bạn dù sao đi nữa nên thay đổi dòng sau:

("#"+statesPolyStrings[i]).addClass("highlight"); 

để

$(this).addClass("highlight"); 

Nếu bạn không đủ với quen thuộc this và các sự kiện bạn có thể muốn đọc bài viết này: http://www.sitepoint.com/javascript-this-event-handlers/

Bạn có thể nhận thấy rằng tôi cũng đã viết đối số event bên trong hàm gọi lại ẩn danh. Hãy thử để console.log sự kiện này bạn được phân phối miễn phí với bất kỳ chức năng gọi lại của người nghe sự kiện nào và khám phá tất cả những thứ khác mà bạn có quyền truy cập. Ví dụ: bạn có thể tìm thấy phần tử thực tế mà bạn đã nhấp vào với event.target (vì di chuột thực tế có thể đã xảy ra với con của phần tử của bạn). Vì vậy:

google.maps.event.addDomListener(el, 'mouseover', function(event) { 
    console.log(event); 
    ... 

và mở bảng điều khiển trình duyệt của bạn để xem sự kiện nào mang lại ...

Hãy lưu ý rằng mặc dù google.maps.event.addDomListener chuyển một số thứ khác nhau sau đó document.body.addEventListener và cũng có sự khác biệt giữa các trình duyệt. Ví dụ jQuery.on() cũng cung cấp một số thứ khác nhau trong đối tượng sự kiện, nhưng ở đó bạn có thể đếm ít nhất trên cùng một dữ liệu trong tất cả các trình duyệt.

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