2017-08-31 51 views
1

化妝。每()等待我使用<code>html2canvas</code>轉換html2canvas轉換元件,以DataURL

我解析使用.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,沒有工作。

+0

似乎'.toDataURL()'是同步的[toDataURL作用異步](https://stackoverflow.com/questions/30811253/canvas-image-cropper-canvas-todataurl -is-acting-asynchronously-do-this-retur) –

+0

你可以做的是爲每個異步啓動('html2canvas'我猜)遞增一個變量並將其傳遞給回調函數,以便元素知道哪個索引它必須放在數組 – Kaddath

+0

不試圖說出來,我實際上是這樣說的;)添加了一個例子 – Kaddath

回答

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) 
}) 
+0

謝謝你的回答,怎麼可以我將返回的對象推到'$ .when'中的'content'數組中?對不起,這個問題,我不知道這一切 –

+0

你可以請更新你的答案嗎? –

+0

檢查更新的答案 – dfsq

1

這顯示了我在評論中所說的內容。我用超時和隨機延遲來模擬異步。

在這個例子中,IIFE僅用於跟蹤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);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<div class="kadd">A</div> 
 
<div class="kadd">B</div> 
 
<div class="kadd">C</div> 
 
<div class="kadd">D</div> 
 
<div class="kadd">E</div> 
 
<div class="kadd">F</div> 
 
<div class="kadd">G</div>

+0

謝謝你的回答,我不能添加'setTimeout()',因爲可能有太多元素。這是一個函數,我有更多的相同,所以需要做同樣的所有和使用'setTimeout'將需要太多時間 –

+0

setTimeout只是一個異步的例子,在你的情況下,你只是將它替換爲'html2canvas( )'。確實,我的示例缺少代碼以知道所有異步調用都已結束(可以用承諾完成,而是使用全局超時代替)。順便說一句,承諾本身並不能保證結果會按順序到達,這是我答案的目的,它只說明瞭有序的結果 – Kaddath