make .each()等待将元素转换为DataURL

时间:2017-08-31 07:25:38

标签: javascript jquery promise html2canvas

我使用html2canvas转换html2canvas,

我正在使用.each解析html,然后将元素传递给html2canvas。元素转换为DataURL后。我将它推送到数组content

$('.itinerary-section-detail').each(function( index, element ) { 
                 setTimeout(function() {
                   console.log(element);
                       html2canvas(element).then(function(canvas) {
                            element.appendChild(canvas);
                             elem  = canvas.toDataURL();
                              var item = {};
                              item["image"] = elem;
                              item["width"] = 595;
                              content.push(item);
                          }); 
                  }, 4000);
            });

但问题是时间因将元素转换为DataURL而异。这就是为什么元素的顺序是随机的。所以我需要等到一个元素转换为DataURL,然后将其推入content数组,然后从.each获得下一个元素。

请在这里建议我。尝试setTimeout,没有用。

2 个答案:

答案 0 :(得分:3)

您不能仅仅遍历异步元素,因为它们不会暂停循环。相反,您可以构造承诺数组并使用$.when。然后,一旦所有承诺解决,将调用您提供的回调:

var promises = $('.itinerary-section-detail').map(function(index, element) {
  console.log(element)
  return html2canvas(element).then(function(canvas) {
      element.appendChild(canvas)
      var elem = canvas.toDataURL()

      return {
        image: elem,
        width: 595
      }
    })
}).get()

$.when.apply(null, promises).then(function() {
  var content = [].slice.call(arguments)
  console.log(content)
})

答案 1 :(得分:1)

这显示了我在评论中所说的内容。我用超时和随机延迟来模拟异步。

在该示例中,IIFE仅用于跟踪private MapPoint _pt; public MapPoint pt { get { return _pt; } set { _pt = value; // here normal MapPoint class passed bs.DataSource = pt; bs.ResetBindings(false); // or true } } ,因为它会在异步回调中丢失(您还可以将异步调用包装在存储该值的函数中)

结果完成没有排序,但数组结果是。

index
var content = [];

$('div.kadd').each(function( index, element ) { 
    console.log('launching: ' + element.innerHTML);
    (function(i){ setTimeout(function() {
        console.log('finishing: ' + element.innerHTML);
        content[i] = element.innerHTML;
    }, (Math.random() * 100) + 1); })(index);
});

setTimeout(function() {
    console.log('result: ', content);
}, 1000);