Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
592 views
in Technique[技术] by (71.8m points)

javascript - Why does JS wait until function is complete before changing background color?

Why doesn't the background change right as I copy? I added a console.log() and as you can see, the console.log() works, but the background won't change. What is the problem here?

To test, click on the snippet and then press CMD + C (Windows:CTRL + C)

window.addEventListener('copy', function(e) {
  e.preventDefault();

  //This should change!
  document.getElementById("object").style.backgroundColor = 'white';
  console.log("Started!");

  tryCopyAsync(e).then(() =>
    document.getElementById("object").style.backgroundColor = 'gray'
  );
});
async function tryCopyAsync(e){
  if(navigator.clipboard){
    await e.clipboardData.setData('text/plain',getText());
  }
}
function getText(){
  var html = '';
  var row = '<div></div>';
  for (i=0; i<100000; i++) {
      html += row;
  }
  return html;
}
#object{
  width:100%;
  height:100vh;
  background:gray;
}
body{
  padding:0;
  margin:0;
  overflow:hidden;
}
<div id='object'></div>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

First, your sleepFor method is completely blocking the event-loop synchronously, even if it is called from an async function:

window.addEventListener('copy', function(e) {
  e.preventDefault();

  //This should change!
  document.getElementById("object").style.backgroundColor = 'white';
  console.log("Started!");

  tryCopyAsync(e).then(() =>
    document.getElementById("object").style.backgroundColor = 'gray'
  );
  console.log('sync');
});
async function tryCopyAsync(e){
  if(navigator.clipboard){
    await e.clipboardData.setData('text/plain',getText());
  }
}
function sleepFor(sleepDuration){
  var now = new Date().getTime();
  while(new Date().getTime() < now + sleepDuration){} 
}
function getText(){
  console.log('blocking');
  var html = '';
  var row = '<div></div>';
  for (i=0; i<10; i++) {
      html += row;
      sleepFor(300);
  }
  console.log('stopped blocking');
  return html;
}
onclick = e => document.execCommand('copy');
#object{
  width:100%;
  height:100vh;
  background:gray;
}
body{
  padding:0;
  margin:0;
  overflow:hidden;
}
click to trigger the function
<div id='object'></div>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...