为什么第二次我在一个元素上盘旋它消失了?

时间:2014-09-11 10:14:18

标签: javascript jquery

我正在尝试创建一个代码,当你将跨度悬停几秒钟时,会出现一个框,如果你将鼠标放在盒子上,它就会静止而不会再次淡出。示例代码是这样的:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>I'm a pathetic programmer please don't flame me</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
    <script type="text/javascript">
        $(function() {
            var b = 1000;
            var c = $('#box');
            var d = function(a) {
                if (a) {
                    c.fadeOut(500)
                } else {
                    c.fadeIn(500)
                }
            };
            $('span').mouseenter(function() {
                e = setTimeout(function() {
                    d()
                }, b);
                $(this).mouseleave(function() {
                    typeof e != 'undefined' && clearTimeout(e);
                    f = setTimeout(function() {
                        d(1)
                    }, 300)
                })
            });
            c.mouseenter(function() {
                clearTimeout(f);
                typeof g != 'undefined' && clearTimeout(g)
            }).mouseleave(function() {
                g = setTimeout(function() {
                    d(1)
                }, 300)
            })
        });
    </script>
    <style type="text/css" media="screen">
        #box {
            display: none;
            width: 100px;
            height: 100px;
            background-color: lightblue;
        }
    </style>
</head>
<body>
<span>HOVER ME</span>
<div id="box"></div>
</body>
</html>

编辑: JS小提琴现场测试:http://jsfiddle.net/2ogcp9tm/

问题是我第一次运行它时代码工作正常,但是如果我将鼠标悬停在第二次并尝试将鼠标放在蓝色框上,它就会消失。

为什么会这样?

4 个答案:

答案 0 :(得分:2)

每次输入span时,都会为该范围绑定mouseleave处理程序。因此,如果您多次输入跨度,当您离开时,您将多次运行mouseleave处理程序。其中每个都会调用setTimeout(),但f只会设置为最后一个。因此,当您稍后执行clearTimeout(f)时,它只会清除其中一个,其他人继续运行。

在另一个事件处理程序中绑定一个事件处理程序几乎是不对的。事件处理程序通常应在顶层定义。如果您希望一个处理程序依赖于某个其他处理程序是否先运行,请使用变量来跟踪它。

答案 1 :(得分:1)

每次为.mouseleave()触发mouseenter时,您都会挂起span事件处理程序,为同一事件创建多个事件处理程序,从而触发所有这些处理程序,从而生成mouseleave逻辑不正确(设置多个超时并重写f变量)。

应该用以下内容重写

.mouseleave()

var e;

$('span').mouseenter(function() {
    e = setTimeout(function() {
        d()
    }, b);
});

$('span').mouseleave(function() {
    typeof e != 'undefined' && clearTimeout(e);
    f = setTimeout(function() {
        d(1)
    }, 300)
});

Updated fiddle

答案 2 :(得分:1)

试试这个:click here for jsfiddle working code

旧代码:

       $('span').mouseenter(function() {
            e = setTimeout(function() {
                d()
            }, b);
            $(this).mouseleave(function() {
                typeof e != 'undefined' && clearTimeout(e);
                f = setTimeout(function() {
                    d(1)
                }, 300)
            })
        });

新守则:

        $('span').mouseenter(function() {
            e = setTimeout(function() {
                d()
            }, b);
        }).mouseleave(function() {
            typeof e != 'undefined' && clearTimeout(e);
            f = setTimeout(function() {
                d(1)
            }, 300)
        });

答案 3 :(得分:0)

$(function() {
        var b = 1000;
        var c = $('#box');
        var d = function(a) {
            if (a) {
                c.fadeOut(500)
            } else {
                c.fadeIn(500)
            }
        };
        $('span').mouseenter(function() {
            e = setTimeout(function() {
                d()
            }, b);
        });
            $('#box').mouseenter(function() {
            e = setTimeout(function() {
                d()
            }, b);
            $(this).mouseleave(function() {
                typeof e != 'undefined' && clearTimeout(e);
                f = setTimeout(function() {
                    d(1)
                }, 300)
            })
        });
        c.mouseenter(function() {
            clearTimeout(f);
            typeof g != 'undefined' && clearTimeout(g)
        }).mouseleave(function() {
            g = setTimeout(function() {
                d(1)
            }, 300)
        })
    });

这里是JSFiddle` http://jsfiddle.net/2ogcp9tm/3/