16

Mục tiêuLàm cách nào để chuyển một biến theo giá trị sang một hàm javascript ẩn danh?

Tôi muốn chỉ định động việc xử lý sự kiện cho một số div trên các trang trong toàn bộ trang web.

Phương My

Im sử dụng jQuery để ràng buộc chức năng ẩn danh như xử lý cho các sự kiện div chọn.

Vấn đề

Mã lặp một loạt các tên div và url liên quan. Tên div được sử dụng để đặt mục tiêu ràng buộc tức là đính kèm trình xử lý sự kiện này vào sự kiện div này.

Trong khi trình xử lý sự kiện được liên kết thành công với từng sự kiện div, các hành động được kích hoạt bởi các trình xử lý sự kiện đó chỉ bao giờ nhắm mục tiêu mục cuối cùng trong mảng.

Vì vậy, ý tưởng là nếu người dùng di chuột qua một div nhất định, nó sẽ chạy một hoạt ảnh trượt ra cho div đó. Nhưng thay vào đó, di chuột qua div1 (rangeTabAll) sẽ kích hoạt một slide-out animation cho div4 (rangeTabThm). Điều này cũng đúng cho divs 2, 3, etc. Thứ tự là không quan trọng. Thay đổi các phần tử mảng xung quanh và các sự kiện sẽ luôn luôn nhắm mục tiêu phần tử cuối cùng trong mảng, div4.

Mã My - (Sử dụng jQuery)

var curTab, curDiv; 
var inlineRangeNavUrls=[['rangeTabAll','range_all.html'],['rangeTabRem','range_remedial.html'], 
       ['rangeTabGym','range_gym.html'],['rangeTabThm','range_thermal.html']]; 
     for (var i=0;i<inlineRangeNavUrls.length;i++) 
     { 
      curTab=(inlineRangeNavUrls[i][0]).toString(); 
      curDiv='#' + curTab; 
      if ($(curDiv).length) 
      { 
       $(curDiv).bind("mouseover", function(){showHideRangeSlidingTabs(curTab, true);}); 
       $(curDiv).bind("mouseout", function(){showHideRangeSlidingTabs(curTab, false);}); 
      } 
     } 

Lý thuyết của tôi

tôi hoặc không nhìn thấy một lỗi cú pháp blindingly rõ ràng hoặc một đường chuyền của nó bởi sự cố tài liệu tham khảo. Ban đầu tôi đã có báo cáo kết quả sau đây để thiết lập giá trị của curTab:

curTab=inlineRangeNavUrls[i][0]; 

Vì vậy, khi vấn đề xảy ra tôi đã tìm thấy như tôi đã thay đổi (thông qua cho vòng lặp) tham chiếu đến curTab, tôi đã được trên thực tế thay đổi tham chiếu cho tất cả các trình xử lý sự kiện hàm ẩn danh trước đó với giá trị curTab mới .... đó là lý do tại sao trình xử lý sự kiện luôn nhắm mục tiêu đến div cuối cùng. Vì vậy, những gì tôi thực sự cần làm là vượt qua giá trị curTab cho trình xử lý sự kiện chức năng ẩn danh không phải là tham chiếu curTab đối tượng.

Vì vậy, tôi nghĩ:

curTab=(inlineRangeNavUrls[i][0]).toString(); 

sẽ khắc phục vấn đề, nhưng nó không. Cùng một thỏa thuận. Vì vậy, rõ ràng im thiếu một số chìa khóa, và có lẽ rất cơ bản, kiến ​​thức về vấn đề này. Cảm ơn.

+0

JavaScript luôn chuyển và gán theo giá trị. Câu hỏi của bạn không đối phó với việc đi qua chút nào; mà đúng hơn là với việc nắm bắt các biến bằng cách đóng. – newacct

Trả lời

20

Bạn cần phải tạo một biến mới trên mỗi đi qua vòng lặp, do đó nó sẽ bị bắt giữ trong các đóng mà bạn đang tạo cho trình xử lý sự kiện.

Tuy nhiên, chỉ việc di chuyển biến khai báo vào vòng lặp sẽ không thực hiện được điều này, bởi vì JavaScript doesn't introduce a new scope for arbitrary blocks.

Một cách dễ dàng để buộc sự ra đời của một phạm vi mới là sử dụng một chức năng ẩn danh:

for (var i=0;i<inlineRangeNavUrls.length;i++) 
{ 
    curDiv='#' + inlineRangeNavUrls[i][1]; 
    if ($(curDiv).length) 
    { 
    (function(curTab) 
    { 
     $(curDiv).bind("mouseover", function(){showHideRangeSlidingTabs(curTab, true);}); 
     $(curDiv).bind("mouseout", function(){showHideRangeSlidingTabs(curTab, false);}); 
    })(inlineRangeNavUrls[i][0]); // pass as argument to anonymous function - this will introduce a new scope 
    } 
} 

As Jason suggests, bạn thực sự có thể làm sạch này lên khá một chút sử dụng jQuery tích hợp trong hover() chức năng:

for (var i=0;i<inlineRangeNavUrls.length;i++) 
{ 
    (function(curTab) // introduce a new scope 
    { 
    $('#' + inlineRangeNavUrls[i][1]) 
    .hover(
     function(){showHideRangeSlidingTabs(curTab, true);}, 
     function(){showHideRangeSlidingTabs(curTab, false);} 
    ); 
    // establish per-loop variable by passsing as argument to anonymous function 
    })(inlineRangeNavUrls[i][0]); 
} 
+0

Công cụ tuyệt vời, cảm ơn. – rism

1

Tôi nghĩ bạn đang làm điều này phức tạp hơn mức cần thiết. Nếu tất cả những gì bạn đang làm là gán hiệu ứng trượt khi di chuột qua/ra thì hãy thử hiệu ứng hover với jquery.

$("#mytab").hover(function(){ 
    $(this).next("div").slideDown("fast");}, 
    function(){ 
    $(this).next("div").slideUp("fast"); 
}); 

Nếu bạn đăng HTML đầy đủ của bạn tôi có thể cho bạn biết chính xác làm thế nào để làm điều đó :)

+2

đúng, nhưng đó không phải là nguyên nhân gây ra sự cố. –

+0

... vì vậy tôi nhận được một downvote? để cung cấp câu trả lời đơn giản, rõ ràng hơn cho vấn đề của OP? có thật không? – Jason

+0

Câu trả lời của bạn không giải quyết được vấn đề của OP. – Breton

15

những gì đang xảy ra ở đây là các hàm không đồng nhất của bạn đang tạo thành một bao đóng và lấy phạm vi bên ngoài của chúng với chúng. Điều đó có nghĩa là khi bạn tham chiếu curTab bên trong hàm bất thường của bạn, khi trình xử lý sự kiện chạy hàm đó, nó sẽ tra cứu giá trị hiện tại của curTab trong phạm vi bên ngoài của bạn. Đó sẽ là bất cứ điều gì bạn mới chỉ định cho curTab. (Không phải những gì đã được giao tại thời điểm bạn binded chức năng)

những gì bạn cần làm là thay đổi này:

$(curDiv).bind("mouseover", function(){showHideRangeSlidingTabs(curTab, true);}); 

này:

$(curDiv).bind("mouseover", 
    (function (mylocalvariable) { 
     return function(){ 
      showHideRangeSlidingTabs(mylocalvariable, true); 
     } 
    })(curTab) 
); 

này sẽ sao chép các giá trị của curTab vào phạm vi của hàm ngoài, hàm bên trong sẽ mang theo nó. Việc sao chép này xảy ra cùng lúc với việc bạn ràng buộc hàm bên trong với trình xử lý sự kiện, do đó, "mylocalvariable" phản ánh giá trị của curTab tại thời điểm đó. Sau đó, lần tiếp theo vòng lặp, một hàm ngoài mới, với một phạm vi mới sẽ được tạo và giá trị tiếp theo của curTab được sao chép vào nó.

Câu trả lời của shog9 hoàn thành về cơ bản cùng một điều, nhưng mã của anh ấy hơi khắc khổ hơn một chút.

nó khá phức tạp, nhưng có ý nghĩa nếu bạn nghĩ về nó. Đóng cửa là lạ.

chỉnh sửa: oops, quên trả về hàm bên trong. Đã sửa.

+0

Cảm ơn một bó, bit của một đồng xu quăng cho câu trả lời được chấp nhận. – rism

1

Bạn có thể đặt giá trị của biến vào thẻ không tồn tại và sau đó bạn có thể đọc chúng từ đó. Đoạn mã này là một phần của nội dung vòng lặp:

s = introduction.introductions[page * 6 + i][0]; //The variables content 
$('#intro_img_'+i).attr('tag' , s);    //Store them in a tag named tag 
$('#intro_img_'+i).click(function() {introduction.selectTemplate(this, $(this).attr('tag'));} ); //retrieve the stored data 
+0

để tương thích với HTML5, bạn có thể thêm 'data-' trước 'tag' để tạo' data-tag', sau đó bạn có thể sử dụng phương thức ['data'] của jQuery (http://api.jquery.com/data/). – Brombomb

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