angularjs $compile 对 iframe 上的 onload 事件进行错误处理
Posted
技术标签:
【中文标题】angularjs $compile 对 iframe 上的 onload 事件进行错误处理【英文标题】:angularjs $compile bugs the onload event on an iframe 【发布时间】:2015-11-18 08:30:17 【问题描述】:我正在尝试创建一个打印提供程序,它接收模板和范围并将其编译为 html,而不是在 body 标记中注入带有此 html 内容的 iframe,并在 iframe 上的 onload
事件上调用 print 以打印此内容内容。
代码如下所示:
myApp.provider('$print', function()
return
$get: function($document, $interpolate, $compile, $timeout)
var $print = ;
function printFrame(content)
var frameContent = '<!doctype html>' +
'<html>' +
'<body onload="window.print()">' +
content +
'</body>' +
'</html>';
// inject iframe into DOM
var iframe = document.createElement("IFRAME");
iframe.id = 'print-frame';
iframe.style.display = 'none';
var body = $document.find('body').eq(0);
body.append(iframe);
iframe = document.getElementById('print-frame');
// fill iframe with print content
var iframeContent = (iframe.contentWindow) ? iframe.contentWindow : (iframe.contentDocument.document) ? iframe.contentDocument.document : iframe.contentDocument;
iframeContent.document.open();
iframeContent.document.write(frameContent);
iframeContent.document.close();
;
$print.iframe1 = function(printOptions)
var printScope = printOptions.scope.$new();
var htmlToPrint = $interpolate(printOptions.template)(printScope);
printFrame(htmlToPrint);
$print.iframe2 = function(printOptions)
var printScope = printOptions.scope.$new();
$timeout(function()
var htmlToPrint = $compile(printOptions.template)(printScope);
printScope.$digest();
printFrame(htmlToPrint.html());
);
return $print;
);
我遇到的问题是,例如,当我使用 $interpolate
时,提供程序工作正常,iframe onload
事件等到图像和所有内容都加载后才调用打印,但是当我使用 @987654326 @,由于某种原因,iframe 的 onload
事件在图像加载之前触发。
我为这个例子创建了一个 JSFiddle,如果你禁用缓存,你可以看到在插值时,打印仅在加载大图像后调用,但在编译时,打印消息立即打开。
希望有人可以帮助我,在此先感谢丹尼尔!
http://jsfiddle.net/HB7LU/16737/
【问题讨论】:
【参考方案1】:htmlToPrint
确实有两个元素 h1
和另一个是 img
标签,但问题是当您从 iframe2
函数执行 htmlToPrint.html()
时,它只返回 SuperHero
,它没有'不返回 html 的其他部分。
为了解决这个问题,你可以使用一些 div 来包装你的模板,这样在对元素执行 .html()
时将返回正确的元素。
模板
template: '<div>'+
'<h1>printTitle</h1>'+
'<img style="width: 1000px" src="http://velocityagency.com/wp-content/uploads/2013/08/go.jpg"'>+'
'<div>',
此外,您需要在$timeout
函数中设置一些以毫秒为单位的少量超时,例如10
。
$timeout(function()
printFrame(htmlToPrint.html());
,10);
Working Fiddle
更新
如果我禁用了浏览器缓存,上述解决方案不起作用,我认为我们在在页面上呈现图像之前发送一个页面进行打印。
$print.iframe2 = function(printOptions, scope)
var printScope = printOptions.scope.$new();
var htmlToPrint = $compile(printOptions.template)(printScope);
angular.element(htmlToPrint.find('img').on('load', function()
$timeout(function()
console.log("Img loaded")
printFrame(htmlToPrint.html());
);
))
Updated Fiddle
【讨论】:
你说得对,我更新了我的 JSFiddle 但这并不能解决我遇到的问题,$compile 打印仍然会在图像加载之前打开 brwoser 打印模式,所以打印里面没有图片 @PacuraruDaniel 看看我的编辑..会解决你的问题..谢谢:) @PankajParkar 我认为超时 0 应该没问题(以便 $digest 完成)。 @PankajParkar 嘿伙计,我试过小提琴,但它对我做同样的事情,当我打开编译打印时,第一次没有图像,你可以看到如果你禁用缓存和刷新页面后打开 @DeblatonJean-Philippe nope..我已经试过了。我很惊讶这不起作用..这就是为什么我包含超时值..【参考方案2】:我发现了这个问题,问题是当我编译 html 时,图像开始下载并被浏览器缓存,当我将它们注入 iframe 时,iframe 上的 onload 事件认为它们已经下载,无需等待。
【讨论】:
以上是关于angularjs $compile 对 iframe 上的 onload 事件进行错误处理的主要内容,如果未能解决你的问题,请参考以下文章
Angularjs+Typescript 指令实现 $compile
angularJS DOM element() $compile()
AngularJS:使用 $compile 将 html 附加到网页
AngularJS:在包含带有 templateurl 的指令的 html 上使用 $compile
Angularjs:错误:[$compile:ctreq] 控制器“carousel”,指令“ngTransclude”需要,找不到