Nhập HTML

Thêm cho web

Tại sao cần nhập?

Hãy nghĩ về cách bạn tải các loại tài nguyên khác nhau trên web. Đối với JS, chúng ta có <script src>. Đối với CSS, bạn có thể sử dụng <link rel="stylesheet">. Đối với hình ảnh, đó là <img>. Video có <video>. Âm thanh, <audio>… Vào thẳng trọng tâm! Phần lớn nội dung trên web có cách tự tải đơn giản và mang tính khai báo. Nhưng không phải như vậy đối với HTML. Bạn có thể chọn những cách sau đây:

  1. <iframe> – đã thử và đúng nhưng nặng. Nội dung của iframe hoàn toàn nằm trong ngữ cảnh riêng biệt với trang của bạn. Mặc dù đây chủ yếu là một tính năng tuyệt vời, nhưng nó cũng tạo ra thêm nhiều thách thức (rất khó để thu nhỏ kích thước khung cho nội dung, cực kỳ khó khăn khi viết tập lệnh vào/ra, gần như không thể tạo kiểu).
  2. AJAXTôi thích xhr.responseType="document", nhưng bạn đang nói rằng tôi cần JS để tải HTML? Có vẻ như không đúng.
  3. CrazyHacks™ – được nhúng trong chuỗi, ẩn dưới dạng nhận xét (ví dụ: <script type="text/html">). Thật kinh tởm!

Bạn thấy điều trớ trêu? Nội dung cơ bản nhất của web (HTML) đòi hỏi nhiều công sức nhất để xử lý. Rất may, Thành phần web sẽ giúp chúng ta quay lại đúng hướng.

Bắt đầu

HTML Imports (Tệp nhập HTML), một phần của nhóm truyền Web Components (Thành phần web), là một cách để đưa tài liệu HTML vào các tài liệu HTML khác. Bạn cũng không bị giới hạn ở mã đánh dấu. Dữ liệu nhập cũng có thể bao gồm CSS, JavaScript hoặc bất kỳ nội dung nào khác mà tệp .html có thể chứa. Nói cách khác, điều này làm cho việc nhập một công cụ tuyệt vời để tải HTML/CSS/JS có liên quan.

Khái niệm cơ bản

Bao gồm một mục nhập trên trang của bạn bằng cách khai báo <link rel="import">:

<head>
    <link rel="import" href="/path/to/imports/stuff.html">
</head>

URL của mục nhập được gọi là vị trí nhập. Để tải nội dung từ một miền khác, vị trí nhập cần bật CORS:

<!-- Resources on other origins must be CORS-enabled. -->
<link rel="import" href="http://example.com/elements.html">

Phát hiện và hỗ trợ tính năng

Để phát hiện khả năng hỗ trợ, hãy kiểm tra xem .import có tồn tại trên phần tử <link> hay không:

function supportsImports() {
    return 'import' in document.createElement('link');
}

if (supportsImports()) {
    // Good to go!
} else {
    // Use other libraries/require systems to load files.
}

Tính năng hỗ trợ trình duyệt vẫn đang trong giai đoạn đầu. Chrome 31 là trình duyệt đầu tiên triển khai nhưng các nhà cung cấp trình duyệt khác vẫn đang chờ xem các Mô-đun ES hoạt động như thế nào. Tuy nhiên, đối với các trình duyệt khác, webcomponents.js polyfill hoạt động rất tốt cho đến khi mọi thứ được hỗ trợ rộng rãi.

Gói tài nguyên

Thao tác nhập đưa ra quy ước nhóm HTML/CSS/JS (thậm chí cả các mục Nhập HTML khác) vào một sản phẩm. Đây là một tính năng nội tại nhưng rất mạnh mẽ. Nếu bạn đang tạo một giao diện, thư viện hoặc chỉ muốn phân đoạn ứng dụng thành các phần hợp lý, thì việc cung cấp cho người dùng một URL duy nhất là điều cần thiết. Bạn thậm chí có thể phân phối toàn bộ ứng dụng thông qua lệnh nhập. Hãy suy nghĩ về điều đó trong giây lát.

Một ví dụ thực tế là Bootstrap. Bootstrap bao gồm các tệp riêng lẻ (bootstrap.css, bootstrap.js, phông chữ), yêu cầu JQuery cho các trình bổ trợ và cung cấp các ví dụ về mã đánh dấu. Các nhà phát triển thích tính linh hoạt theo nhu cầu. Điều này cho phép họ sử dụng những phần của khung mà họ muốn sử dụng. Tuy nhiên, tôi hy vọng JoeDeveloperTM điển hình của bạn sẽ hoạt động dễ dàng và tải tất cả phiên bản Tự thân khởi nghiệp xuống.

Việc nhập sẽ rất hữu ích cho các công cụ như Bootstrap. Tôi xin giới thiệu với bạn về tương lai của việc tải Bootstrap:

<head>
    <link rel="import" href="bootstrap.html">
</head>

Người dùng chỉ cần tải một đường liên kết Nhập HTML. Họ không cần làm phiền vì ảnh chụp phân tán các tệp. Thay vào đó, toàn bộ Bootstrap được quản lý và gói gọn trong một tệp nhập, bootstrap.html:

<link rel="stylesheet" href="bootstrap.css">
<link rel="stylesheet" href="fonts.css">
<script src="jquery.js"></script>
<script src="bootstrap.js"></script>
<script src="bootstrap-tooltip.js"></script>
<script src="bootstrap-dropdown.js"></script>
...

<!-- scaffolding markup -->
<template>
    ...
</template>

Hãy để yên. Đây là những nội dung thú vị.

Sự kiện tải/lỗi

Phần tử <link> sẽ kích hoạt sự kiện load khi một lượt nhập được tải thành công và onerror khi lượt nhập không thành công (ví dụ: nếu tài nguyên 404).

Các lệnh nhập sẽ cố gắng tải ngay lập tức. Một cách dễ dàng để tránh đau đầu là sử dụng các thuộc tính onload/onerror:

<script>
    function handleLoad(e) {
    console.log('Loaded import: ' + e.target.href);
    }
    function handleError(e) {
    console.log('Error loading import: ' + e.target.href);
    }
</script>

<link rel="import" href="file.html"
        onload="handleLoad(event)" onerror="handleError(event)">

Hoặc nếu bạn đang tạo lệnh nhập động:

var link = document.createElement('link');
link.rel = 'import';
// link.setAttribute('async', ''); // make it async!
link.href = 'file.html';
link.onload = function(e) {...};
link.onerror = function(e) {...};
document.head.appendChild(link);

Sử dụng nội dung

Việc bao gồm dữ liệu nhập trên một trang không có nghĩa là "chọn nội dung của tệp đó ở đây". Tức là "trình phân tích cú pháp, hãy tìm nạp tài liệu này để tôi có thể sử dụng". Để thực sự sử dụng nội dung, bạn phải hành động và viết tập lệnh.

Một khoảnh khắc aha! quan trọng là khi bạn nhận ra rằng một lệnh nhập chỉ là một tài liệu. Trên thực tế, nội dung của một tệp nhập được gọi là tài liệu nhập. Bạn có thể thao tác với nội dung nhập bằng các API DOM chuẩn!

link.import

Để truy cập vào nội dung của một tệp nhập, hãy sử dụng thuộc tính .import của phần tử đường liên kết:

var content = document.querySelector('link[rel="import"]').import;

link.importnull trong các điều kiện sau:

  • Trình duyệt không hỗ trợ tính năng Nhập HTML.
  • <link> không có rel="import".
  • <link> chưa được thêm vào DOM.
  • <link> đã bị xoá khỏi DOM.
  • Tài nguyên không bật CORS.

Ví dụ đầy đủ

Giả sử warnings.html chứa:

<div class="warning">
    <style>
    h3 {
        color: red !important;
    }
    </style>
    <h3>Warning!
    <p>This page is under construction
</div>

<div class="outdated">
    <h3>Heads up!
    <p>This content may be out of date
</div>

Trình nhập có thể lấy một phần cụ thể của tài liệu này và sao chép phần đó vào trang của họ:

<head>
    <link rel="import" href="warnings.html">
</head>
<body>
    ...
    <script>
    var link = document.querySelector('link[rel="import"]');
    var content = link.import;

    // Grab DOM from warning.html's document.
    var el = content.querySelector('.warning');

    document.body.appendChild(el.cloneNode(true));
    </script>
</body>

Tập lệnh trong các lệnh nhập

Các lệnh nhập không nằm trong tài liệu chính. Các lớp này là vệ tinh của lớp đó. Tuy nhiên, nội dung nhập của bạn vẫn có thể hoạt động trên trang chính ngay cả khi tài liệu chính chiếm tối đa. Dữ liệu nhập có thể truy cập vào DOM và/hoặc DOM của trang đang nhập dữ liệu đó:

Ví dụ – import.html thêm một trong các tệp kiểu vào trang chính

<link rel="stylesheet" href="http://www.example.com/styles.css">
<link rel="stylesheet" href="http://www.example.com/styles2.css">

<style>
/* Note: <style> in an import apply to the main
    document by default. That is, style tags don't need to be
    explicitly added to the main document. */
#somecontainer {
color: blue;
}
</style>
...

<script>
// importDoc references this import's document
var importDoc = document.currentScript.ownerDocument;

// mainDoc references the main document (the page that's importing us)
var mainDoc = document;

// Grab the first stylesheet from this import, clone it,
// and append it to the importing document.
    var styles = importDoc.querySelector('link[rel="stylesheet"]');
    mainDoc.head.appendChild(styles.cloneNode(true));
</script>

Hãy chú ý những gì đang diễn ra ở đây. Tập lệnh bên trong lệnh nhập tham chiếu đến tài liệu đã nhập (document.currentScript.ownerDocument) và thêm một phần của tài liệu đó vào trang nhập (mainDoc.head.appendChild(...)). Khá phức tạp nếu bạn hỏi tôi.

Quy tắc của JavaScript trong quá trình nhập:

  • Tập lệnh trong quá trình nhập được thực thi trong ngữ cảnh của cửa sổ chứa document đang nhập. Vì vậy, window.document đề cập đến tài liệu trang chính. Điều này có hai hệ quả hữu ích:
    • các hàm được xác định trong một lệnh nhập sẽ kết thúc trên window.
    • bạn không phải làm bất cứ điều gì khó khăn như nối các khối <script> của quá trình nhập vào trang chính. Một lần nữa, tập lệnh sẽ được thực thi.
  • Các lệnh nhập không chặn việc phân tích cú pháp trang chính. Tuy nhiên, các tập lệnh bên trong chúng được xử lý theo thứ tự. Điều này có nghĩa là bạn nhận được hành vi giống như trì hoãn trong khi vẫn duy trì thứ tự tập lệnh thích hợp. Tìm hiểu thêm về nội dung này ở bên dưới.

Phân phối thành phần web

Thiết kế của tính năng Nhập HTML rất phù hợp để tải nội dung có thể sử dụng lại trên web. Cụ thể, đây là cách lý tưởng để phân phối Thành phần web. Mọi thứ từ HTML <template> cơ bản cho đến Phần tử tuỳ chỉnh toàn diện với DOM bóng [1, 2, 3]. Khi các công nghệ này được sử dụng song song, các lệnh nhập sẽ trở thành #include cho Thành phần web.

Bao gồm mẫu

Phần tử Mẫu HTML rất phù hợp với tính năng Nhập HTML. <template> rất phù hợp để tạo các phần đánh dấu cho ứng dụng nhập để sử dụng theo ý muốn. Việc gói nội dung trong <template> cũng mang lại cho bạn lợi ích bổ sung là làm cho nội dung không hoạt động cho đến khi được sử dụng. Điều này có nghĩa là tập lệnh không chạy cho đến khi mẫu được thêm vào DOM). Xong rồi!

import.html

<template>
    <h1>Hello World!</h1>
    <!-- Img is not requested until the <template> goes live. -->
    <img src="world.png">
    <script>alert("Executed when the template is activated.");</script>
</template>
index.html

<head>
    <link rel="import" href="import.html">
</head>
<body>
    <div id="container"></div>
    <script>
    var link = document.querySelector('link[rel="import"]');

    // Clone the <template> in the import.
    var template = link.import.querySelector('template');
    var clone = document.importNode(template.content, true);

    document.querySelector('#container').appendChild(clone);
    </script>
</body>

Đăng ký phần tử tuỳ chỉnh

Thành phần tuỳ chỉnh là một công nghệ Thành phần web khác hoạt động rất hiệu quả với tính năng Nhập HTML. Các lệnh nhập có thể thực thi tập lệnh, vậy tại sao bạn không xác định + đăng ký các phần tử tuỳ chỉnh để người dùng không phải làm điều đó? Đặt tên là "tự động đăng ký".

elements.html

<script>
    // Define and register <say-hi>.
    var proto = Object.create(HTMLElement.prototype);

    proto.createdCallback = function() {
    this.innerHTML = 'Hello, <b>' +
                        (this.getAttribute('name') || '?') + '</b>';
    };

    document.registerElement('say-hi', {prototype: proto});
</script>

<template id="t">
    <style>
    ::content > * {
        color: red;
    }
    </style>
    <span>I'm a shadow-element using Shadow DOM!</span>
    <content></content>
</template>

<script>
    (function() {
    var importDoc = document.currentScript.ownerDocument; // importee

    // Define and register <shadow-element>
    // that uses Shadow DOM and a template.
    var proto2 = Object.create(HTMLElement.prototype);

    proto2.createdCallback = function() {
        // get template in import
        var template = importDoc.querySelector('#t');

        // import template into
        var clone = document.importNode(template.content, true);

        var root = this.createShadowRoot();
        root.appendChild(clone);
    };

    document.registerElement('shadow-element', {prototype: proto2});
    })();
</script>

Thao tác nhập này xác định (và đăng ký) hai phần tử là <say-hi><shadow-element>. Mục đầu tiên hiển thị một phần tử tuỳ chỉnh cơ bản tự đăng ký bên trong phần nhập. Ví dụ thứ hai cho biết cách triển khai một phần tử tuỳ chỉnh giúp tạo DOM bóng từ <template>, sau đó tự đăng ký.

Phần hay nhất về việc đăng ký các phần tử tuỳ chỉnh bên trong dữ liệu nhập HTML là trình nhập chỉ cần khai báo phần tử của bạn trên trang của họ. Không cần đi dây.

index.html

<head>
    <link rel="import" href="elements.html">
</head>
<body>
    <say-hi name="Eric"></say-hi>
    <shadow-element>
    <div>( I'm in the light dom )</div>
    </shadow-element>
</body>

Theo tôi, chỉ riêng quy trình làm việc này thôi cũng khiến tính năng Nhập HTML trở thành một cách lý tưởng để chia sẻ Thành phần web.

Quản lý các phần phụ thuộc và nhập phụ

Lệnh nhập phụ

Một lệnh nhập có thể hữu ích khi bao gồm một lệnh nhập khác. Ví dụ: nếu bạn muốn sử dụng lại hoặc mở rộng một thành phần khác, hãy dùng tính năng nhập để tải(các) thành phần khác.

Dưới đây là ví dụ thực tế từ Polymer. Đây là một thành phần thẻ mới (<paper-tabs>) sử dụng lại một thành phần bố cục và thành phần bộ chọn. Các phần phụ thuộc được quản lý bằng tính năng Nhập HTML.

paper-tabs.html (đơn giản):

<link rel="import" href="iron-selector.html">
<link rel="import" href="classes/iron-flex-layout.html">

<dom-module id="paper-tabs">
    <template>
    <style>...</style>
    <iron-selector class="layout horizonta center">
        <content select="*"></content>
    </iron-selector>
    </template>
    <script>...</script>
</dom-module>

Nhà phát triển ứng dụng có thể nhập phần tử mới này bằng cách sử dụng:

<link rel="import" href="paper-tabs.html">
<paper-tabs></paper-tabs>

Trong tương lai, khi có một <iron-selector2> mới, tuyệt vời hơn, bạn có thể hoán đổi <iron-selector> và bắt đầu sử dụng ngay. Bạn sẽ không làm người dùng gặp sự cố nhờ các thành phần nhập và web.

Quản lý phần phụ thuộc

Chúng ta đều biết rằng việc tải JQuery nhiều lần trên mỗi trang sẽ gây ra lỗi. Điều này có phải là vấn đề lớn đối với Thành phần web khi nhiều thành phần sử dụng cùng một thư viện không? Không thể nếu chúng ta sử dụng tính năng Nhập HTML! Bạn có thể dùng các tệp này để quản lý các phần phụ thuộc.

Bằng cách gói các thư viện trong một tệp nhập HTML, bạn sẽ tự động loại bỏ các tài nguyên trùng lặp. Tài liệu chỉ được phân tích cú pháp một lần. Tập lệnh chỉ được thực thi một lần. Ví dụ: giả sử bạn xác định một tệp nhập, jquery.html, để tải một bản sao của JQuery.

jquery.html

<script src="http://cdn.com/jquery.js"></script>

Bạn có thể sử dụng lại lệnh nhập này trong các lệnh nhập tiếp theo như sau:

import2.html

<link rel="import" href="jquery.html">
<div>Hello, I'm import 2</div>
ajax-element.html

<link rel="import" href="jquery.html">
<link rel="import" href="import2.html">

<script>
    var proto = Object.create(HTMLElement.prototype);

    proto.makeRequest = function(url, done) {
    return $.ajax(url).done(function() {
        done();
    });
    };

    document.registerElement('ajax-element', {prototype: proto});
</script>

Ngay cả trang chính cũng có thể bao gồm jquery.html nếu cần thư viện:

<head>
    <link rel="import" href="jquery.html">
    <link rel="import" href="ajax-element.html">
</head>
<body>

...

<script>
    $(document).ready(function() {
    var el = document.createElement('ajax-element');
    el.makeRequest('http://example.com');
    });
</script>
</body>

Mặc dù jquery.html được đưa vào nhiều cây nhập khác nhau, nhưng tài liệu của tệp này chỉ được trình duyệt tìm nạp và xử lý một lần. Việc kiểm tra bảng điều khiển mạng đã chứng minh điều này:

jquery.html được yêu cầu một lần
jquery.html được yêu cầu một lần

Xem xét hiệu suất

Tính năng nhập HTML hoàn toàn tuyệt vời nhưng cũng giống như bất kỳ công nghệ web mới nào, bạn nên sử dụng chúng một cách khôn ngoan. Các phương pháp hay nhất về phát triển web vẫn đúng. Dưới đây là một số điều cần lưu ý.

Nhập nối

Việc giảm số yêu cầu kết nối mạng luôn là điều quan trọng. Nếu bạn có nhiều đường liên kết nhập cấp cao nhất, hãy cân nhắc kết hợp các đường liên kết đó thành một tài nguyên duy nhất và nhập tệp đó!

Vulcanize là một công cụ xây dựng npm của nhóm Polymer. Công cụ này lồng nhau làm phẳng một tập hợp các lệnh Nhập HTML thành một tệp duy nhất. Hãy xem đây là bước tạo chuỗi kết hợp cho Thành phần web.

Tính năng nhập tận dụng tính năng lưu vào bộ nhớ đệm của trình duyệt

Nhiều người quên rằng ngăn xếp mạng của trình duyệt đã được điều chỉnh tinh vi trong nhiều năm. Các lệnh nhập (và lệnh nhập phụ) cũng tận dụng logic này. Tệp nhập http://cdn.com/bootstrap.html có thể có tài nguyên phụ, nhưng các tài nguyên phụ này sẽ được lưu vào bộ nhớ đệm.

Nội dung chỉ hữu ích khi bạn thêm nội dung

Hãy xem nội dung là không hoạt động cho đến khi bạn gọi các dịch vụ của nội dung đó. Lấy một tệp định kiểu thông thường, được tạo động:

var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'styles.css';

Trình duyệt sẽ không yêu cầu styles.css cho đến khi link được thêm vào DOM:

document.head.appendChild(link); // browser requests styles.css

Một ví dụ khác là mã đánh dấu được tạo linh động:

var h2 = document.createElement('h2');
h2.textContent = 'Booyah!';

h2 tương đối vô nghĩa cho đến khi bạn thêm nó vào DOM.

Khái niệm tương tự cũng áp dụng cho tài liệu nhập. Trừ phi bạn thêm nội dung vào DOM, nội dung này sẽ không hoạt động. Trên thực tế, mục duy nhất "thực thi" trực tiếp trong tài liệu nhập là <script>. Xem phần viết tập lệnh trong các lệnh nhập.

Tối ưu hoá để tải không đồng bộ

Nhập chặn kết xuất

Các tệp nhập chặn quá trình hiển thị trang chính. Điều này tương tự như những gì <link rel="stylesheet"> làm. Lý do trình duyệt chặn việc kết xuất trên các tệp định kiểu ngay từ đầu là để giảm thiểu FOUC. Các tệp nhập hoạt động tương tự vì có thể chứa các trang định kiểu.

Để hoàn toàn không đồng bộ và không chặn trình phân tích cú pháp hoặc hiển thị, hãy sử dụng thuộc tính async:

<link rel="import" href="/path/to/import_that_takes_5secs.html" async>

Lý do async không phải là mặc định cho tính năng Nhập HTML là vì tính năng này yêu cầu nhà phát triển làm nhiều việc hơn. Đồng bộ theo mặc định có nghĩa là các mục Nhập HTML có định nghĩa phần tử tuỳ chỉnh bên trong đảm bảo tải và nâng cấp theo thứ tự. Trong một thế giới hoàn toàn không đồng bộ, các nhà phát triển sẽ phải tự quản lý thời gian nhảy và nâng cấp đó.

Bạn cũng có thể tự động tạo dữ liệu nhập không đồng bộ:

var l = document.createElement('link');
l.rel = 'import';
l.href = 'elements.html';
l.setAttribute('async', '');
l.onload = function(e) { ... };

Các lệnh nhập không chặn quá trình phân tích cú pháp

Tính năng nhập không chặn quá trình phân tích cú pháp trang chính. Các tập lệnh bên trong lệnh nhập được xử lý theo thứ tự nhưng không chặn trang nhập. Điều này có nghĩa là bạn sẽ nhận được hành vi giống như trì hoãn trong khi vẫn duy trì thứ tự tập lệnh thích hợp. Một lợi ích của việc đưa nội dung nhập vào <head> là cho phép trình phân tích cú pháp bắt đầu xử lý nội dung sớm nhất có thể. Dù vậy, bạn phải ghi nhớ <script> trong tài liệu chính vẫn tiếp tục chặn trang. <script> đầu tiên sau khi nhập sẽ chặn quá trình hiển thị trang. Đó là do một lệnh nhập có thể có tập lệnh bên trong cần được thực thi trước tập lệnh trong trang chính.

<head>
    <link rel="import" href="/path/to/import_that_takes_5secs.html">
    <script>console.log('I block page rendering');</script>
</head>

Tuỳ thuộc vào cấu trúc ứng dụng và trường hợp sử dụng, có một số cách để tối ưu hoá hành vi không đồng bộ. Các kỹ thuật dưới đây giúp giảm thiểu việc chặn quá trình kết xuất trang chính.

Tình huống 1 (ưu tiên): bạn không có tập lệnh trong <head> hoặc nội tuyến trong <body>

Bạn nên đặt <script> sau khi nhập dữ liệu. Di chuyển tập lệnh càng trễ trong trò chơi càng tốt…nhưng bạn đã thực hiện phương pháp hay nhất đó, PHẢI KHÔNG!? ;)

Ví dụ:

<head>
    <link rel="import" href="/path/to/import.html">
    <link rel="import" href="/path/to/import2.html">
    <!-- avoid including script -->
</head>
<body>
    <!-- avoid including script -->

    <div id="container"></div>

    <!-- avoid including script -->
    ...

    <script>
    // Other scripts n' stuff.

    // Bring in the import content.
    var link = document.querySelector('link[rel="import"]');
    var post = link.import.querySelector('#blog-post');

    var container = document.querySelector('#container');
    container.appendChild(post.cloneNode(true));
    </script>
</body>

Mọi thứ đều nằm ở dưới cùng.

Tình huống 1.5: lệnh nhập tự thêm vào

Một cách khác là yêu cầu tính năng nhập thêm nội dung của riêng nó. Nếu tác giả nhập thiết lập một hợp đồng để nhà phát triển ứng dụng tuân theo, thì nội dung nhập có thể tự thêm vào một khu vực trên trang chính:

import.html:

<div id="blog-post">...</div>
<script>
    var me = document.currentScript.ownerDocument;
    var post = me.querySelector('#blog-post');

    var container = document.querySelector('#container');
    container.appendChild(post.cloneNode(true));
</script>
index.html

<head>
    <link rel="import" href="/path/to/import.html">
</head>
<body>
    <!-- no need for script. the import takes care of things -->
</body>

Tình huống 2: bạn tập lệnh trong <head> hoặc cùng dòng trong <body>

Nếu một tệp nhập mất nhiều thời gian để tải, thì <script> đầu tiên theo sau tệp đó trên trang sẽ chặn việc hiển thị trang. Ví dụ: Google Analytics đề xuất đặt mã theo dõi vào <head>, Nếu bạn không thể tránh được việc đặt <script> vào <head>, thì việc thêm dữ liệu nhập một cách linh động sẽ giúp trang không bị chặn:

<head>
    <script>
    function addImportLink(url) {
        var link = document.createElement('link');
        link.rel = 'import';
        link.href = url;
        link.onload = function(e) {
        var post = this.import.querySelector('#blog-post');

        var container = document.querySelector('#container');
        container.appendChild(post.cloneNode(true));
        };
        document.head.appendChild(link);
    }

    addImportLink('/path/to/import.html'); // Import is added early :)
    </script>
    <script>
    // other scripts
    </script>
</head>
<body>
    <div id="container"></div>
    ...
</body>

Ngoài ra, hãy thêm dữ liệu nhập gần cuối <body>:

<head>
    <script>
    // other scripts
    </script>
</head>
<body>
    <div id="container"></div>
    ...

    <script>
    function addImportLink(url) { ... }

    addImportLink('/path/to/import.html'); // Import is added very late :(
    </script>
</body>

Những điều cần nhớ

  • MIME của tệp nhập là text/html.

  • Bạn cần bật CORS (Chia sẻ tài nguyên giữa các tài nguyên trên các nguồn khác).

  • Các tệp nhập từ cùng một URL sẽ được truy xuất và phân tích cú pháp một lần. Điều đó có nghĩa là tập lệnh trong tệp nhập chỉ được thực thi trong lần đầu tiên Google nhìn thấy tệp nhập đó.

  • Các tập lệnh trong một lệnh nhập được xử lý theo thứ tự, nhưng không chặn quá trình phân tích cú pháp tài liệu chính.

  • Liên kết nhập không có nghĩa là "#include the content here". Tức là "trình phân tích cú pháp, hãy tìm nạp tài liệu này để tôi có thể sử dụng sau". Mặc dù các tập lệnh thực thi tại thời điểm nhập, nhưng bạn cần thêm rõ ràng các tệp kiểu, mã đánh dấu và tài nguyên khác vào trang chính. Lưu ý: Bạn không cần thêm <style> một cách rõ ràng. Đây là một điểm khác biệt lớn giữa tính năng Nhập HTML và <iframe>, trong đó có nội dung "tải và kết xuất nội dung này tại đây".

Kết luận

Tính năng Nhập HTML cho phép gói HTML/CSS/JS thành một tài nguyên duy nhất. Mặc dù bản thân chúng vẫn hữu ích nhưng ý tưởng này lại trở nên cực kỳ mạnh mẽ trong thế giới Thành phần web. Nhà phát triển có thể tạo các thành phần có thể sử dụng lại để người khác sử dụng và đưa vào ứng dụng của riêng họ, tất cả đều được phân phối thông qua <link rel="import">.

Nhập HTML là một khái niệm đơn giản, nhưng cho phép một số trường hợp sử dụng thú vị cho nền tảng.

Trường hợp sử dụng

  • Phân phối HTML/CSS/JS liên quan dưới dạng một gói duy nhất. Về mặt lý thuyết, bạn có thể nhập toàn bộ một ứng dụng web vào một ứng dụng web khác.
  • Sắp xếp mã – phân chia các khái niệm một cách hợp lý thành các tệp khác nhau, khuyến khích mô-đun và tái sử dụng**.
  • Phân phối một hoặc nhiều định nghĩa Phần tử tuỳ chỉnh. Bạn có thể dùng một phần dữ liệu nhập để register và đưa chúng vào ứng dụng. Việc này giúp áp dụng các mẫu phần mềm hiệu quả, tách biệt giao diện/định nghĩa của phần tử với cách sử dụng.
  • Quản lý phần phụ thuộc – tài nguyên được tự động loại bỏ trùng lặp.
  • Gói tập lệnh – trước khi nhập, thư viện JS có kích thước lớn sẽ phân tích cú pháp toàn bộ tệp để bắt đầu chạy, điều này sẽ làm chậm quá trình. Với lệnh nhập, thư viện có thể bắt đầu hoạt động ngay khi phân đoạn A được phân tích cú pháp. Ít độ trễ hơn!
// TODO: DevSite - Code sample removed as it used inline event handlers
  • Tiến hành phân tích cú pháp HTML song song – lần đầu tiên trình duyệt có thể chạy song song hai (hoặc nhiều) trình phân tích cú pháp HTML.

  • Cho phép chuyển đổi giữa chế độ gỡ lỗi và chế độ không gỡ lỗi trong một ứng dụng, chỉ bằng cách thay đổi chính mục tiêu nhập. Ứng dụng của bạn không cần phải biết mục tiêu nhập là tài nguyên đi kèm/biên dịch hay cây nhập.