這篇文章主要介紹了簡單介紹HTML中的文件導入,包括加載jQuery、導入後的執行順序等知識點,需要的朋友可以參考下
Template、Shadow DOM及Custom Elements 讓你創建UI元件比以前更容易了。但是像HTML、CSS、JavaScript這樣的資源仍然需要一個個去加載,這是很沒效率的。
刪除重複依賴也不簡單。例如,現在載入jQuery UI或Bootstrap就需要為JavaScript、CSS及Web Fonts新增單獨的標籤。如果你的Web 元件應用了多重的依賴,那事情就變得更複雜。
HTML 導入讓你以一個合併的HTML檔案來載入這些資源。
使用HTML導入
為載入一個HTML文件,你需要增加一個link標籤,其rel屬性為import,herf屬性是HTML文件的路徑。例如,如果你想把component.html載入到index.html:
index.html
#XML/HTML Code複製內容到剪貼板
<link rel="import" href="component.html" >
你可以往HTML導入文件(譯者註:本文將“ the imported HTML”翻譯為“HTML導入文件”,將“the original HTML”翻譯為“HTML主文件” 。
component.html
XML/HTML Code複製內容到剪貼簿
<link rel="stylesheet" href="css/style.css"> <script src="js/script.js"></script>
doctype、html、 head、 body這些標籤是不需要的。 HTML 匯入會立即載入要匯入的文檔,解析文件中的資源,如果有腳本的話也會立即執行它們。
執行順序
瀏覽器解析HTML文件的方式是線性的,這就是說HTML頂部的script會比底部先執行。而且,瀏覽器通常會等到JavaScript程式碼執行完畢後,才會接著解析後面的程式碼。
為了不讓script 妨礙HTML的渲染,你可以在標籤中加入async或defer屬性(或者你也可以將script 標籤放到頁面的底部)。 defer 屬性會延遲腳本的執行,直到全部頁面解析完畢。 async 屬性讓瀏覽器非同步地執行腳本,而不會妨礙HTML的渲染。那麼,HTML 導入是怎麼運作的呢?
HTML匯入檔案中的腳本就跟含有defer屬性一樣。例如在下面的範例中,index.html會先執行script1.js和script2.js ,然後再執行script3.js。
index.html
XML/HTML Code#複製內容到剪貼簿
<link rel="import" href="component.html"> // 1. <title>Import Example</title> <script src="script3.js"></script> // 4.
#component.html
XML/HTML Code複製內容到剪貼簿
<script src="js/script1.js"></script> // 2. <script src="js/script2.js"></script> // 3.
1.在index.html 中載入component.html並等待執行
2.執行component.html中的script1.js
3.執行完script1.js後執行component.html中的script2 .js
4.執行完script2.js繼而執行index.html中的script3.js
注意,如果給link[rel="import"]加上async屬性,HTML導入會把它當作含有async屬性的腳本來對待。它不會等待HTML匯入檔案的執行和加載,這意味著HTML 匯入不會妨礙HTML主檔案的渲染。這也為提升網站效能帶來了可能,除非有其他的腳本依賴HTML匯入檔案的執行。
跨網域導入
從根本上來說,HTML導入是不能從其他的網域導入資源的。
例如,你不能從http://webcomponents.org/向 http://example.com/ 匯入HTML 檔案。為了繞過這個限制,可以使用CORS(跨域資源共享)。想了解CORS,請看這篇文章。
HTML匯入檔案中的window和document物件
前面我曾經提過在匯入HTML檔案的時候裡面的腳本是會被執行的,但這並不代表HTML匯入檔案中的標籤也會被瀏覽器渲染。你需要寫一些JavaScript程式碼來幫忙。
當在HTML導入檔案中使用JavaScript時,有一點要提防的是,HTML導入檔案中的document物件實際上指的是HTML主檔案中的document物件。以前面的程式碼為例,index.html和 component.html 的document都是指index.html的document物件。怎麼才能使用HTML導入文件中的document 呢?借助link中的import 屬性。
index.html
XML/HTML Code#複製內容到剪貼簿
var link = document.querySelector('link[rel="import"]'); link.addEventListener('load', function(e) { var importedDoc = link.import; // importedDoc points to the document under component.html });
為了取得component. html中的document 對象,要使用document.currentScript.ownerDocument.
#component.html
##XML/HTML Code複製內容到剪貼簿
var mainDoc = document.currentScript.ownerDocument; // mainDoc points to the document under component.html
如果你在用webcomponents.js,那么就用document._currentScript来代替document.currentScript。下划线用于填充currentScript属性,因为并不是所有的浏览器都支持这个属性。
component.html
XML/HTML Code复制内容到剪贴板
var mainDoc = document._currentScript.ownerDocument; // mainDoc points to the document under component.html
通过在脚本开头添加下面的代码,你就可以轻松地访问component.html中的document对象,而不用管浏览器是不是支持HTML导入。
document._currentScript = document._currentScript || document.currentScript;
性能方面的考虑
使用HTML 导入的一个好处是能够将资源组织起来,但是也意味着在加载这些资源的时候,由于使用了一些额外的HTML文件而让头部变得过大。有几点是需要考虑的:
解析依赖
假如HTML主文件要依赖多个导入文件,而且导入文件中含有相同的库,这时会怎样呢?例如,你要从导入文件中加载jQuery,如果每个导入文件都含有加载jQuery的script标签,那么jQuery就会被加载两次,并且也会被执行两次。
index.html
XML/HTML Code复制内容到剪贴板
<link rel="import" href="component1.html"> <link rel="import" href="component2.html">
component1.html
XML/HTML Code复制内容到剪贴板
<script src="js/jquery.js"></script>
component2.html
HTML导入自动帮你解决了这个问题。
与加载两次script标签的做法不同,HTML 导入对已经加载过的HTML文件不再进行加载和执行。以前面的代码为例,通过将加载jQuery的script标签打包成一个HTML导入文件,这样jQuery就只被加载和执行一次了。
但这还有一个问题:我们增加了一个要加载的文件。怎么处理数目膨胀的文件呢?幸运的是,我们有一个叫vulcanize的工具来解决这个问题。
合并网络请求
Vulcanize 能将多个HTML文件合并成一个文件,从而减少了网络连接数。你可以借助npm安装它,并且用命令行来使用它。你可能也在用 grunt和gulp 托管一些任务,这样的话你可以把vulcanize作为构建过程的一部分。
为了解析依赖以及合并index.html中的导入文件,使用如下命令:
复制代码
代码如下:
$ vulcanize -o vulcanized.html index.html
通过执行这个命令,index.html中的依赖会被解析,并且会产生一个合并的HTML文件,称作 vulcanized.html。学习更多有关vulcanize的知识,请看这儿。
注意:http2的服务器推送功能被考虑用于以后消除文件的连结与合并。
把Template、Shadow DOM、自定义元素跟HTML导入结合起来
让我们对这个文章系列的代码使用HTML导入。你之前可能没有看过这些文章,我先解释一下:Template可以让你用声明的方式定义你的自定义元素的内容。Shadow DOM可以让一个元素的style、ID、class只作用到其本身。自定义元素可以让你自定义HTML标签。通过把这些跟HTML导入结合起来,你自定义的web 组件会变得模块化,具有复用性。任何人添加一个Link标签就可以使用它。
x-component.html
XML/HTML Code复制内容到剪贴板
<template id="template"> <style> ... </style> <p id="container"> <img src="http://webcomponents.org/img/logo.svg"> <content select="h1"></content> </p> </template> <script> // This element will be registered to index.html // Because `document` here means the one in index.html var XComponent = document.registerElement('x-component', { prototype: Object.create(HTMLElement.prototype, { createdCallback: { value: function() { var root = this.createShadowRoot(); var template = document.querySelector('#template'); var clone = document.importNode(template.content, true); root.appendChild(clone); } } }) }); </script>
index.html
XML/HTML Code复制内容到剪贴板
... <link rel="import" href="x-component.html"> </head> <body> <x-component> <h1>This is Custom Element</h1> </x-component> ...
注意,因为x-component.html 中的document 对象跟index.html的一样,你没必要再写一些棘手的代码,它会自动为你注册。
支持的浏览器
Chrome 和 Opera提供对HTML导入的支持,Firefox要在2014年12月后才支持(Mozilla表示Firefox不计划在近期提供对HTML导入的支持,声称需要首先了解ES6的模块是怎样实现的)。
你可以去chromestatus.com或caniuse.com查询浏览器是否支持HTML导入。想要在其他浏览器上使用HTML导入,可以用webcomponents.js(原名platform.js)。
相关推荐:
以上是簡單介紹HTML5中的檔案匯入的詳細內容。更多資訊請關注PHP中文網其他相關文章!