2010-10-26 2 views
2

это, кажется, простой вопрос, и я надеюсь, что вы можете мне помочь. Я хотел бы добавить, что мой код работает так, как я его описываю. Я не доволен тем, как я решил проблему, связанную с моей проблемой, при увеличении [i] вне цикла for.Приращение [i] в ​​петле не работает

Что я хочу - это получить меню боковой панели, отображаемое при наведении на изображение.

Мой CSS выглядит следующим образом:


GM_addStyle 
(
'.colormenu {  \ 
display:none;  \ 
margin-left: 10px;  \ 
margin-top: -55px;  \ 
}    \ 
.colormenu a {   \ 
display: block;    \ 
width: 30px;     \ 
}       \ 
.colorlist {     \ 
list-style-type: none;   \ 
}       \ 
' 
); 

Теперь я определяю две переменные. Один из них содержит некоторые цвета, а другой - некоторые фрукты.

var color = ['red','yellow','green','blue']; 
var fruit = ['strawberry','banana','apple','blueberry']; 

я затем определить два массива:

var hoverstring = new Array(color.length); 
var idstring = new Array(color.length);

Теперь я хочу, чтобы увидеть, соответствует ли значение элемента вар цвета название изображений на Webiste. Для каждого элемента, меньшего длины цвета var, я создаю две ссылки в списке, который обертывается div и вставляет его после href, обертывающего img-элемент.

for (var i=0;i<color.length;i++) { 
$("<div id='colormenu"+i+"' class='colormenu'><ul class='colorlist'><li><a href='path"+color[i]+"'>Call</a></li><li><a href='path"+color[i]+"'>Chat</a></li></ul><div>").insertAfter("a[href$='"+fruit[i]+"']"); 


hoverstring[i]="img[title$='"+fruit[i]+"']:first"; 
idstring[i]="#colormenu"+i; 

}

Последний шаг, который я предпринимаю, и здесь у меня возникают проблемы с созданием функции для каждого элемента. Это просто пример того, как он выглядит:

$(hoverstring[0]).hover(function(){ 
     $(idstring[0]).toggle(); 
    });
$(hoverstring[1]).hover(function(){ $(idstring[1]).toggle(); });
$(hoverstring[2]).hover(function(){ $(idstring[2]).toggle(); });
$(hoverstring[3]).hover(function(){ $(idstring[3]).toggle(); });
$(hoverstring[4]).hover(function(){ $(idstring[4]).toggle(); });
$(hoverstring[5]).hover(function(){ $(idstring[5]).toggle(); });

Этот метод работает, но не очень удобен, я бы сказал. Вместо создания большого количества функций я хотел бы увеличить i и не делать это вручную.

Как:


for (var i=0;i<color.length;i++) { 
$("<div id='colormenu"+i+"' class='colormenu'><ul class='colorlist'><li><a href='path"+color[i]+"'>Call</a></li><li><a href='path"+color[i]+"'>Chat</a></li></ul><div>").insertAfter("a[href$='"+fruit[i]+"']"); 




hoverstring[i]="img[title$='"+fruit[i]+"']:first"; 
idstring[i]="#colormenu"+i; 


$(hoverstring[i]).hover(function(){ 
     $(idstring[i]).toggle(); 
    }); 
}

Я попробовал несколько раз, но по какой-то причине я не увеличивается в течение петли. У вас есть идея, почему?

Надеюсь, вы можете мне помочь. Заранее спасибо.

ответ

4

Вы можете сделать что-то быстро, как это:

$.each(color, function(i) { 
    $("<div id='colormenu"+i+"' class='colormenu'><ul class='colorlist'><li><a href='path"+this+"'>Call</a></li><li><a href='path"+this+"'>Chat</a></li></ul><div>").insertAfter("a[href$='"+fruit[i]+"']"); 
    $("img[title$='"+fruit[i]+"']:first").hover(function(){ 
    $("#colormenu"+i).toggle(); 
    }); 
}); 

Разница заключается в том, что i привязан к этому обратному вызову, не ссылаясь на ту же переменную, которая меняется с циклом каждый раз.

+1

Это просто великолепно. Потребовались бы мне дни, чтобы понять это. Спасибо. – tombolatwo

+0

@tombolatwo - welcome :) –

+0

Эй, поздравляю вас с достижением 100K! – Kobi

2

вы столкнулись с одной из самых больших ошибок, ECMA-/ Javascript программист может сделать:

Забыв о closures и hoisting of variables.

Положив это в for-loop:

$(hoverstring[i]).hover(function(){ 
    $(idstring[i]).toggle(); 
}); 

вызвал бы, что i будет closured всех ваших методов. Вам нужно вызвать другую функцию, чтобы решить эту проблему:

for (var i=0;i<color.length;i++) { 
    $("<div id='colormenu"+i+"' class='colormenu'><ul class='colorlist'><li><a  href='path"+color[i]+"'>Call</a></li><li><a  href='path"+color[i]+"'>Chat</a></li></ul><div>").insertAfter("a[href$='"+fruit[i]+"']"); 


    hoverstring[i]="img[title$='"+fruit[i]+"']:first"; 
    idstring[i]="#colormenu"+i; 

    (function(index){ 
     $(hoverstring[index]).hover(function(){ 
      $(idstring[index]).toggle(); 
     }); 
    }(i)); 
} 
+0

Что я могу сказать, чем самое большое «Спасибо», которое у меня есть. Я не программист, просто пытаюсь понять синтаксис и каждый день учиться немного больше. Спасибо, что указал на мою ошибку и все такое. – tombolatwo

1

Это увеличивающееся i просто отлично, но i внутри парения функции является ссылкой к i в петле. После того, как цикл завершен, i внутри функции наведения, внутри все функции зависания, это значение i после цикла. Это называется замыканием.

Если вы хотите, чтобы заморозить значение i в определенный момент времени вы создаете функцию, вам нужно сделать следующее:

$(hoverstring[i]).hover((function (x) { 
    return function() { 
     $(idstring[x]).toggle(); 
    } 
})(i)); 
Смежные вопросы