2010-11-30 2 views
1

У меня есть меню, в котором есть 8 изображений, и я хочу написать эффект затухания для них. Я хочу показать имя меню, когда мышь перейдет через него, и спрячьте его, когда мышь уйдет. Вот мой код для двух моих пунктов меню:JQuery Fading Problem

$(".menu_account").mouseover(function(){ 
    $("#menu_name").html('first'); 
    $("#menu_name").fadeIn('slow', function(){ 
    $(".menu_account").mouseout(function(){ 
     $("#menu_name").fadeOut('slow', function(){}); 
    }) 
    }); 
}); 

$(".menu_myposts").mouseover(function(){ 
    $("#menu_name").html('second'); 
    $("#menu_name").fadeIn('slow', function(){ 
    $(".menu_myposts").mouseout(function(){ 
     $("#menu_name").fadeOut('slow', function(){}); 
    }) 
    }); 
}); 

Моя проблема, когда я нахожусь на первом пункте, и было появилось имя, когда я двигаю курсор ко второму элементу перед первым угасает, имя innerHTML изменяется, и оно становится уродливым. Я хочу подождать, пока исчезновение будет завершено и начнется снова. Я очень ценю любую помощь. thanx.

Вот мой полный код: HTML:

<div id="menu"> 
       <a class="menu_account"></a> 
       <a class="menu_myposts"></a> 
       <a class="menu_allposts"></a> 
       <a class="menu_favorites"></a> 
       <a class="menu_follow"></a> 
       <a class="menu_logout"></a> 
       <a class="menu_help"></a> 
       <a class="menu_contact"></a> 
      </div> 

<div style="height:20px;width:200px;margin:0 auto;text-align:center;"> 
        <div id="menu_name" style="font-size:30px;color:#A1A1A1;display:none;"></div> 
       </div> 

JS:

$("#menu").ready(function(){ 

$(".menu_myposts").hover(
    function() { 
     $("#menu_name").html('first'); 
     $("#menu_name").fadeIn('slow', function(){}); 
    }, 
    function() { 
     $("#menu_name").fadeOut('slow', function(){}); 
    } 
); 

$(".menu_myposts").hover(
    function() { 
     $("#menu_name").html('second'); 
     $("#menu_name").fadeIn('slow', function(){}); 
    }, 
    function() { 
     $("#menu_name").fadeOut('slow', function(){}); 
    } 
); 
}); 

Правильные JS:

$(".menu_item").hover(
     function() {   
      $("#menu_name").html($('#' + this.id + '_name').html()); 
      $("#menu_name").stop(true, true).fadeIn(); 
     }, 
     function() { 
      $("#menu_name").stop(true, true).fadeOut(); 
     } 
    ); 
+0

Значит, вы не хотите, чтобы пользователь мог парить над любой другой элемент пока не завершится замирание? – Calvin 2010-11-30 20:55:38

+0

@Calvin Точно. – AliBZ 2010-11-30 21:01:26

ответ

1

Я создал Fiddle, что может быть интересно. Это похоже на сообщение this с той разницей, что имена пунктов меню создаются «на лету».

Код из скрипки:

$("#menu li").hover(
    function() { 
     if (!$(this).data("name")) { 
      $(this).data("name", 
       $('<div class="name"></div>') 
        .text($(this).text()) 
        .hide() 
        .appendTo("#nameWrapper")); 
     } 

     $(this).data("name") 
      .stop(true, true) 
      .fadeIn(); 
    }, 
    function() { 
     $(this).data("name") 
      .stop(true, true) 
      .fadeOut(); 
    } 
); 

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

Первая часть функции первого наведения создает элемент имени, если его нет. Элемент связан с элементом меню с помощью функции data().

Вторая часть функции первого наведения только исчезает в элементе имени. Вторая функция исчезает.

Уловка здесь заключается в использовании stop(true, true), чтобы остановить всю анимацию элемента.

EDIT:

Вы начинаете с HTML структуры, как этот:

<ul id="menu"> 
    <li>First</li> 
    <li>Second</li> 
</ul> 
<div id="nameWrapper"></div> 

И через пару наведении мыши Закончено пунктов меню по nameWrapper ДИВ наполняется как так:

<div id="nameWrapper"> 
    <div class="name">First</div> 
    <div class="name">Second</div> 
</div> 

Элементы div.name - это то, что фактически отображается, когда вы наводите курсор на элементы меню. Элементы div.name создаются при наведении курсора на пункт меню в первый раз, в разделе ниже код:

$(this).data("name",     // associate the <div class="name"> element with the menu item that is currently hovered - $(this) 
    $('<div class="name"></div>')  // create a div element 
     .text($(this).text())   // set text inside div to text of the menu item 
     .hide()       // hide the div (it gets faded in later) 
     .appendTo("#nameWrapper"));  // append the element to the element with id nameWrapper 
2

Я думаю mouseout событие должно быть определено снаружи, как это : -

$(".menu_account").mouseover(function(){ 
    $("#menu_name").html('first'); 
    $("#menu_name").fadeIn('slow', function(){ 
    }); 
}); 

$(".menu_account").mouseout(function(){ 
    $("#menu_name").fadeOut('slow', function(){}); 
}) 

Именно поэтому постепенное исчезновение происходит немедленно.

Вы можете повторно использовать код, как это: -

var menuClasses = {'menu_account' : 'first', 'menu_classes' :'second'}; 

$.each(menuClasses function(index, value) { 
    $("."+value).hover(dothisOnMouseover(value), dothisOnMouseout()) 
}); 

$("td").hover(
    function() { 
    $(this).addClass("hover"); 
    }, 
    function() { 
    $(this).removeClass("hover"); 
    } 
); 

function dothisOnMouseover(value) 
{ 
     $("#menu_name").html(value); 
     $("#menu_name").fadeIn('slow', function(){}); 
} 

function dothisOnMouseout() 
{ 
     $("#menu_name").html(''); 
     $("#menu_name").fadeOut('slow', function(){}); 
} 

Обновления
Решение каким-то образом проверить внутри dothisOnMouseout() если fadeIn() завершена уже. Но я не знаю, как это сделать. Итак, у меня есть другой трюк, чтобы позволить mouseover только если fadeOut() является полным -

function dothisOnMouseover(value) 
{ 
     //Remove the `onmouseover="dothisOnMouseover()" binding of all other menus here - or may be all menus - check it. 
     $("#menu_name").html(value); 
     $("#menu_name").fadeIn('slow', function(){ 
      //On completion of this fade in attach back the `onmouseover="dothisOnMouseover"` event binding all other menus here - Note - do not call `dothisOnMouseout()` here 
     }); 
} 

Поступая таким образом, при наведении на любое меню до тех fadeOut() Завершает, ничего не произойдет. попробуйте.

+3

вы можете сделать код более чистым, используя зависание http://api.jquery.com/hover/ – kobe 2010-11-30 21:13:46

+0

@sandeepan Thanx, но у меня все еще такая же проблема. – AliBZ 2010-11-30 21:20:19

+0

@gov Thanx для подсказки;) – AliBZ 2010-11-30 21:20:55

1

Редактировать: Смотрите этот jsFiddle код

Я бы связать все пункты меню сразу с именем класса с идентификатором прикрепленного к каждой из них, как (я просто угадать структуру HTML здесь):

<ul id="menu"> 
    <li class="menu-item" id="account">Account</li> 
    <li class="menu-item" id="myposts">My Posts</li> 
</ul> 

И ваш javascript может быть чем-то вроде ниже. Имейте в виду, что он непроверен, и я не уверен, какой эффект он повлиял бы на производительность.

bindMouseOver(); 
$('.menu-item').mouseout(function(){ 
    $('.menu-item').unbind('mouseover'); //disable all mouseovers while fadeOut is happening 
    $("#menu_name").fadeOut('slow', function(){ 
     bindMouseOver(); //rebind the mouseover event after the fadeOut is completed 
    }); 
}); 
var bindMouseOver = function(){ 
    $('.menu-item').mouseover(function(){ 
     $("#menu_name").html($(this).html()); //use the menu item's innerHTML text, or something else if you prefer 
     $("#menu_name").fadeIn('slow');   
    }); 
}; 
0

Вот JSFiddle я сделал что-то упрощает все JS в один парения слушателя: Example here

[EDIT] обновляется для автоматической загрузки в заголовке меню контейнера ...

Код примера:

CSS

#menu_name div{ 
    position:absolute; 
    display:none; 
} 

.menu_link{ 
    cursor:pointer; 
} 

HTML

<div id="menu_name"></div> 
<br/> 
<div id="menu_account" class="menu_link">link 1</div> 
<div id="menu_myposts" class="menu_link">link 2</div> 

JavaScript

(function() { 
    //auto-load the menu title container... 
    $(".menu_link").each(function(index, item) { 
     $('#menu_name').append('<div id="' + item.id + '-title">' + item.innerHTML + '</div>'); 
    }); 

    $(".menu_link").hover(
     function() { 
      $('#' + this.id + '-title').fadeIn('medium'); 
     }, function() { 
      $('#' + this.id + '-title').fadeOut('medium'); 
    }); 
})();