Javascript 画布无法生成循环中的所有图像

Javascript 画布无法生成循环中的所有图像,javascript,html,html5-canvas,Javascript,Html,Html5 Canvas,我使用一个循环来生成一些HTML表,它们不是太大,在循环中我执行了一些JS(我尝试了JQuery和JavaScript)来将表创建为图像。这只是一个由35个表组成的小循环,但大约三分之二的循环只返回空白图像。我想知道这是内存问题还是DOM不完整的问题,所以我将我的语句包装在一个$(document).ready()中,仍然是相同的问题。我在我的循环中使用了其中一个人,他们自己生成了很好的结果。控制台中没有错误。我一直在控制台中手动执行JQuery并检查生成 html2canvas($('#kim

我使用一个循环来生成一些HTML表,它们不是太大,在循环中我执行了一些JS(我尝试了JQuery和JavaScript)来将表创建为图像。这只是一个由35个表组成的小循环,但大约三分之二的循环只返回空白图像。我想知道这是内存问题还是DOM不完整的问题,所以我将我的语句包装在一个
$(document).ready()
中,仍然是相同的问题。我在我的循环中使用了其中一个人,他们自己生成了很好的结果。控制台中没有错误。我一直在控制台中手动执行JQuery并检查生成

html2canvas($('#kimberly-t'), {
    onrendered: function (canvas) {
        var data = canvas.toDataURL('image/png');
        $('#kimberly-t-canvas').html('<img src="'+data+'" alt="">');
        }
    });
html2canvas($('kimberly-t'){
onrendered:函数(画布){
var data=canvas.toDataURL('image/png');
$('#kimberly-t-canvas').html('';
}
});
对于每个人来说,他们都工作得很好,但有一个人就是不工作,随后从新的HTML表创建图像的每次尝试都失败了。我甚至不知道如何开始,因为没有错误

更新赏金


下面是一个例子来说明这个问题。您可以看到对div的前10个调用生成了一个映像。如果您取消注释JS的其余部分,它将生成空白画布或使浏览器崩溃。当浏览器没有崩溃时,我从PHP循环或控制台在本地计算机上也没有收到任何错误。

我通过一些技巧使其正常工作,下面是JSFIDLE:

其中的诀窍是,我在导出cavas图像时使用
100ms
延迟将它们存储在一个
base64图像
数组中,然后在
10s
延迟后显示它们

存储部件

setTimeout(function(index){

      html2canvas( $('#div'+index) , {
            onrendered: function(canvas) {
              var data = canvas.toDataURL('image/png');

              // Instead displauing images directly
              //$('#div'+index+'-canvas').html('<img src="' + data + '" alt="">');          
              // Storing images
              base64Images.push( {'index':index, 'data':data} );
            }
      });  
}, 100*i, i );
setTimeout(function(index){

    for( var i = 0; i < base64Images.length; i++){

        $('#div' +base64Images[i]['index']+ '-canvas').html(            
           '<img style="border: 5px solid red;" src="' +base64Images[i]['data']+ '" alt="">'
        );
    }
}, 10000 ); 
setTimeout(函数(索引){
html2canvas($('div'+索引){
onrendered:函数(画布){
var data=canvas.toDataURL('image/png');
//而是直接显示图像
//$('#div'+index+'-canvas').html('');
//存储图像
push({'index':index,'data':data});
}
});  
},100*i,i);
显示部分

setTimeout(function(index){

      html2canvas( $('#div'+index) , {
            onrendered: function(canvas) {
              var data = canvas.toDataURL('image/png');

              // Instead displauing images directly
              //$('#div'+index+'-canvas').html('<img src="' + data + '" alt="">');          
              // Storing images
              base64Images.push( {'index':index, 'data':data} );
            }
      });  
}, 100*i, i );
setTimeout(function(index){

    for( var i = 0; i < base64Images.length; i++){

        $('#div' +base64Images[i]['index']+ '-canvas').html(            
           '<img style="border: 5px solid red;" src="' +base64Images[i]['data']+ '" alt="">'
        );
    }
}, 10000 ); 
setTimeout(函数(索引){
对于(变量i=0;i
这不是正常工作的
其他浏览器
,如果我更改100ms延迟以降低它在
chrome
下停止工作,它也会崩溃,如果我改为直接从第26个表格开始显示图像,则图像不会像Jonny的初始示例中那样显示,因此,让我们说,对于这个浏览器和PC,此参数仅适用于这个表格数量和其中的数据量

我知道这不是100%的正常解决方案,但至少是一些

我对这个问题的看法是,它与某种浏览器js堆栈大小限制有关,这些限制以某种方式负责处理
canvas
部分。在这个JSFIDLE中还有一个注意事项:当我阅读同一个html表并直接将其正常显示30倍时,它正在以64倍显示evan,但在64倍显示之后,它再次开始不显示图像,我还在google中搜索了一些关于此领域限制的文档,但没有用


此解决方案的主要思想是一部分一部分地显示这样的图像,以避免浏览器“某些”缓存泄漏

实际上,我无法在Chrome(stable&Canary)或Firefox上重现您的错误

我认为你的代码没有问题,而且在一个网站中使用这么多画布节点是不明智的。我的笔记本电脑有16GB的RAM和一个奇特的CPU,因此这里没有问题,但是任何一台普通的计算机都可能遇到你描述的问题

另一方面:您可能想开始使用for循环来执行我在您的小提琴版本中看到的重复动作


for(var i=1;i看起来像是您的DOM操作影响了html2canvas代码(堆栈问题、干扰事件、竞争条件,我不知道)

检查(这不是一个非常漂亮的解决方案,但它可以呈现39个表,没有测试更多)

在这里,我一次查看一个表,并使用html2canvas进行渲染,并将生成的dataurl保存到帮助器数组中,然后在处理完所有表后,显示图像:

  var process_div = function(index) {
    var id = divs_to_process[index];
    //console.log('process_div ' + id);
    html2canvas($(id), {
      onrendered: function(canvas) {
        var data = canvas.toDataURL('image/png');
        //$(id + '-canvas').html('<img src="' + data + '" alt="">');
        imgs.push([id + '-canvas', data]);
        data = undefined;
        setTimeout(process_div_wrapper, 0);
      }
    });
  };
  var i = 0;
  var process_div_wrapper = function() {
    if (i < divs_to_process.length) {
      var id = divs_to_process[i];
      process_div(i);
      ++i;
    } else {
      for (var j = 0; j < imgs.length; ++j) {
        var e = imgs[j];
        //console.log('show img ' + e[0]);
        $(e[0]).html('<img src="' + e[1] + '" alt="">');
      }
      alert('done');
    }
  };
  setTimeout(process_div_wrapper, 1);
var进程\u div=函数(索引){
var id=divs_to_进程[索引];
//console.log('process\u div'+id);
html2canvas($(id){
onrendered:函数(画布){
var data=canvas.toDataURL('image/png');
//$(id+'-canvas').html(“”);
push([id+'-canvas',data]);
数据=未定义;
setTimeout(进程分区包装,0);
}
});
};
var i=0;
var process\u div\u wrapper=函数(){
if(i
我怀疑存在CORS问题。()请检查您的所有图像是否都来自您的域。@GameAlchest我尝试创建的所有图像都是我自己网页中的HTML。这是否仍然会导致问题?您是否在所有浏览器中都观察到这种行为?是否为“空白图像”在
src
中是否包含空白图像?很抱歉,我找不到问题的根源。我注意到在
FF
浏览器中,生成的图像数量是
22
而不是
10
,这意味着它与客户端内存或类似的东西有关,我还创建了这个JSFIDLE:在这里我添加了延迟
100ms
在每个
htmltocanvas
循环调用之间,但无论如何它停止到d