做者: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...)上与咱们联系。 谢谢阅读!