为什么我不能在功能开始时更改此按钮的文本?

Mar*_*cel 2 html javascript jquery

我有一个按钮.onClick按钮触发JS函数.在第一行代码中的这个函数中,我使用jQuery更改了按钮的HTML.然后该功能需要几秒钟.按钮HTML仅在完成功能完成后更改(在浏览器中).

https://jsfiddle.net/wqps1r0k/

代码:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>
<button class="btn btn-primary" onclick="setToDisabled(this)">Toggle</button>

    <script type="text/javascript">
    function setToDisabled(btn) {
      //log
      console.log('start');

      //how to force the browser to show this text immediately?
      $(btn).html("TEXT CHANGED ON START OF FUNCTION");

      //create a 2 seconds delay
      var d1 = new Date();
      var t1 = d1.getTime();
      var keeprunning = true;
      while(keeprunning) {
        var d2 = new Date();	
        var t2 = d2.getTime();
        var dif = t2 - t1;
        if((dif / 1000) > 2) keeprunning = false;
      }
    
      //log
      console.log('done');
    }
    </script>
Run Code Online (Sandbox Code Playgroud)

在这个例子中,是否可以在流程开头更改按钮文本并立即在浏览器中查看?例如,将文本更改为"正在加载...".

如果我检查按钮,您可以看到文本直接更改,但只有在功能完成后才能看到.

PS.我用铬

Ror*_*san 6

问题是因为while()循环是同步的并且在更新UI的浏览器线程有机会执行之前开始执行.因此,阻止UI更改,直到循环结束,此时新的HTML将应用于按钮.

要解决此问题,请使用超时来延迟某些逻辑.它是异步的,不会干扰UI:

$('.btn').click(function() {
  console.log('start');
  $(this).html("TEXT CHANGED ON START OF FUNCTION");

  setTimeout(function() {
    console.log('done');
  }, 2000);
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="btn btn-primary">Toggle</button>
Run Code Online (Sandbox Code Playgroud)

另请注意,我on*使用不显眼的事件处理程序删除了过时的事件属性,因为这被认为是更好的做法.