使用jQuery切换类时,CSS样式无法立即应用

时间:2019-01-01 03:37:49

标签: javascript jquery html css

我正在尝试在后台运行某些javascript时更改元素的样式,以指示页面“繁忙”或“正在加载”。我一直在尝试通过在jQuery脚本的开头用jQuery的.toggleClass()切换一个类,并在结尾将其切换为合适的CSS样式来切换类。

尽管该类会立即切换,但是附加到它的CSS样式直到JS完成执行后才适用。因此,如果同时打开和关闭该类,则用户不会看到样式上的任何更改。

我在下面提供了一个简单的示例。在其余的JS代码执行之前,如何强制CSS样式更改立即应用?

$(function() {
  $('#box').click(function() {

    // Toggle class 'red' on.
    $(this).toggleClass('red');

    // Do something that takes time.
    for (i = 0; i < 10000; i++) {
      console.log(i);
    }

    // Toggle class 'red' off.
    $(this).toggleClass('red');
  });
});
.wrapper {
  margin: 15px;
  text-align: center;
  color: #000;
}

#box {
  margin: 15px 0;
  width: 100px;
  height: 100px;
  line-height: 100px;
  cursor: pointer;
  background: #ccc;
  border: solid 3px #ccc;
  -webkit-transition: all .3s linear 0s;
  transition: all .3s linear 0s;
}

#box.red {
  background: #f43059;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <div id="box">Click me.</div>
</div>

1 个答案:

答案 0 :(得分:1)

问题在于您的“耗时的东西”是同步且受阻的-在运行时,浏览器重绘将被禁用。

一种选择是监听transitionend事件,以确保红色的动画在资源密集型操作运行之前完成。

为使.red的移除也能发出动画效果,您可以在完成繁重的操作后立即设置setTimeout。请注意,如果您使用addClassremoveClass而非toggleClass,则代码会更清晰:

$('#box').click(function() {
  $(this).one('transitionend', () => {
    // Do something that takes time.
    for (i = 0; i < 1000; i++) {
      console.log(i);
    }
    // Toggle class 'red' off.
    setTimeout(() => {
      $(this).removeClass('red');
    });
  });
  $(this).addClass('red');
});
.wrapper {
  margin: 15px;
  text-align: center;
  color: #000;
}

#box {
  margin: 15px 0;
  width: 100px;
  height: 100px;
  line-height: 100px;
  cursor: pointer;
  background: #ccc;
  border: solid 3px #ccc;
  -webkit-transition: all .3s linear 0s;
  transition: all .3s linear 0s;
}

#box.red {
  background: #f43059;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="wrapper">
  <div id="box">Click me.</div>
</div>