【问题标题】:jquery timeout-function never called on mouseenter mouseleavejquery timeout-function 从不调用 mouseenter mouseleave
【发布时间】:2012-04-29 17:06:35
【问题描述】:

我在使用 setTimeout 函数时遇到了一点问题。

$(this) 是每个具有特定类的 DOM 元素。

当鼠标进入一个元素,然后离开它,没有问题。但是当鼠标将一个元素直接离开另一个元素(在 500 毫秒超时内)时,第一个元素(即鼠标离开的那个元素)永远不会淡出。

因此,新的 mouseenter-Event 类型会阻止 timeOut 调用该函数。 没有 setTimeout-wrapper 一切正常。

这是我的代码:

$(this).hover(methods['mouseenterManager'], methods['mouseleaveManager']);


/**
 * manage mouseenter events
 */
mouseenterManager: function() {

    clearTimeout(timer);

    //create toolbar, if no toolbar is in dom
    if ($(this).data("layouter").toolbar == undefined) {

        //get bottom center of this element
        pos_left = ($(this).width() / 2) + $(this).offset().left;
        pos_top = $(this).height() + $(this).offset().top;

        //create toolbar element
        toolbar = $('<div style="display:none; left:' + parseInt(pos_left) + 'px; top:' + parseInt(pos_top) + 'px;" class="layouter_bar"><ul><li><a class="edit" href="javascript:;">Edit</a></li><li><a class="copy" href="javascript:;">Edit</a></li><li><a class="remove" href="javascript:;">Edit</a></li></ul></div>');

        //bind this element to toolbar
        toolbar.data("layouter", {
            parent: $(this),
        });

        //bind toolbar to this element
        data = $(this).data("layouter");
        data.toolbar = toolbar;
        $(this).data("layouter", data);

        //bind this element to toolbar
        data = toolbar.data("layouter");
        data.parent = $(this);
        toolbar.data("layouter", data);

        element = $(this);
        toolbar.mouseleave(function() {

            toolbar = $(this);
            timer = setTimeout(function() {
                if (!toolbar.is(":hover") && !element.is(":hover")) {

                    toolbar.fadeOut("fast", function() {
                        $(this).remove();
                    });

                    data = element.data("layouter");
                    data.toolbar = undefined;
                    element.data("layouter", data);
                }
            }, 500);
        });

        //display the toolbar  
        $("body").append(toolbar);
        toolbar.fadeIn("fast");
    }
},


/**
 * manage mouseleave events
 */
mouseleaveManager: function() {

    toolbar = $(this).data("layouter").toolbar;
    element = $(this);
    if (toolbar != undefined) {
        timer = setTimeout(function() {
            if (!toolbar.is(":hover")) {

                toolbar.fadeOut("fast", function() {
                    $(this).remove();
                });

                data = element.data("layouter");
                data.toolbar = undefined;
                element.data("layouter", data);
            }
        }, 500);
    }
},

};​

有什么想法吗?

谢谢!

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    在我看来,您使用了很多全局变量,当您进入另一个元素时,所有这些全局变量的值都会发生变化。您的超时函数正在引用这些全局变量,因此当它们通过输入另一个元素进行更改时它无法正常工作。

    在我看来,一旦你输入另一个元素,你就会清除计时器以防止它运行,并且由于它是一个全局计时器,所以只有一个,所以你已经杀死了你想要触发的计时器。

    对于全局变量问题,将var放在所有应该是局部变量的前面,如下所示:

    var toolbar = $(this).data("layouter").toolbar;
    var element = $(this);
    

    //get bottom center of this element
    var pos_left = ($(this).width() / 2) + $(this).offset().left;
    var pos_top = $(this).height() + $(this).offset().top;
    

    对于计时器问题,在我看来,您不需要有一个全局计时器,而是需要为每个元素设置一个计时器。这有点复杂。如果没有我可以运行和测试的东西,我无法确定这是否可以在没有任何其他更改的情况下工作,但这是朝着正确方向迈出的一步,可以将变量固定为本地变量,并使每个元素的计时器都本地化:

    $(this).hover(methods['mouseenterManager'], methods['mouseleaveManager']);
    
    
    /**
     * manage mouseenter events
     */
    mouseenterManager: function() {
    
        var self = $(this);
        var timer = self.data("timer");
        if (timer) {
            clearTimeout(timer);
        }
    
        //create toolbar, if no toolbar is in dom
        if (self.data("layouter").toolbar == undefined) {
    
            //get bottom center of this element
            var pos_left = ($(this).width() / 2) + $(this).offset().left;
            var pos_top = $(this).height() + $(this).offset().top;
    
            //create toolbar element
            var toolbar = $('<div style="display:none; left:' + parseInt(pos_left) + 'px; top:' + parseInt(pos_top) + 'px;" class="layouter_bar"><ul><li><a class="edit" href="javascript:;">Edit</a></li><li><a class="copy" href="javascript:;">Edit</a></li><li><a class="remove" href="javascript:;">Edit</a></li></ul></div>');
    
            //bind this element to toolbar
            toolbar.data("layouter", {
                parent: self,
            });
    
            //bind toolbar to this element
            var data = self.data("layouter");
            data.toolbar = toolbar;
            self.data("layouter", data);
    
            //bind this element to toolbar
            data = toolbar.data("layouter");
            data.parent = self;
            toolbar.data("layouter", data);
    
            var element = self;
            toolbar.mouseleave(function() {
    
                toolbar = self;
                timer = setTimeout(function() {
                    self.data("timer", null);
                    if (!toolbar.is(":hover") && !element.is(":hover")) {
    
                        toolbar.fadeOut("fast", function() {
                            $(this).remove();
                        });
    
                        data = element.data("layouter");
                        data.toolbar = undefined;
                        element.data("layouter", data);
                    }
                }, 500);
                self.data("timer", timer);
            });
    
            //display the toolbar  
            $("body").append(toolbar);
            toolbar.fadeIn("fast");
        }
    },
    
    
    /**
     * manage mouseleave events
     */
    mouseleaveManager: function() {
    
        var toolbar = $(this).data("layouter").toolbar;
        var element = $(this);
        var timer = element.data("timer");
        if (toolbar != undefined && !timer) {
            timer = setTimeout(function() {
                element.data("timer", null);
                if (!toolbar.is(":hover")) {
    
                    toolbar.fadeOut("fast", function() {
                        $(this).remove();
                    });
    
                    var data = element.data("layouter");
                    data.toolbar = undefined;
                    element.data("layouter", data);
                }
            }, 500);
            element.data("timer", timer);
        }
    },
    
    };​
    

    【讨论】:

    • 谢谢!这是一个简单的全球/本地问题!我唯一需要使用“var”将局部变量标记为局部变量。
    【解决方案2】:

    将要编辑的元素传递给计时器的函数。

    例如:

    timer = setTimeout(function(toolbar, element) {
            if (!toolbar.is(":hover")) {
    
                toolbar.fadeOut("fast", function() {
                    toolbar.remove();
                });
    
                data = element.data("layouter");
                data.toolbar = undefined;
                element.data("layouter", data);
            }
        }, 500)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多