2013-08-02 2 views
0

iframe이 포함 된 웹 페이지가 있고 iframe에는 최대 1,000 개의 캔버스 요소가 포함 된 테이블이 있습니다. 캔버스 요소는 부모 페이지에서 호출되는 iframe에 정의 된 함수로 채워집니다. 이 함수는 각 캔버스를 반복하여 부모 페이지의 숨겨진 범위에 포함 된 base64 데이터 URI로 채 웁니다. 비슷한 문제에 관한 몇 가지 다른 Stackoverflow 게시물을 읽었지만 가장 일반적으로 사용되는 제안 (onload 사용)을 이미 시도했지만 작동하지 않는 것 같습니다. 나는 html/javascript에 상당히 신선하다. 그래서 나는 최선의 방법으로 일을하고 있는지 의심 스럽다. 누군가가 나를 처음으로로드 할 때 모든 캔버스 요소가 base64 데이터로 채워질 수 있도록 가이드 할 수 있기를 바랬습니다. 따라서 미리보기 이미지를 가져 오기 위해 여러 번 새로 고칠 필요가 없습니까? 여기에 몇 가지 코드가 있습니다, 그것은 내 html 페이지에서 아주 잘린 코드입니다. 전체 페이지를 붙여 넣기 만해도 너무 잘 감당할 수 있습니다. 여기 내가 필수적인 배우라고 믿는 것이있다.내 캔버스가 새로 고침 만하는 이유는 무엇입니까?

캔버스를 채우는 내 함수 내 온로드 호출이 iframe을 포함하는 메인 페이지에 - 여기

<body onload="document.getElementById('framePage').contentWindow.fillCans();"> 

이있는 framePage은 iframe 내에 포함 된 fillCans() 함수 (I 아마 이것을 기본 HTML 페이지로 옮겨야하지만, 지금까지는 스크립트가 어떻게 진화 했는가? 하하). pgCnt 요소는 "카운터"숫자를 포함합니다. 반복 할 요소의 수를 정의합니다. var c가 할당되면 "can"+ i 요소가 캔버스입니다. var에이 imgsrc가 할당되면, "범위"+ 내가 요소가 기본 64 데이터 URI를 포함하는 상위 페이지에 숨겨진 스팬 요소 -

function fillCans() { 
    var cnt = document.getElementById("pgCnt").innerHTML; 
    var cnt = cnt.split("-"); 
    var cnt1 = cnt[0]; 
    var cnt2 = cnt[1]; 
    for (var i=cnt1; i <= cnt2; i++) { 
     var targ = "span"+i 
     var c = document.getElementById("can"+i); 
     var ctx = c.getContext("2d"); 
     ctx.fillStyle="#FFFFFF"; 
     ctx.fillRect(0,0,128,128); 
     var image = new Image(); 
     var imgSrc = parent.document.getElementById("span"+i).innerHTML; 
     imgSrc = imgSrc.split("*"); 
     image.src = imgSrc[0]; 
     ctx.drawImage(image,0,0); 
    } 

내가 말했듯이,이 좋은로드가, 불을 지르고는 오류를보고합니다 , 그러나 모든 캔버스는 축소판없이 흰색입니다. 새로 고침을 몇 번하면 모두 마침내로드됩니다. 나는 이미지 데이터가 비동기 적으로로드되었다는 것을 읽었지만 그것이 의미하는 바를 확신 할 수는 없다. 나는 그것이 onload가 실행하는 규칙에 의해 작동하지 않는다는 것을 의미한다고 생각한다. 어쨌든 언제나처럼 모든 stackoverflow 커뮤니티에 감사드립니다. 이러한 썸네일을 첫 번째 페이지로드에서 성공적으로로드하는 방법을 아는 것이 좋습니다.

@ Sebastian의 훌륭한 제안을 통해 필자는 JavaScript 기능을 제대로 구현할 수있었습니다. 나는 새로운 기능을 붙이고있다. 누구나 비슷한 문제가 생기면 지금 작동합니다. 이미지를 그린 함수에 onload 호출을 구현 한 다음 IIFE for 루프에서 활용하여 각 축소판이 올바르게 반복 된 데이터로 그려지도록했습니다.

function fillCans() { 
var cnt = document.getElementById("pgCnt").innerHTML; 
var cnt = cnt.split("-"); 
var cnt1 = cnt[0]; 
var cnt2 = cnt[1]; 
for (var i=cnt1; i <= cnt2; i++) { 
    (function(iterable){ 
     var c = document.getElementById("can"+iterable); 
     var ctx = c.getContext("2d"); 
     ctx.fillStyle="#FFFFFF"; 
     ctx.fillRect(0,0,128,128); 
     var image = new Image(); 
     var imgSrc = parent.document.getElementById("span"+iterable).innerHTML; 
     imgSrc = imgSrc.split("*"); 

     image.onload = function() { 
      ctx.drawImage(image, 0, 0); 
     }; 
     image.src = imgSrc[0]; 
    })(i); 
} 
} 
+0

제발 ... 질문의 내용을 줄일 수 있습니까? –

+0

@MESSIAH 죄송합니다. MESSIAH, 내 질문에 답할 수없는 몇 가지 정보를 생략하면 내 코드 문제를 해결하기 위해 어디서부터 시작해야할지 모르겠습니다. – 0xhughes

답변

2

맞아요, 문제는 이미지를 그리기 전에 먼저로드해야한다는 것입니다. 귀하의 경우 image에서 는 소스 속성의 할당 및 브라우저가 이미 가지고있는 drawImage 호출에 나중에 브라우저에서 이미지 URL을 캐시하고있는 통화 사이 그러나

ctx.drawImage(image,0,0); 

를 호출 할 때로드되지 않습니다 캐시에서 이미지를 검색했습니다.

그것은 어떤 경우에 작동하려면, 당신은 부하에 이미지를 기다릴 필요 :

image.onload = function() { 
    ctx.drawImage(image, 0, 0); 
    }; 
    image.src = imgSrc[0]; 

먼저 콜백을 등록하고 src을 설정해야합니다.

HTML Canvas DrawImage Tutorial

+0

@Sebastian에 대한 정보를 제공해 주셔서 감사합니다. 올바른 순서로 편집 된 두 줄의 수정 된 스크립트를 실행했습니다. 내 테스트 세트에는 테이블에 나타나는 7 개의 이미지가 있습니다. 마지막 이미지 만 나타나지만 올바른 (첫 번째) 페이지로드시에 나타납니다! 그러나 새로 고침을 누르면 다른 이미지가로드되지 않습니다. 이 함수가 필자의 반복 함수에 상주하는 콜백 함수와 관련이 있다는 느낌이 든다. – 0xhughes

+0

조금 더 연구를 해본 결과, 새로운 문제는 클로저와 범위 지정 및 기타 등락에 더 가까운 것이라고 생각합니다. 그러나 이미지가 첫 번째 페이지로드에 성공적으로로드되었으므로 다음 버그를 파악해야합니다. 도움을 다시 주셔서 감사합니다! – 0xhughes

+0

@ 0xhughes : 코드는 루프에서 작동하지 않습니다. 왜냐하면'image'는 콜백이 실행될 때 마지막 값이 할당 될 것이기 때문입니다 (모두 같은 클로져 변수를 사용합니다). 이 문제를 해결하려면 루프 본문에 "IIFE"를 사용하고 모든 이미지를 올바르게로드 할 수 있도록 각 호출마다 새로운 변수를 얻습니다. – Sebastian

관련 문제