2017-10-12 17 views
2

jQuery的,CSS不长的时间执行函数之前的变化

function doact() { 
 
    $('p.main').addClass("hide"); 
 
    $('p.loading').removeClass("hide"); 
 

 
    //this is only example of long time exec function 
 
    for (var i = 0; i < 1000000000; i++) { 
 
    for (var j = 0; j < 2; j++) {} 
 
    } 
 
    // 
 

 
    $('p.loading').addClass("hide"); 
 
    $('p.main').removeClass("hide"); 
 

 
    alert('done'); 
 
}
.hide { 
 
    display: none; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<p class="loading hide">loading...</p> 
 
<p class="main">bla bla bla</p> 
 
<input id="btn" type="button" value="do action" onclick="doact()" />

当我按一下按钮,loading...不会出现,main没有消失,只是做信息。 如何实现这样的算法?

回答

3

问题是因为JS是单线程的。因此渲染器在启动巨大循环之前没有足够的时间重新绘制UI。然后它只能在环路完成后更新,此时它隐藏了该元素,然后再次立即显示,因此没有任何事情发生。

若要解决此问题,请在setTimeout()中运行阻止代码,并稍稍延迟一段时间,以便在启动循环之前更新UI时间。

另请注意,应避免on*事件属性。我修改代码以使用一个不显眼的JS处理程序,因为你已经包括jQuery的反正:

$('#btn').click(function() { 
 
    $('p.main, p.loading').toggleClass("hide"); 
 

 
    setTimeout(function() { 
 
    for (var i = 0; i < 1000000000; i++) { 
 
     for (var j = 0; j < 2; j++) {} 
 
    } 
 

 
    $('p.main, p.loading').toggleClass("hide"); 
 
    console.log('done'); 
 
    }, 50); 
 
})
.hide { 
 
    display: none; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> 
 
<p class="loading hide">loading...</p> 
 
<p class="main">bla bla bla</p> 
 
<input id="btn" type="button" value="do action" />

随着中说,它阻止用户界面长期运行的同步操作是非常坏模式。我强烈建议重构你的代码,以避免这种情况。

相关问题