2

所有,我知道 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的运行机制。所以我有这样一个问题。希望有人愿意告诉我更多关于它的信息,以帮助我更好地理解它。谢谢。

4

2 回答 2

3

我想我只是不了解javascript的运行机制。所以我有这样一个问题。希望有人愿意告诉我更多关于它的信息,以帮助我更好地理解它。

Javascript 没有多线程特性,所以说可能存在竞争问题是错误的。您可能已经注意到,Javascript 是一种事件驱动语言。这是一种架构,有两个主要阶段,主循环,检查是否触发了任何事件,以及事件处理体,为任何触发的事件运行。

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

于 2013-03-29T04:22:05.207 回答
2

相反,我可以建议您一个更好的解决方案,而不是mouseenterand mouseleave,这将是.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.
});
于 2013-03-29T03:28:33.397 回答