在执行功能期间,如何显示/隐藏动画gif?

发布于 2025-01-22 16:40:25 字数 1123 浏览 3 评论 0原文

我想在执行功能期间显示动画gif(旋转器图标),然后在函数完成时隐藏gif。

但是,我正在实现的代码显然不会显示GIF,因为该函数正在引起线程,并且不允许显示GIF。

示例:( https://jsfiddle.net/jzxu8clt/jzxu8clt/

HTML
<button onclick="go();">Go</button>
<span id="result"></span>
<hr>
<img style="display: none;" id="spinner" src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif">
JS
function longLoop() {
  let count = 1000000000;
  let result = 0;
  for (let i = 1; i <= count; i++) {
    result = i;
  }
  return result;
}

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = longLoop();
  resultElement.innerHTML = result;
  spinnerElement.style.display = 'none';
}

)在调用长期运行函数之前显示GIF的工作,然后在长期运行函数完成时将隐藏GIF。

但是,GIF从来没有机会在浏览器中显示,我不知道如何使GIF显示。注意:如果我在调用longloop()函数的线路上放置一个断点,则正确显示了gif。

在longloop()函数期间,我需要做什么才能使GIF显示和动画?

I want to display an animated GIF (spinner icon) during the execution of a function and then hide the GIF when the function is completed.

However, the code that I'm implementing does not display the GIF apparently because the function is hogging the thread and not allowing the GIF to ever be shown.

Example: (https://jsfiddle.net/jzxu8cLt/)

HTML
<button onclick="go();">Go</button>
<span id="result"></span>
<hr>
<img style="display: none;" id="spinner" src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif">
JS
function longLoop() {
  let count = 1000000000;
  let result = 0;
  for (let i = 1; i <= count; i++) {
    result = i;
  }
  return result;
}

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = longLoop();
  resultElement.innerHTML = result;
  spinnerElement.style.display = 'none';
}

The go() function above should do the work of showing the GIF prior to calling a long running function, then will hide the GIF when the long running function is completed.

However, the GIF never has a chance to be displayed in the browser and I can't figure out how to get the GIF to be displayed. Note: If I place a breakpoint at the line that calls the longLoop() function, the GIF is displayed correctly.

What do I need to do to allow the GIF to be displayed and animated during the longLoop() function?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

遥远的绿洲 2025-01-29 16:40:25

是的,您是对的,由于JavaScript是单线读取的,因此Longloop函数正在阻止事件循环,而不是让浏览器有机会渲染GIF。

jsfiddle解决方案: https://jsfiddle.net/12yf4tgd/12yf4tgd/ 将其包裹在承诺中,以便在完成后运行其他任务。

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';

  new Promise(resolve => setTimeout(() => {
    resolve(longLoop())
  }))
  .then((result) => {
    spinnerElement.style.display = 'none';
    resultElement.innerHTML = result;   
  })
}

由于它是由某些Web API在其他地方处理的,而不是在主呼叫堆栈上处理,因此不会阻止它。

如果您不想因为所有嵌套而使用。

async function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = await new Promise((resolve, reject) => {
    setTimeout(() => resolve(longLoop()))
  })
  spinnerElement.style.display = 'none';
  resultElement.innerHTML = result;
}

他们俩都以相同的方式工作。

Yep you're right, since JavaScript is single-threaded, the longLoop function is blocking the event loop and not giving the browser a chance to render the gif.

JsFiddle solution: https://jsfiddle.net/12yf4tgd/

I used setTimeout to make the longLoop function asynchronous and wrap that in a Promise so that the other assignments run after it completes.

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';

  new Promise(resolve => setTimeout(() => {
    resolve(longLoop())
  }))
  .then((result) => {
    spinnerElement.style.display = 'none';
    resultElement.innerHTML = result;   
  })
}

Since it is being handled elsewhere by some Web Api and not on the main call stack, it won't be blocking.

If you don't want to use .then() because of all the nesting, the other option is to make go() and async function to take advantage of async/await syntax.

async function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = await new Promise((resolve, reject) => {
    setTimeout(() => resolve(longLoop()))
  })
  spinnerElement.style.display = 'none';
  resultElement.innerHTML = result;
}

They both work the same way.

很酷不放纵 2025-01-29 16:40:25

运行长时间运行并恢复代码,以a settimeimout 参数省略或0将执行“立即”,或更准确地执行下一个事件周期,这将阻止阻塞。

function longLoop() {
  let count = 1000000000;
  let result = 0;
  for (let i = 1; i <= count; i++) {
    result = i;
  }
  return result;
}

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  setTimeout(() => {
    let result = longLoop();
    resultElement.innerHTML = result;
    spinnerElement.style.display = 'none';
  })
}
<button onclick="go();">Go</button>
<span id="result"></span>
<hr>
<img style="display: none;" id="spinner" src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif">

Run your long running and revert code in a setTimeout with timing param omitted or 0 which will execute "immediately", or more accurately, the next event cycle, which will prevent the blocking.

function longLoop() {
  let count = 1000000000;
  let result = 0;
  for (let i = 1; i <= count; i++) {
    result = i;
  }
  return result;
}

function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  setTimeout(() => {
    let result = longLoop();
    resultElement.innerHTML = result;
    spinnerElement.style.display = 'none';
  })
}
<button onclick="go();">Go</button>
<span id="result"></span>
<hr>
<img style="display: none;" id="spinner" src="https://upload.wikimedia.org/wikipedia/commons/b/b1/Loading_icon.gif">

衣神在巴黎 2025-01-29 16:40:25

我建议您在这里使用异步/等待您的pourpuse在这里更可读的代码:一个解决方案:

function longLoop(timeout) {
  return new Promise(resolve => setTimeout(resolve, timeout));
}

async function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = await longLoop(4000);
  
  spinnerElement.style.display = 'none';
 
}

I will recommend use async/await for you pourpuse will be more readable code here a solutions:

function longLoop(timeout) {
  return new Promise(resolve => setTimeout(resolve, timeout));
}

async function go() {
  let spinnerElement = document.getElementById('spinner');
  let resultElement = document.getElementById('result');
  spinnerElement.style.display = 'block';
  let result = await longLoop(4000);
  
  spinnerElement.style.display = 'none';
 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文