Javascript 在悬停和动画回调上设置活动元素的jQuery脚本存在问题

Javascript 在悬停和动画回调上设置活动元素的jQuery脚本存在问题,javascript,jquery,Javascript,Jquery,我在一个有一系列元素的网站上工作,并且在任何时候只有一个元素必须处于活动状态。当该元素处于活动状态时,将显示“详细信息”div 当您将鼠标悬停在这些元素上时,这些元素将变为活动元素,但正如我所说的,它们中只有一个可以同时处于活动状态。我当前正在使用活动类设置活动元素 在我当前的代码中,当用户将鼠标悬停在任何元素上时会发生以下情况: 前一个活动元素删除了类“active”,并逐渐消失 在淡出回调中,悬停的元素变为活动(获取类“active”),并且是fadeIn 如果当前没有活动元素,则悬停的元

我在一个有一系列元素的网站上工作,并且在任何时候只有一个元素必须处于活动状态。当该元素处于活动状态时,将显示“详细信息”div

当您将鼠标悬停在这些元素上时,这些元素将变为活动元素,但正如我所说的,它们中只有一个可以同时处于活动状态。我当前正在使用活动类设置活动元素

在我当前的代码中,当用户将鼠标悬停在任何元素上时会发生以下情况:

  • 前一个活动元素删除了类“active”,并逐渐消失
  • 在淡出回调中,悬停的元素变为活动(获取类“active”),并且是fadeIn
  • 如果当前没有活动元素,则悬停的元素将变为活动(类“活动”)并为fadeIn
这可以解决问题,但当您在元素之间快速悬停时,会有一个短暂的时刻,其中没有任何元素处于活动状态,因此多于元素将获得活动类并显示

你将如何处理这个问题

这是我的密码:

function setActive(selected) {


    //stores the active element in a variable
    active = selected;

    //checks if there are currently elements with the 'active' class in the DOM
    if ( $('#info article.active').length > 0) {

        //if there is any currently active element, and its element_id attribute is not the one stored in the active variable
        //it gets the 'active' class removed, its hidden, and in the callback of the animation
        //the newly selected element gets the class 'active' and is shown with fadeIn

        $('#info article.active[element_id!="' + selected + '"]').removeClass('active').fadeOut('fast', function(){
            $('#info article[element_id="' + selected +'"]').addClass('active').fadeIn('normal');
            }); 

    } else {

        //if there is no current active element, the newly selected one is applied the class active, and shown with fadeIn

        $('#info article[element_id="' + selected +'"]').addClass('active').fadeIn('normal');
    }
}

如果可以的话,在JSFIDLE中用HTML设置一个链接,这样我就可以有更详细的了解

但我认为你的问题是由fadeIn和/或fadeOut的动画引起的。尝试在设置动画时停止悬停,
$('selector')。is(':animated')==false,例如

已更新

function setActive(selected) {
    //*******if animate is happening, hide elements and removes class
    if ($('#info article').is(':animated')) {
        $('#info article.active').removeClass('active').hide();
    }
    //*******Check if everything is not animated and do hover
    if (!$('#info article').is(':animated')) {
        //stores the active element in a variable
        active = selected;

        //checks if there are currently elements with the 'active' class in the DOM
        if ($('#info article.active').length > 0) {

            //if there is any currently active element, and its element_id attribute is not the one stored in the active variable
            //it gets the 'active' class removed, its hidden, and in the callback of the animation
            //the newly selected element gets the class 'active' and is shown with fadeIn
            $('#info article.active[element_id!="' + selected + '"]').removeClass('active').fadeOut('fast', function() {
                $('#info article[element_id="' + selected + '"]').addClass('active').fadeIn('normal');
            });

        } else {

            //if there is no current active element, the newly selected one is applied the class active, and shown with fadeIn
            $('#info article[element_id="' + selected + '"]').addClass('active').fadeIn('normal');
        }
    }
}
在滑鼠天桥上的迷路(mis)射击和/或挑剔的目标是一个常见问题。标准解决方案是在悬停“粘住”之前有一个小的延迟

重要提示:该问题没有显示如何调用
setActive()

但是,如果您按照如下方式构造HTML:

<div id="flyOverControls">
    <ul>
        <li rel="Article_1">Show 111</li>
        <li rel="Article_2">Show 222</li>
        <li rel="Article_3">Show 333</li>
        <li rel="Article_4">Show 444</li>
    </ul>
</div>
<div id="info">
    <article id="Article_1">First article.</article>
    <article id="Article_2">Second article.</article>
    <article id="Article_3">Third article.</article>
    <article id="Article_4">Fourth article.</article>
</div>
$("#flyOverControls li").hover (function (zEvent) {setActiveArticle (zEvent); } );

那么这段代码就应该做到了。根据口味调整速度。就我个人而言,我会扼杀这种淡出

function setActiveArticle (zEvent)
{
    var dDelay;
    var ActionFunction  = null;
    var targetID        = $(zEvent.currentTarget).attr ('rel');

    if (zEvent.type == 'mouseenter')
    {
        //--- Hovering over a new article control... Pause for an ergo delay.
        dDelay          = 300;
        ActionFunction  = function (targetID, context) {
            //--- If we are setting the same article, then nothing needs be done here.
            if ( ! (context.lastArticle  &&  context.lastArticle == targetID) ) {
                //checks if there are currently elements with the 'active' class in the DOM
                if ( $('#info article.active').length > 0) {

                    /*  If there is any currently active element, and its element_id attribute is not the one stored in the
                        active variable it gets the 'active' class removed, it's hidden, and in the callback of the animation
                        the newly selected element gets the class 'active' and is shown with fadeIn.
                    */
                    $('#info article.active').removeClass ('active').fadeOut ('fast', function () {
                        $('#info article#' + targetID).addClass ('active').fadeIn ('normal');
                    } );

                } else {
                    //if there is no current active element, the newly selected one is applied the class active, and shown with fadeIn

                    $('#info article#' + targetID).addClass ('active').fadeIn ('normal');
                }
                context.lastArticle = targetID;
            }
        };
    }
    else //-- zEvent.type == 'mouseleave'
    {
        //--- Done hovering, no action is needed, other than to wait, in case of user jitter.
        dDelay          = 200;
        ActionFunction  = function (targetID, context) {
            var noOp    = 0;
        };
    }

    if (typeof this.delayTimer == "number")
    {
        clearTimeout (this.delayTimer);
    }
    context             = this;
    this.delayTimer     = setTimeout (function() { ActionFunction (targetID, context); }, dDelay);
}


谢谢你,马克。但是,在当前事件完成之前,这不会使函数忽略新事件吗?我认为理想的行为是停止任何当前活动,并执行最后一个触发的事件。这是正确的,因此您需要做的是,使用“:animated”方法。检查悬停时是否已设置动画,执行即时隐藏。如果未设置动画,请检查“非”是否处于活动和隐藏状态,并进行淡入以获得正确的当前悬停。