Mouseenter和mouseleave种族问题

时间:2013-03-29 03:17:50

标签: javascript jquery

全部,我知道javascript在单线程模式下运行。但是我不确定在某些情况下是否存在在多线程世界中常见的竞赛问题。 假设你有html结构

<div id='parent' class="parent container">
    <div id="child1" class="child container">
       <div id="child11" class="child container">
           <!--maybe there are more nested divs with class 'container' -->
       </div>
       <div id="child12" class="child container">
           <!--maybe there are more nested divs with class 'container' -->
       </div> 
    </div>
    <div id="child2" class="child container">
       <div id="child21" class="child container">
           <!--maybe there are more nested divs with class 'container' -->
       </div>
       <div id="child122" class="child container">
           <!--maybe there are more nested divs with class 'container' -->
       </div> 
    </div>
</div>

JS代码:

$(function() {
    $('div.container').mouseenter(function(e){
        e.stopPropagation();
        $(this).css("border","2px solid red");//set it selected state.
        $(this).append("<div class='newdiv'></div>"); 
        $(this).parents().each(function(){
            if ($(this).children(".newdiv").length>0)
            {
                $(this).children(".newdiv").remove();
                $(this).css("border","1px solid black");//set father of it not selected state
            }
        });
    }).mouseleave( function(e){
        $(".newdiv",this).remove();
        if ($(this).parent().hasClass("container") && $(".newdiv",$(this).parent()).length==0)
        {
            $(this).parent().css("border","2px solid red");//set it's parent selected state.
            $(this).parent().append("<div class='newdiv'></div>"); 
        }
        $(this).css("border","1px solid black");//set it not selected state.
    });
});

如果我将鼠标快速移入和移出这些div,我怀疑是否存在种族问题。因为我发现有时div.newdiv没有删除。我想我只是不明白javascript的运行机制。所以我有这样一个问题。希望有人想告诉我更多有关它的信息,以帮助我更好地理解它。感谢。

2 个答案:

答案 0 :(得分:3)

  

我想我只是不明白的运行机制   JavaScript的。所以我有这样一个问题。希望有人想告诉   我更多的是帮助我更好地理解它。

Javascript没有多线程功能,因此说可能存在种族问题是错误的。您可能已经注意到,Javascript是一种事件驱动的语言。这是一种体系结构,它有两个主要阶段,主循环,用于检查是否触发了任何事件; 事件处理体,它针对任何触发事件运行。

在这种情况下,问题在于主循环阶段。 onmouseenter只是一小部分时间,也就是当鼠标到达节点的边缘时。因此,如果在主循环中检查另一个事件时处于边缘,则会发生类似问题的事情。但是使用悬停,这部分时间会更长,因此在主循环中检查的概率更高(接近100%)。

答案 1 :(得分:2)

相反,我可以建议您使用更好的解决方案,而不是mouseentermouseleave,这将是.hover()并且不会发生冲突。

$('div.container').hover(function(e){
    e.stopPropagation();
    $(this).css("border","2px solid red");//set it selected state.
    $(this).append("<div class='newdiv'></div>"); 
    $(this).parents().each(function(){
        if ($(this).children(".newdiv").length>0)
        {
            $(this).children(".newdiv").remove();
            $(this).css("border","1px solid black");//set father of it not selected state
        }
    });
}, function(e){
    $(".newdiv",this).remove();
    if ($(this).parent().hasClass("container") && $(".newdiv",$(this).parent()).length==0)
    {
        $(this).parent().css("border","2px solid red");//set it's parent selected state.
        $(this).parent().append("<div class='newdiv'></div>"); 
    }
    $(this).css("border","1px solid black");//set it not selected state.
});