在網頁新舊版本交界期,IFrame
算是蠻常用的手法,在 Angular 4 (Angular 2) 的 SPA 頁面中,利用 IFrame
插入舊版網頁,使系統整體感一致。IFrame
的寬高大小又不能固定不變,太小會留下很多空白,太大會使內外頁都產生 Scrollbar。 本篇將介紹如何讓 IFrame
在 Angular 的 SPA 頁面中,隨著視窗自動調整大小。
IFrame 太小 如果只是把 IFrame
設定寬高 100%
實際上他不會真的套用百分比的設定,視窗大於 IFrame
時,就會空出空間。如下:
1 <iframe src ="https://blog.johnwu.cc/" width ="100%" height ="100%" > </iframe >
IFrame 太大 若把 IFrame
設定固定寬高,當視窗大於 IFrame
時,就會空出空間;視窗小於 IFrame
時,就會同時產生 IFrame
及瀏覽器的 Scrollbar。如下:
1 <iframe src ="https://blog.johnwu.cc/" width ="600px" height ="800px" > </iframe >
動態計算 比較好的方式是透過 Page Load 及 Window Resize 的事件,動態計算 IFrame
的寬高,讓 IFrame
隨著視窗大小自動改變。
此範例我是用 Component
包裝,也可以用 Directive
實現一樣的功能。
1. MyIFrameComponent my-iframe.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 import { Component , Input , ViewChild , ElementRef , HostListener } from "@angular/core" ;@Component ({ selector : "my-iframe" , templateUrl : "/app/my-iframe.component.html" , styles : ["iframe { margin-bottom: -4px; }" ] }) export class MyIFrameComponent { @Input () src : string ; @ViewChild ("frame" ) frameElement : ElementRef ; containerMinWidth : number = 0 ; containerMinHeight : number = 0 ; containerWidth : number = this .containerMinWidth ; containerHeight : number = this .containerMinHeight ; ngOnInit ( ) { this .onResize (window .innerWidth , window .innerHeight ); } @HostListener ("window:resize" , ["$event.target.innerWidth" , "$event.target.innerHeight" ]) onResize (width : number , height : number ): void { let top = this .frameElement .nativeElement .offsetTop ; let left = this .frameElement .nativeElement .offsetLeft ; this .containerWidth = Math .max (width - left, this .containerMinWidth ); this .containerHeight = Math .max (height - top, this .containerMinHeight ); } }
my-iframe.component.ts
1 2 3 4 5 6 7 8 9 10 <iframe #frame [src ]="src" [style.width.px ]="containerWidth" [style.height.px ]="containerHeight" height ="100%" width ="100%" frameborder ="0" marginheight ="0" marginwidth ="0" > </iframe >
2. 使用 MyIFrameComponent app.component.ts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 import { Component } from "@angular/core" ;import { DomSanitizer , SafeResourceUrl } from '@angular/platform-browser' ;@Component ({ selector : "my-app" , templateUrl : "/app/app.component.html" }) export class AppComponent { frameUrl : SafeResourceUrl ; constructor (private sanitizer: DomSanitizer ) { let url = "https://blog.johnwu.cc/" ; this .frameUrl = this .sanitizer .bypassSecurityTrustResourceUrl (url)); } }
app.component.html
1 2 3 4 5 6 7 8 9 10 11 <div class ="banner" > Banner </div > <div > <div class ="sidebar" > Sidebar </div > <div class ="content" > <my-iframe [src ]="frameUrl" > </my-iframe > </div > </div >
執行結果
程式碼下載 my-angular-iframe-auto-resize