Меню на jquery (помогите)

Привет, помогите кто может, а то голову сломал. может решение и на поверхности
короче есть меню с сабменю выглядит так
Курск
мы находимся в текущем разделе (.current)
при наведении на другие пункты показываю их подразделы.
Задача: сделать так что если при наведении на разделы в которых нет вложенного меню или вне меню у нас возвращалось сабменю пункта .current
HTML

<nav class="main_nav" id="mainmenu">
          <ul>
            <li><a href="#">Projects</a>
             <ul>
                <li><a href="#filter=*">Show All</a></li>
                <li><a href="#filter=.item1">Featured Projects</a></li>
                <li><a href="#filter=.item2">Learning Environments</a></li>
                <li><a href="#filter=.item3">Dining and Recreation</a></li>
                <li><a href="#filter=.item4">Campus Centers</a></li>
                <li><a href="#filter=.item5">Visual and Performing Arts</a></li>
                <li><a href="#filter=.item6">Heathcare and Research</a></li>
                <li><a href="#filter=.item7">Housing</a></li>
                <li><a href="#filter=.item8">Administration and Mixed Use</a></li>
                <li><a href="#filter=.item9">Planning and Programming</a></li>
                <li><a href="#filter=.item10">On the Boards</a></li>
              </ul>
            </li>
            <li><a href="#">Process</a>
             <ul>
                <li><a href="#">Architectural Design</a></li>
                <li><a href="#2">Planning and Programming</a></li>
                <li><a href="#">Interior Design</a></li>
                <li><a href="#">Sustainable Design</a></li>
                <li><a href="#">Project Management</a></li>
                <li><a href="#">Building Information Modeling</a></li>
              </ul>
            </li>
            <li class="current"><a href="#">Firm</a>
              <ul>
                <li><a href="#">Firm Overview</a></li>
                <li><a href="#">People</a></li>
                <li><a href="#2">Careers</a></li>
                <li class="current"><a href="#">Awards</a></li>
                <li><a href="#">Client List </a></li>
              </ul>
            </li>
          ......
          </ul>
        </nav>

JS
$(".no-touch #mainmenu>ul>li").not(".search").hover(function(){
        $(this).addClass("hover");
        $('ul:first',this).stop(true, true).fadeIn(450);
    
    }, function(){
    	$(this).removeClass("hover");
        $('ul:first',this).stop(true, true).fadeOut(450);
    });

48 комментариев

Если я правильно понял задачу, то здесь можно обойтись вообще без js, применив псевдокласс :hover а также комбинации css-свойств display, transition и opacity.
Если всё же использовать js, то нужно проверять существование дочернего элемента например так
if ($('ul:first',this).length != 0) {
    $('ul:first',this).stop(true, true).fadeIn(450);
  }
или просто
if ($('ul:first',this).length) {
    $('ul:first',this).stop(true, true).fadeIn(450);
  }
или так
if ( $('ul:first',this)[0] ) {
  $('ul:first',this).stop(true, true).fadeIn(450);
}
вообще можно и так
if ($('ul:first',this).length) {
    $('ul:first',this).stop(true, true).fadeIn(450);
  }


но основная проблема как вернуть назад подменю текущего меню при «уводе» курсора с пунктов меню или вообще куда либо
Я сходу не понял, в чём может быть проблема? И почему первый вариант без js не подходит?
в том что если я навожу на левый пункт меню а потом убираю с него курсор то срабатывает
$('ul:first',this).stop(true, true).fadeOut(450);
в итоге сабменю остается пустым.
А что должно быть? Как я понимаю — навёл нассылку — если есть ul-потомок у её родителя, то его покажут. Убрал курсор — ul (сабменю) спрячется.

Фейдаут насколько я помню делает примерно то, что я предложил без css c с тем отличием, что вместо свойства display применяется visibility, хотя могу и ошибаться.

Можешь положить на jsfiddle.net это меню?
  • аватар SeL
  • 0
Я не специалист в webUI и не спал больше суток, но все равно не понию в чем проблема.
$("#mainmenu>ul>li>ul").each(function () {
        var current = $("#mainmenu>ul>li.current>ul");
        var menu = this;
        $(this).parent().hover(function() {
            $(current).hide();
            $(menu).show();
        }, function(){
            $(menu).hide();
            $(current).show();
        })
    })
То что доктор прописал, не догадался обойти дом.
Спасибо большое :)
ды не за что)
Расскажи, почему без js не годится? Например, так

#mainmenu li{display:block;float:left;margin-right:10px}
#mainmenu li:hover ul{display:block;opacity:1}​
#mainmenu li ul{position:absolute;top:20px;left:0;opacity:0;-webkit-transition:opacity,.45s;}
Я просто с jquery больше чем с CSS дружу)
Этот вопрос скорее к bananan, а во втором селекторе у меня случайно затесалось ненужное свойство display:block;
ну изначально у нас у li.current ul { display:block}
как ты его скроешь при наведении на другой пункт меню?
сразу говорю background назначать нельзя ибо на другой странице он полупрозначный а под ним картинка
То есть нужно на некой странице показывать текущее меню, соответствующее контексту, а прочие показывать только при наведении?
ага как на картинке в начале. это нормальное состояние меню
на картинке я не увидел полупрозрачности, поэтому предложил бы
#mainmenu li ul {background:#000;z-index:2}
#mainmenu li.current ul {display:block;z-index:1}

Но если там нужна прозрачность, то ты прав, такой вариант не самый лучший, хотя, в зависимости от фона под меню и это можно решить. Собственно, ход мысли ты угадал верно.
Курск

фон это слайдер из картинок. и еще фишка в том что не только там будет hover
если modernizr определит что у нас тачскрин то будет click
Можно что-то такое наманьячить
#mainmenu:hover li.current ul{z-index:-1} 
#mainmenu li.current:hover ul{z-index:1}
а лучше с прозрачностью и тогда получится в итоге вот так
#mainmenu li{display:block;float:left;margin-right:10px}
#mainmenu li:hover ul,#mainmenu li.current ul{display:block;opacity:1}
#mainmenu li ul{position:absolute;top:20px;left:0;opacity:0;-webkit-transition:opacity,.45s;height:70px;width:100%}
#mainmenu:hover li.current ul{opacity:0} 
#mainmenu li.current:hover ul{opacity:1}​
Должно работать с полупрозрачным фоном, а модернизатор (ещё то говно, кстати) для чего используется? Если только для отлавливания события hover, то можешь его выкидывать, а на активные элементы для тач-устройств просто повесь
onclick="return:false"
для определения тача и csstransforms csstransforms3d csstransitions
дак как же я определю что это тач устройство чтоб повесить то?
дак как же я определю что это тач устройство чтоб повесить то?
Шаблонизатор/browscap/js/или просто для всех добавить — ошибок это не вызовет.

Эмуляция всех этих свойств модернизатором совровождается серьёзными тормозами (старые браузеры чаще всего стоят на старых слабых машинах), разумнее не учить старую собаку новым фокусам, а оставить её в покое. Моё мнение таково — уж лучше это выглядит и работает не в точности, как на современных браузерах, но зато работает комфортно. Зачем подменять цель средством? Задача разработчика заключается вовсе не в создании одинакового внешнего вида и поведения абсолютно везде, а в создании удобного полезного интерфейса.

Строго говоря, моё css-only предложение не будет работать в ie6 (исправляется легко) и в опере 6 (когда вы её в последний раз видели?).
или просто для всех добавить

я тогда и по ссылке не перейду
В нашем случае активный элемент для тач-события не ссылка, а её родитель, поскольку список с элементами вложенного меню не является потомком ссылки. Если кратко, то нужно писать так:
<li onclick="return:false">

Этот подход не претендует на статус идеального, я просто выдвинул альтернативное предложения в качестве пищи для размышлений. Тем не менее, он работает.
попробуй нажать на любой линк в сабменю кроме в Firm
Я забыл о том, что нужно позиционировать внутри элемента, на котором срабатывает hover. В этом случае всё несколько сложнее, поскольку придётся использовать фиксированные значения для ширины выпадающих меню и их родителей: jsfiddle.net/bu4cR/1/
Да, ты прав. Я уже закончил работу и рублюсь в openRA, потому результат вышел в стиле «поспешишь — кур насмешишь». Желаешь сыграть, кстати?
Высоту сабменю всё же нужно указать, иначе будет смешная фигня, если медленно перемещать курсор к навигации снизу вверх. Скрытые списку будут откликаться на hover.
и почему-то невозможно навести на субменю чтоб оно не исчезло
не понял
ну навожу на пункт меню появляется сабменю, хочу кликнуть на пункт сабменю, веду мышь а оно пропадает как только происходит mousout с li:hover
покажи макет, может получится и без js обойтись, это всегда лучше, чем с ним
Вообще стыдно, я зачем-то лишние переменные ввел, ну да ладно, главное работает))
кстати попробуй с fadein fadeout. как то не очень ((
Из-за дрожания при наведении на curent?
при наведении на другие пункты на долю секнды появляется сабменю .current и когда навожу на пункт не содержащий сабменю тоже фэйдица и если увести курсор а потом подвести на .current сабменю то он фэйдица туда сюда
эти доли секунды из-за стилей. между #mainmenu>ul>li и #mainmenu>ul>li>ul небольшой зазор, куда попадает курсор и следовательно происходит mouseout. если его убрать, то не будет появляться.

с сабменю пофиксил

ага спс. мигания ушли но странно у меня нет зазора но все равно происходит на долю секунды переход
.main_nav>ul>li {
	display:block;
	float: left;
	line-height: normal;
}
.main_nav>ul>li>a {
	color: #fff;
	text-transform: uppercase;
	font-size: 15px;
	display: block;
	padding-right: 25px;
	padding-left: 25px;
	border-left: 1px solid #666;
}

я сначала думал это из за border который раньше был на li
но я его перенес в поидеи li примыкают плотно друг к другу
не, это не из-за позиционирования оказывается. это именно скрипт такое делает, но я избавился. теперь поменяй fadeOut на hide
так хорошо да )
а синхронный фэйд не выйдет?
выйдет, но нужно вводить проверку является ли пункт:hover пунктом .current, и для тех, которые не являются, не делать $(current).fadeIn(450).

в общем, скрипт увеличится в два раза, проще класс написать)

Чтобы оставлять комментарии, нужно или зарегистрироваться.