Javascript中的img onload-event时没有页面呈现 [英] No page rendering while img onload-event in Javascript

查看:53
本文介绍了Javascript中的img onload-event时没有页面呈现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个香草Javascript,可将img的src属性设置为data-uri.在分配给 onload 事件的函数中,我尝试在页面上显示一些准备工作的进度,这可能需要一段时间(生成了多个画布元素,并且设置了一些设置).

I have got a vanilla Javascript that sets an img's src attribute to a data-uri. In the function assigned to the onload event, I try to show the progress of some preparations on the page that might take a while (multiple canvas elements are generated and a few settings are set).

这是应该呈现进度条的功能:

This is the function, that should render a progress bar:

let progress = document.querySelector('.progress');

function showProgress(message, percent) {
    console.log(message + ' (' + (percent * 100).toFixed(0) + '%)');
    progress.querySelector('.progress--message').innerHTML = message;
    progress.querySelector('.progress--bar-container--bar').style.width = (percent * 100).toFixed(0) + '%';
}

代码是这样运行的:

img.onload = function() {
    showProgress('Preparing image...' .1);

    // Some preparations...

    showProgress('Preparing tools...', .2);

    // etc...

    showProgress('Done...', 1);
}

控制台记录按预期工作,但是DOM元素的呈现停止直到该函数结束,并显示完成"消息.一切准备就绪后状态.

The console logging works as intended, but the rendering of the DOM elements stops until the end of the function and displays the "done" state after everything is ready.

onload 事件处理中是否存在任何渲染阻止,并且可以避免?还是我错过了什么?代码本身对结果没有任何影响.甚至该函数的第一行也确实具有这种奇怪的行为.

Is there any render-blocking in the onload event handling and can it be circumvented? Or am I missing something? The code itself does not have any effect on the outcome. Even the first line in the function does have this strange behaviour.

推荐答案

除非您进行后台Web Workers按摩(更复杂,尤其是在您所处的环境中),否则进度条的渲染 只能在脚本完全返回后才能发生;因此,在每个 showProgress 调用之后.现在,如何返回,渲染然后重新启动其余的?好吧,这就是0毫秒的 setTimeout 派上用场的地方.有了它,下面的方法应该起作用:

Unless you go with background Web Workers massaging (more complicated, espacially in your situation), the rendering of your progress bar can only occur after a complete return from your script; therefore, after each showProgress call. Now, how to return, render then restart for the remaining? Well, that's where a setTimeout of 0 millisecond comes handy. With it, the following should work:

img.onload = function() {
    showProgress('Preparing image...' .1);
    setTimeout(function() {
        // Some preparations...
        showProgress('Preparing tools...', .2);
        setTimeout(function() {
            // etc...
            showProgress('Done...', 1);
        }, 0);
    }, 0);
}

嵌套代码的另一种方法是一种递归调用-但每次调用都将在以下步骤开始之前完成-像这样的一系列步骤:

An alternative approach to nesting code would be a kind of recursive call - yet each call will complete before the following will start - on an array of steps, like this:

steps = [
  function() { // first step (img loading just completed so, show Preparing it right away)
      showProgress('Preparing image...', .1);
  },
  function() { // second step
      // Some preparations...
      showProgress('Preparing tools...', .2);
  }, // other steps...
  function() { // last step
      // Last things to do...
      showProgress('Done...', 1);
  }
];
// function that processes "steps" - array of at least 1 function - until empty
function displayAfterEachStep() {
    steps.shift()(); // Pull out the first step and run it
    if(steps.length > 0) // if there's still steps
         setTimeout(displayAfterEachStep, 0); // Recall the process after page rendering
}
img.onload = displayAfterEachStep;

这篇关于Javascript中的img onload-event时没有页面呈现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆