Циклы JavaScript

#javascript #jquery #css

#javascript #jquery #css

Вопрос:

У меня есть следующий код, который я хочу уменьшить.

     $('#1').hover(function() { $('#hiddenMenu1').css('display', 'block'); },
            function() { $('#hiddenMenu1').css('display', 'none'); });
    $('#2').hover(function() { $('#hiddenMenu2').css('display', 'block'); },
            function() { $('#hiddenMenu2').css('display', 'none'); });
    $('#3').hover(function() { $('#hiddenMenu3').css('display', 'block'); },
            function() { $('#hiddenMenu3').css('display', 'none'); });
    $('#4').hover(function() { $('#hiddenMenu4').css('display', 'block'); },
            function() { $('#hiddenMenu4').css('display', 'none'); });
    $('#5').hover(function() { $('#hiddenMenu5').css('display', 'block'); },
            function() { $('#hiddenMenu5').css('display', 'none'); });
    $('#6').hover(function() { $('#hiddenMenu6').css('display', 'block'); },
            function() { $('#hiddenMenu6').css('display', 'none'); });
    $('#7').hover(function() { $('#hiddenMenu7').css('display', 'block'); },
            function() { $('#hiddenMenu7').css('display', 'none'); });
    $('#8').hover(function() { $('#hiddenMenu8').css('display', 'block'); },
            function() { $('#hiddenMenu8').css('display', 'none'); });
    $('#9').hover(function() { $('#hiddenMenu9').css('display', 'block'); },
            function() { $('#hiddenMenu9').css('display', 'none'); });
    $('#10').hover(function() { $('#hiddenMenu10').css('display', 'block'); },
            function() { $('#hiddenMenu10').css('display', 'none'); });
  

Я пробовал это, но это не работает. РЕДАКТИРОВАТЬ: это не ошибка, просто ничего не происходит.

     for (i = 1; i <= 10; i  ) {
        var id = '#'   i.toString();
        var menu = '#hiddenMenu'   i.toString();
        $(id).hover(function() { $(menu).css('display', 'block'); },
                function() { $(menu).css('display', 'none'); });
    }
  

Заранее спасибо

РЕДАКТИРОВАТЬ: HTML

 <div id="ctl00_divMenu" class="dynamicMenu">
    <ul class="siteNav">
        <li id="1"></li>
        <li id="2"></li>
        <li id="3"></li>
        <li id="4"></li>
        <li id="5"></li>
        <li id="6"></li>
        <li id="7"></li>
        <li id="8"></li>
        <li id="9"></li>
        <li id="10"></li>
    </ul>
    <div id="hiddenMenu1" class="hiddenMenu">
        <div class="list">...</div>
    </div>
    <div id="hiddenMenu2" class="hiddenMenu">
        <div class="list">...</div>
    </div>
    <div id="hiddenMenu3" class="hiddenMenu">
        <div class="list">...</div>
    </div>
    ...
    <div id="hiddenMenu10" class="hiddenMenu">...</div>
</div>
  

Комментарии:

1. можете ли вы привести пример html # 1, # 2 … ?

2. @lappy Являются #1, #2, #3, … элементы родственные? Если это так, вы могли бы использовать делегирование событий.

3. @lappy Кроме того, являются ли скрытые меню братьями и сестрами?

4. Лично я бы не стал заморачиваться с циклом, просто оставьте все как есть. Я не вижу в этом преимущества.

5. @chrislegend Избыточный код отнимает 5 лет вашей жизни… :)

Ответ №1:

Я бы дал им общий класс, а затем связал их все сразу.

 $('.commonClass').hover(function(e) {
   $('#hiddenMenu'   this.id).toggle(e.type === 'mouseenter');
}):
  

Если бы я знал структуру HTML, то ее можно было бы оптимизировать дальше (делегирование событий, преобразование и т.д.)

РЕДАКТИРОВАТЬ: Новый код (с использованием делегирования событий), поскольку вы предоставили нам структуру HTML —

 $('.siteNav').delegate('mouseenter mouseleave', 'li', function(e) {
  $('#hiddenMenu'   this.id).toggle(e.type === 'mouseenter');
});
  

Комментарии:

1. Я бы сделал это: .toggle(e.type === 'mouseenter') , чтобы убедиться, что поведение случайно не переключается ( mouseenter = скрыть, mouseleave = показать ), что может произойти, если вы быстро перемещаете курсор мыши (без каламбура).

2. @Sime отличная идея, я добавил это в — решение просто стало в 10 раз лучше

Ответ №2:

Ваш код не работает, потому что вы создали замыкания в цикле for ( hover функции выполняются позже, и когда это происходит, они обращаются к i переменной внешней функции, которая всегда равна 10 (выполнение цикла завершено)).

больше объяснений здесь:http://jibbering.com/faq/notes/closures /

Что вы можете сделать, так это поместить значение i внутрь другой функции, которая будет вызывать hover :

 for (i = 1; i <= 10; i  ) {
    (function(num) {
        var id = '#'   num;
        var menu = '#hiddenMenu'   num;
        $(id).hover(function() {
            $(menu).css('display', 'block');
        }, function() {
            $(menu).css('display', 'none');
        })
    })(i.toString());
}
  

Вы также можете просто сделать это:

 $('#1,#2,#3,#4,#5,#6,#7,#8,#9,#10').hover(function() { 
    $('#hiddenMenu' $(this).attr('id')).css('display', 'block');
},function() { 
    $('#hiddenMenu' $(this).attr('id')).css('display', 'none'); 
});
  

или (после вашего обновления):

 $('ul.siteNav li').hover(function() { 
        $('#hiddenMenu' $(this).attr('id')).css('display', 'block');
    },function() { 
        $('#hiddenMenu' $(this).attr('id')).css('display', 'none'); 
    });
  

Ответ №3:

Что-то вроде этого должно сработать.

 $('#1, #2, #3, #4, #5, #6, #7, #8, #9, #10').hover(
    function() { 
        $('#hiddenMenu'   this.id).show(); 
    },
    function() { 
        $('#hiddenMenu'   this.id).hide(); 
    }
);