jquery脚本的两个问题:z-index和setTimeout

时间:2015-01-23 19:18:46

标签: javascript jquery html css

在网站左侧有一个侧边菜单。我希望子菜单以一个整洁的动画向右滑动。我制作了剧本:

jQuery(document).ready(function($){
    $(".main-navigation ul li").mouseenter(function() {
        if ($(this).children().length > 0) {
            $(this).children("ul").css ({
            "display" : "block",
            }).animate({
                left: '250px',
                opacity: 1,
                }, 500)
            }})
            .mouseleave(function() {
                setTimeout(function() {
                    $(this).children("ul").css({
                    "display" : "none",
                    "left" : "0px",
                    "opacity": 0,
                    }) 
                }, 1000);
            });
});

滑动效果很好。菜单显示得很好。

但是有两个问题。一个是,菜单z-index不起作用。子菜单的ul在css中设置了负索引,但是当它滑动时,它会超过主ul。我希望它在菜单下面,所以它没有显示。 第二个是,SetTimeout函数似乎不起作用。一旦鼠标离开该区域,ul就会永远停留在那里。如果没有Settimeout功能,它就会很好地消失(但是我希望它能在那里停留一段时间)。

我做了一个jsfiddle例子 http://jsfiddle.net/r8vx07ae/4/

4 个答案:

答案 0 :(得分:1)

这是因为$(this)正在失去setTimeout功能的范围。要解决此问题,您可以将$(this)范围分配到$this之类的变量中,然后在setTimeout函数中使用它。以下是代码更改:

.mouseleave(function() {
        var $this=$(this);
        setTimeout(function() {
            $this.children("ul").css({
                "display" : "none",
                "left" : "0px",
                "opacity": 0,
            }) 
        }, 1000);
});

这是你的更新小提琴: http://jsfiddle.net/r8vx07ae/5/

答案 1 :(得分:1)

z-index问题:

元素不能出现在其父元素后面。由于子菜单作为菜单的子元素存在,因此无法显示在菜单后面,z-index实际上仅适用于共享同一父元素的两个元素。

setTimeout问题:

问题很可能是由于this变量在超时发生时超出范围而引起的。这有一个简单的解决方法:在超时发生之前创建一个全局变量(比如subMenu)并设置subMenu = this,并在超时函数中用this替换subMenu。如果你有多个子菜单可以使用其他变量或字典/数组,如果两个子菜单一个接一个地打开,则可以防止变量被覆盖

答案 2 :(得分:1)

setTimeout的问题是this

的范围

当它运行时,它是窗口,而不是菜单。

jQuery(document).ready(function($){
    $(".main-navigation ul li").mouseenter(function() {
        /* see if the timer has run yet, if it has not, cancel it */
        var hideTimer = $(this).data("timer");  
        if (hideTimer) window.clearTimeout(hideTimer);

        if ($(this).children().length > 0) {
            $(this).children("ul").css ({
            "display" : "block",
            }).stop().animate({
                left: '250px',
                opacity: 1,
                }, 500)
            }})
            .mouseleave(function() {
                /* store the children here to get rid of the "this" scope issue */
                var ul = $(this).children("ul"); 
                /* Store a reference to the timer so we can cancel it if they mouseover again */
                $(this).data("timer", setTimeout(function() {
                    ul.css({
                    "display" : "none",
                    "left" : "0px",
                    "opacity": 0,
                    }) 
                }, 1000));
            });
});

这不会解决z-index问题。

答案 3 :(得分:1)

我想这是来自setTimeout回调中的“this”的用法,遗憾的是我没有任何计算机可以测试...  请参阅“此问题”部分:https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers.setTimeout#The_%27this%27_problem 要解决此问题,请在调用setTimeout之前保存对此的引用,并在回调中使用已保存的引用