做者:scott jehl翻譯:瘋狂的技術宅html
原文:https://www.filamentgroup.com...前端
未經許可嚴禁轉載程序員
注意:這篇文章描述了一種咱們仍須要測其試性能影響的實驗技術。 它可能最終會成爲一種有用的工具,也有可能成爲不被推薦的作法。 不管哪一種方式,它對咱們來講頗有吸引力!web
只要我一直工做在 Web 上,就須要一種簡單的 HTML 驅動方式,將另外一個文件的內容直接包含在頁面中。 例如,我常常但願向頁面添加額外的 HTML,或者嵌入 SVG 文件的內容,以便咱們能夠爲其設置動畫和樣式。 一般咱們經過使用 JavaScript 獲取文件並將其內容附加到特定元素,或者經過在服務器端去包含文件來實現這種嵌入,但在大多數狀況下,這些方法都不是咱們想要的。面試
本週我在思考如何用一些新的與 fetch
相關的標記模式來實現這一點,例如 rel="preload"
或 HTML import,但我老是得出的相同結論,即這些都不能使你方便地訪問所取得的文件的內容。 而後我想,假設瀏覽器容許我在父文檔中檢索 iframe
的內容,也許一箇舊的 iframe
多是一個很不錯的模式。 事實證實,它確定會的!ajax
下面是一個內聯(嵌入式)SVG 圖形。它是從外部文件 signal.svg
中加載的。segmentfault
要加載並嵌入 SVG 文件,我用了下面的標記:瀏覽器
<iframe src="signal.svg" onload="this.before((this.contentDocument.body || this.contentDocument).children[0]);this.remove()"></iframe>
儘管此標記以 iframe
開頭,但若是你使用開發人員工具檢查上面的圖形,將會看到 SVG 的圖標標記,就內嵌在 HTML DOM 中,並且找不到 iframe
元素。 這是由於代碼用 iframe
加載文件,而且在刪除 iframe以前,用 onload
事件在 HTML 中 iframe
的位置以前注入了 iframe
裏的內容。緩存
該方法也適用於 object
元素,不管如何它一般用於引用SVG,因此我認爲這特別好。 對於一個object
,src
屬性必須用 data
替代:安全
<object data="signal.svg" onload="this.before((this.contentDocument.body || this.contentDocument).children[0]);this.remove()"></object>
也許更有用......這是一個使用HTML而不是SVG的例子!
能夠用下面的標記加載:
<iframe src="/images/includespost/htmlexample.html" onload="this.before((this.contentDocument.body||this.contentDocument).children[0]);this.remove()"></iframe>
一個說明這一個:你可能已經注意到,標記片斷檢查 contentDocument.body
或僅檢查 contentDocument
。這是對 HTML 和 SVG 包含進行的規範化檢查。 這是必要的,由於即便 HTML 文件自己只包含一個段落元素,瀏覽器也會建立一個完整的 HTML 文檔來包裝該段落,幷包含 HTML 元素、head、body等。因此該片斷會試圖獲取 iframe
的 body
元素(若是存在),若是不存在,它將會用於整個文檔。
值得注意的是,若是你要導入包含多個元素的 HTML 文件,我建議將其所有包裝在 div 中,以使 iframe
標記可以簡單地查找 body
中的第一個子節點。
與咱們過去使用的其餘模式相比,這種模式有一些很明顯的好處:
iframe
的性質。iframe
的內容移動到父文檔中,即使失敗了,你仍會看到包含的內容。iframe
將內容導入頁面後會被刪除。 注意:你可能但願爲 iframe
指定 border:0;
甚至能夠在加載時安全地隱藏它(或許經過 onerror 事件再次顯示它?)。iframe
中的備選內容,但我認爲能夠經過調整 onload
處理中的 JS 來得到對 IE 的支持,由於它目前用的是 IE 不喜歡的語法。 稍微調整一下,我認爲 IE 支持是可能的。考慮其餘可能的用途頗有趣......也許你能夠引入 HTML 模塊及其相關的 CSS 連接。 或者在文檔或博客文章中嵌入推文或代碼。 它甚至可能用於異步加載和應用常規的 rel=stylesheet
連接,而且優先級較低,不然很難作到(注意:我沒有對這個想法進行太多的測試)。
使用 iframe
進行此模式的另外一個好處是, iframe
會在進入視口時得到延遲加載的能力。 這能夠用 load ="lazy"
屬性來實現,該屬性也適用於 img
元素。 代碼看起來是這樣:
<iframe src="signal.svg" loading="lazy" onload="this.before((this.contentDocument.body||this.contentDocument).children[0]);this.remove()"></iframe>
iframe
在 web 上很經常使用,可是在頁面中過分使用 iframe 可能會致使性能或內存消耗問題。 例如對頁面上全部圖標使用可能會太重,可是對於須要進行動畫和樣式化的特定圖標來講,它可能會很好用。 不過如今我只能作更多的測試。
還有可能存在XSS問題,但我不肯定這與其餘須要注意外部內容的狀況有什麼不一樣。 你仍須要作一般的安全檢查,而且最好將其看做是同域技術,儘管我也不肯定。
就目前而言,這種作法有但願成爲以前將另外一個文件直接包含在頁面中方法的改進。
咱們將會繼續測試這種模式,若是咱們發現了什麼有趣的內容,會很快發佈後續內容。 若是你有什麼反饋或想法,請隨時在Twitter(https://twitter.com/filamentg...)上與咱們聯繫。 謝謝閱讀!