2014-06-23 1 views
0

jsPDF를 사용하여 html을 pdf로 변환하려고합니다. 내 코드는 다음과 같습니다.각 선택기 JQuery 후에 발생하는 콜백을 추가하는 방법?

var doc = new jsPDF(); 
$(document).ready(function() 
{ 
    $("#runpdf").click(function(event) 
    { 
    $(".page").each(function(){ 


     html2canvas($(this), 
     { 
      logging:true, 
      profile:true, 
      allowTaint:true, 
      letterRendering: true, 
      onrendered:function(canvas) 
      { 
       var imageData = canvas.toDataURL("image/jpeg");  
       doc.addImage(imageData, 'JPEG', 0, 0, 200, 200); 

      } 
     }); 

    }); 
    doc.save('test.pdf'); 
    }); 
}); 

이것은 이미지가있는 pdf를 렌더링하는 것이지만 빈 페이지를 제공합니다. 분명히 이것은 onrendered이 비동기이기 때문에 완료되기 전에 doc.save이 실행되어 onrendered 함수가 이미지를 추가하기 전에 빈 페이지를 제공하기 때문입니다. 그렇다면 각 함수 또는 유사한 함수에 doc.save이 실행될 때까지 $(".page")의 모든 인스턴스를 반복 할 때까지 콜백을 작성할 수 있습니까?
고마워요!

+0

관련 질문 : HTTP : // 2439519/var-not-affected-outside-of-function – jfriend00

답변

1

마지막 걸린 시간을 추적하고 doc.save()으로 전화해야합니다. 여기에 doc.save()onrendered 함수에 넣는 구현이 있습니다. 차라리 콜백을 호출하고 콜백에 doc.save()을 넣을 수 있습니다. 여기에 일반적인 생각이다 : 또한

var doc = new jsPDF(); 
$(document).ready(function() { 
    $("#runpdf").click(function (event) { 
     var pages = $(".page"); 
     // initialize count of how many left to go 
     var remaining = pages.length; 
     pages.each(function() { 
      html2canvas($(this), { 
       logging: true, 
       profile: true, 
       allowTaint: true, 
       letterRendering: true, 
       onrendered: function (canvas) { 
        var imageData = canvas.toDataURL("image/jpeg"); 
        doc.addImage(imageData, 'JPEG', 0, 0, 200, 200); 
        --remaining; 
        // if all are done, the call save 
        if (remaining === 0) { 
         doc.save('test.pdf'); 
        } 
       } 
      }); 

     }); 

    }); 
}); 

, 난 당신이 #runpdf 버튼을 다시 클릭하면이 작동하지 않습니다 생각한다. doc의 초기화를 클릭 핸들러로 옮길 수 있습니다.

+0

예! 정말 고맙습니다! 이것은 내가 필요한 것입니다. 감사. – yodofizzy

+0

@yodofizzy jQuery를 사용하여 다른 답변을 수락하십시오'$ .Deferred'는 실제로 가장 좋은 솔루션이며 프로세스에서 매우 강력한 기술을 배우게됩니다. – Alnitak

+0

예! 정말 고맙습니다! 이것은 내가 필요한 것입니다. 감사. 하하 나는이 자바 스크립트와 jquery와 callbacks (자바에 익숙하지만 기본 프로그래밍)와 물건에 익숙하다. 그래서 나는 대답을 가정 할 때 어딘가에 숨겨져있는 오래된 포럼 스레드를 통해 검색하려고했다. 튜토리얼 및 문서화가 필요하며, 이제는 간단한 카운터 및 if 문을 사용하여 필요한 작업을 쉽게 수행 할 수 있다는 사실을 깨닫게되면 정말 바보가됩니다. 다시 한번 감사드립니다. – yodofizzy

3

jQuery의 Promise 구현 인 jQuery.Deferred의 완벽한 사용 사례입니다.

요약하면 html2canvas 작업마다 지연된 개체를 만든 다음 onrendered 콜백 호출 deferred.resolve()에서 지연 개체를 만듭니다. 그런 다음 루프 다음에 모든 지연 오브젝트를 인수로 사용하여 $.when을 호출하십시오. Deferreds가 모두 해결되면 $.when이 처리되고 doc.save에 대한 호출이 포함 된 $.then에 대한 콜백 함수가 실행됩니다.

이 코드를 테스트하지 않은,하지만 더 또는 덜 정확해야 (나는 // ★★★에 추가 된 코드를 표시 한) :

var doc = new jsPDF(); 

$(document).ready(function() { 
    $("#runpdf").click(function(event) { 
    var deferreds = $(".page").map(function() { 
     var dfd = $.Deferred(); // ★★★ create a new Deferred 

     html2canvas($(this), { 
     logging: true, 
     profile: true, 
     allowTaint: true, 
     letterRendering: true, 

     onrendered: function(canvas) { 
      var imageData = canvas.toDataURL("image/jpeg");  
      doc.addImage(imageData, 'JPEG', 0, 0, 200, 200); 
      dfd.resolve(); // ★★★ resolved this Deferred 
     } 
    ); 

     return dfd.promise(); // ★★★ return a promise to be added to the array 
          // ★★★ that `$.map` returns 
    }); 

    // ★★★ Use $.when to execute the `then` callback only when all of the 
    // ★★★ Deferreds are resolved. Note: $.when.apply($, arr) is 
    // ★★★ equivalent to $.when(arr[0], arr[1], ...) 
    $.when.apply($, deferreds.get()).then(function() { 
     doc.save('test.pdf'); 
    } 
    }); 
}); 
같은 포스터에서
+2

좋은 대답이지만'.each/push' 대신'.map'을 사용하여 지연 배열을 만드는 것을 고려해보십시오. – Alnitak

+1

오, 좋은 전화, 알 니탁. 배열은 나에게 약간 냄새가 나는 것처럼 보였지만, 나는 그것을 고칠 수있는 간단한 방법을 생각할 수 없었다. –

+1

배열은 냄새 나는 것이 아니라 올바른 접근 방법입니다. 코드 냄새는'.map' 대신'.each'와'push'를 사용합니다. 'var deferreds = $ ('. page'). map (....). get()'. – Alnitak

관련 문제