6

我在尝试在 for 循环中实现 html2canvas 脚本时遇到了一些麻烦。

我正在编写一个 Javascript 函数,它使用数据数组来修改一组元素的样式,将容器 div 捕获为画布,将其转换为图像,将其附加到文档正文,然后继续下一个数组的索引。

我遇到麻烦的部分是在循环的最后:

html2canvas(document.getElementById("background"), {
    onrendered: function(canvas) {
        var imgdata = canvas.toDataURL("image/png");
        var obj = document.createElement("img");
        obj.src=imgdata;
        document.body.appendChild(obj);
    }
});

通过逐步浏览脚本,我发现它没有等待画布被渲染,然后继续进行 for 循环的下一次迭代,这导致我试图捕获的元素发生变化,但每个被渲染的图像看起来完全一样(作为数组中的最终索引)。

有没有办法在画布渲染时延迟脚本一秒钟?我尝试过使用setTimeout(),但似乎找不到任何其他延迟脚本的方法,我不熟悉这onrendered部分代码的工作原理。

如果我的解释不清楚,我会尽快准备一些合适的例子。

4

3 回答 3

16

您可能想了解异步工作流程(例如https://github.com/caolan/async

简而言之,试试这个:

var i = 0;
function nextStep(){
  i++;
  if(i >= 30) return;
  // some body
  html2canvas(...
    onrendered: function(canvas){
      // that img stuff
      nextStep();
    }
  }
}
nextStep();

那就是我们只想nextStep在 onrendered 完成时调用。

于 2013-04-29T11:58:55.200 回答
2

同步代码意味着代码中的每个语句一个接一个地执行。

异步代码则相反,它在主程序流程之外使用语句。

html2canvas异步工作,因此您的循环可能会完成,并在执行 html2canvas 代码之前变为 i..20

一种解决方案是这样的:

for (let i = 0; i < array.length; i++) {
  generateCanvas(i);
}

function generateCanvas(i){
  html2canvas(..
    // you can use i here
  )
}

通过将 html2canvas 代码包装在一个函数中,您可以确保“i”的值保持您的预期。

于 2018-02-28T17:15:15.813 回答
1

如果您正在使用 react,请尝试 async/await。

将您的 javascript 函数标记为异步。例子,

async printDocument(){
  let canvas = await html2canvas(printDiv)
  // canvas to image stuff
}

访问 https://medium.com/@patarkf/synchronize-your-asynchronous-code-using-javascripts-async-await-5f3fa5b1366d了解更多信息。

于 2019-04-02T01:15:01.737 回答