如果遵循以下代码顺序,则以下代码应更改div的类,然后显示警报;但是相反,警报在jQuery .addClass()事件触发之前弹出。如何使.addClass()首先启动?
$('div').click(function () {
$(this).addClass('red');
alert('.addClass() should fire *before* the alert, but it will only do so after dismissing the alert.');
});
div {
border:1px solid gray;
padding:3px;
cursor:pointer;
}
.red {background-color:indianred;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Click me</div>
答案 0 :(得分:2)
问题是alert
阻塞了浏览器-调用alert
时,在alert
被取消之前,无法进行进一步的Java处理和渲染。浏览器还没有时间重新绘制页面以反映新的类。
一种可能的解决方案是在setTimeout
之前添加一个小的alert
:
$('div').click(function() {
$(this).addClass('red');
setTimeout(() => {
alert('hi');
});
});
div {
border: 1px solid gray;
padding: 3px;
cursor: pointer;
}
.red {
background-color: indianred;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Click me</div>
最好使用适当的模式而不是alert
-alert
毕竟是用户不友好的。
如果setTimeout
看起来不够优雅,您也可以使用requestAnimationFrame
。将功能传递给requestAnimationFrame
将会在浏览器重新绘制之前在同步运行,因此,如果您在setTimeout
内部调用requestAnimationFrame
,则超时回调将在浏览器重新粉刷:
$('div').click(function() {
$(this).addClass('red');
window.requestAnimationFrame(() => {
setTimeout(() => {
alert('hi');
});
});
});
div {
border: 1px solid gray;
padding: 3px;
cursor: pointer;
}
.red {
background-color: indianred;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Click me</div>
答案 1 :(得分:0)
使用delay and queue
参见下面的示例
$('div').click(function () {
$(this).addClass('red').delay(1).queue(function(){
alert('.addClass() should fire *before* the alert, but it will only do so after dismissing the alert.');
});
});
div {
border:1px solid gray;
padding:3px;
cursor:pointer;
}
.red {background-color:indianred;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>Click me</div>
答案 2 :(得分:-1)
它实际上不是在类更改之前显示的,而是呈现得如此之快,以至于浏览器呈现了完整的更改。
您可以尝试以下
$('div').click(function () {
$(this).addClass('red');
console.log($(this));
alert('.addClass() should fire *before* the alert, but it will only do so after
dismissing the alert.');
});
,您将在浏览器控制台中看到以前应用过红色类。