我在Liferay portlet中有一个Angular2应用程序。 Liferay tomcat与angular2应用程序在不同的域中。我正在尝试根据iframed应用程序的高度调整iframe的大小。我在Liferay的tomcat上使用帮助文件来做到这一点 - 基于答案Resizing an iframe based on content。
这是我到目前为止所得到的: 带有父应用程序的tomcat上的helper.html:
<html>
<!--
This page is on the same domain as the parent, so can
communicate with it to order the iframe window resizing
to fit the content
-->
<body onload="parentIframeResize()">
<script>
// Tell the parent iframe what height the iframe needs to be
function parentIframeResize()
{
var height = getParam('height');
// This works as our parent's parent is on our domain..
parent.parent.resizeIframe(height);
}
// Helper function, parse param from request string
function getParam( name )
{
name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
var regexS = "[\\?&]"+name+"=([^&#]*)";
var regex = new RegExp( regexS );
var results = regex.exec( window.location.href );
if( results == null )
return "";
else
return results[1];
}
</script>
</body>
</html>
使用iframe的portlet中的Jsp文件:
<iframe id="iframed-application"
src="${baseUrl}:${externalTomcatPort}/${applicationName}/iframe?baseUrl=${baseUrl}:${port}">
</iframe>
<script>
// Resize iframe to full height
function resizeIframe(height) {
document.getElementById('iframed-application').height = parseInt(height) + 10;
}
</script>
Angular2 app.component.html
<menu></menu>
<router-outlet></router-outlet>
<iframe id="helpframe" [src]='helperSource' height='0' width='0' frameborder='0'></iframe>
Angular2 app.component.ts
import {Component} from "@angular/core";
import {OnInit} from "@angular/core";
import {ContextService} from "./common/service/context.service";
import {DomSanitizer} from "@angular/platform-browser";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
helperSource;
constructor(private sanitizer: DomSanitizer, private context: ContextService) {
}
ngOnInit(): void {
let height = window.innerHeight;
if (height < 800) height = 800;
this.helperSource = this.sanitizer.bypassSecurityTrustResourceUrl(this.context.baseUrl + '/helper/helper.html' + '?height=' + height);
}
}
当调用ngOnInit时,模板尚未渲染,因此它总是将iframe高度设置为800px,但主要问题是不同的。如何在iframe中检测角度应用内容的resize事件?我试过用:
@HostListener('window:resize', ['$event'])
但它正在侦听整个窗口的大小调整,而不是iframe。
我的第二次尝试就像是:
let iframe: HTMLIFrameElement = <HTMLIFrameElement> document.getElementById('iframed-application');
let contentWindow: Window = iframe.contentWindow;
contentWindow.onresize = event => {
};
但它也失败了,因为document.getElementById返回null - 正如我从安全原因所理解的那样 - 跨域。
无论如何可以听取iframed应用程序的大小调整,或者还有其他方法吗?
答案 0 :(得分:1)
我们找到的唯一解决方案是将此绑定到正文上的onclick事件,例如:
str = "(((MILK AND SOYA) OR NUT) AND COCONUT)"
while not str.nil?
puts str = str.match(/\((.*)\)/).to_a.last
end # =>
((MILK AND SOYA) OR NUT) AND COCONUT
(MILK AND SOYA) OR NUT
MILK AND SOYA
答案 1 :(得分:1)
这是一个执行它的指令
import {Directive, ElementRef, OnInit, Renderer} from "@angular/core";
@Directive({
selector: "[iframeAutoHeight]"
})
export class IframeAutoHeightDirective implements OnInit {
private el: any;
private renderer: Renderer;
private prevHeight: number;
private sameCount: number;
constructor(_elementRef: ElementRef, _renderer: Renderer) {
this.el = _elementRef.nativeElement;
this.renderer = _renderer;
}
ngOnInit() {
const self = this;
if (this.el.tagName === "IFRAME") {
this.renderer.listen(this.el, "load", () => {
self.prevHeight = 0;
self.sameCount = 0;
setTimeout(() => {
self.setHeight();
}, 50);
});
}
}
setHeight() {
const self = this;
if (this.el.contentWindow.document.body.scrollHeight !== this.prevHeight) {
this.sameCount = 0;
this.prevHeight = this.el.contentWindow.document.body.scrollHeight;
this.renderer.setElementStyle(
self.el,
"height",
this.el.contentWindow.document.body.scrollHeight + "px"
);
setTimeout(() => {
self.setHeight();
}, 50);
} else {
this.sameCount++;
if (this.sameCount < 2) {
setTimeout(() => {
self.setHeight();
}, 50);
}
}
}
}
用法:
<iframe [src]="iframeUrl" iframeAutoHeight></iframe>