How Do I Use A Url To Import A Template
HTML Imports are deprecated and was removed from Chrome in February 2020.
Why imports?
Think about how you load unlike types of resources on the web. For JS, we have <script src>. For CSS, your go-to is probably <link rel="stylesheet">. For images information technology's <img>. Video has <video>. Sound, <audio>.... Get to the bespeak! The majority of the web's content has a simple and declarative way to load itself. Not and then for HTML. Here's your options:
-
<iframe>- tried and truthful but heavy weight. An iframe's content lives entirely in a separate context than your page. While that's by and large a bang-up characteristic, it creates additional challenges (compress wrapping the size of the frame to its content is tough, insanely frustrating to script into/out of, nearly incommunicable to style). - AJAX - I love
xhr.responseType="document", just y'all're saying I need JS to load HTML? That doesn't seem correct. - CrazyHacks™ - embedded in strings, subconscious every bit comments (e.thousand.
<script type="text/html">). Yuck!
See the irony? The web'due south most basic content, HTML, requires the greatest amount of effort to work with. Fortunately, Web Components are hither to go u.s. dorsum on track.
Getting started
HTML Imports, office of the Spider web Components cast, is a way to include HTML documents in other HTML documents. Y'all're not limited to markup either. An import tin as well include CSS, JavaScript, or annihilation else an .html file tin can contain. In other words, this makes imports a fantastic tool for loading related HTML/CSS/JS.
The basics
Include an import on your page by declaring a <link rel="import">:
<head> <link rel="import" href="/path/to/imports/stuff.html"> </head> The URL of an import is called an import location. To load content from another domain, the import location needs to be CORS-enabled:
<!-- Resource on other origins must be CORS-enabled. --> <link rel="import" href="http://case.com/elements.html"> The browser's network stack automatically de-dupes all requests from the aforementioned URL. This means that imports that reference the same URL are only retrieved one time. No matter how many times an import at the same location is loaded, it just executes once.
Feature detection and support
To discover support, check if .import exists on the <link> chemical element:
function supportsImports() { render 'import' in document.createElement('link'); } if (supportsImports()) { // Adept to become! } else { // Utilise other libraries/require systems to load files. } Browser support is still in the early days. Chrome 31 was the kickoff browser to come across an implementation only other browser vendors are waiting to run across how ES Modules play out. Nonetheless, for other browsers, webcomponents.js polyfill works great until things are widely supported.
Bundling resources
Imports provide convention for bundling HTML/CSS/JS (even other HTML Imports) into a unmarried deliverable. It'south an intrinsic feature, only a powerful one. If you're creating a theme, library, or merely want to segment your app into logical chunks, giving users a single URL is compelling. Heck, you could even deliver an entire app via an import. Think about that for a second.
A real-earth example is Bootstrap. Bootstrap is comprised of individual files (bootstrap.css, bootstrap.js, fonts), requires JQuery for its plugins, and provides markup examples. Developers similar à la bill of fare flexibility. It allows them buy in to the parts of the framework they want to use. That said, I'd wager your typical JoeDeveloper™ goes the like shooting fish in a barrel road and downloads all of Bootstrap.
Imports make a ton of sense for something like Bootstrap. I present to y'all, the future of loading Bootstrap:
<head> <link rel="import" href="bootstrap.html"> </caput> Users only load an HTML Import link. They don't need to fuss with the scatter-shot of files. Instead, the entirety of Bootstrap is managed and wrapped up in an import, 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> Let this sit. It's exciting stuff.
Load/fault events
The <link> element fires a load event when an import is loaded successfully and onerror when the try fails (e.g. if the resource 404s).
Imports endeavour to load immediately. An like shooting fish in a barrel way avoid headaches is to utilize the onload/onerror attributes:
<script> function handleLoad(e) { console.log('Loaded import: ' + e.target.href); } office handleError(e) { console.log('Mistake loading import: ' + e.target.href); } </script> <link rel="import" href="file.html" onload="handleLoad(outcome)" onerror="handleError(event)"> Find the consequence handlers are divers before the import is loaded on the page. The browser tries to load the import equally soon as information technology encounters the tag. If the functions don't exist all the same, yous'll become panel errors for undefined part names.
Or, if y'all're creating the import dynamically:
var link = certificate.createElement('link'); link.rel = 'import'; link.href = 'file.html'; //link.setAttribute('async', ''); // make it async! link.onload = role(e) {...}; link.onerror = function(e) {...}; certificate.head.appendChild(link); Using the content
Including an import on a folio doesn't hateful "plop the content of that file here". It ways "parser, go off an fetch this certificate then I tin can use it". To really apply the content, you take to accept action and write script.
A disquisitional aha! moment is realizing that an import is but a certificate. In fact, the content of an import is called an import document. You lot're able to manipulate the guts of an import using standard DOM APIs!
link.import
To access the content of an import, utilize the link element'south .import property:
var content = certificate.querySelector('link[rel="import"]').import; link.import is null under the following atmospheric condition:
- The browser doesn't support HTML Imports.
- The
<link>doesn't takerel="import". - The
<link>has non been added to the DOM. - The
<link>has been removed from the DOM. - The resource is non CORS-enabled.
Total instance
Let'south say warnings.html contains:
<div class="alert"> <fashion> h3 { color: red !of import; } </style> <h3>Alert!</h3> <p>This page is under construction</p> </div> <div class="outdated"> <h3>Heads upward!</h3> <p>This content may exist out of date</p> </div> Importers can grab a specific portion of this document and clone information technology into their page:
<head> <link rel="import" href="warnings.html"> </caput> <body> ... <script> var link = document.querySelector('link[rel="import"]'); var content = link.import; // Grab DOM from alarm.html'south document. var el = content.querySelector('.warning'); certificate.body.appendChild(el.cloneNode(truthful)); </script> </body> Scripting in imports
Imports are not in the main document. They're satellite to information technology. However, your import tin still act on the principal page even though the main document reigns supreme. An import can access its own DOM and/or the DOM of the page that's importing information technology:
Example - import.html that adds ane of its stylesheets to the main page
<link rel="stylesheet" href="http://www.case.com/styles.css"> <link rel="stylesheet" href="http://www.case.com/styles2.css"> <way> /* Annotation: <style> in an import apply to the chief certificate past default. That is, manner tags don't need to be explicitly added to the main document. */ #somecontainer { color: blue; } </style> ... <script> // importDoc references this import'southward document var importDoc = document.currentScript.ownerDocument; // mainDoc references the main document (the page that'south importing us) var mainDoc = document; // Grab the get-go 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> Notice what'due south going on hither. The script inside the import references the imported document (certificate.currentScript.ownerDocument), and appends role of that document to the importing page (mainDoc.head.appendChild(...)). Pretty gnarly if y'all ask me.
Rules of JavaScript in an import:
- Script in the import is executed in the context of the window that contains the importing
certificate. Sowindow.documentrefers to the main page document. This has ii useful corollaries:- functions defined in an import terminate upwards on
window. - you lot don't have to do annihilation crazy like append the import's
<script>blocks to the main page. Again, script gets executed.
- functions defined in an import terminate upwards on
- Imports do not block parsing of the principal page. Notwithstanding, scripts within them are candy in club. This means yous become defer-like behavior while maintaining proper script order. More than on this below.
Delivering Web Components
The blueprint of HTML Imports lends itself nicely to loading reusable content on the web. In particular, it's an ideal way to distribute Web Components. Everything from basic HTML <template>s to full diddled Custom Elements with Shadow DOM [ane, two, 3]. When these technologies are used in tandem, imports become a #include for Spider web Components.
Including templates
The HTML Template element is a natural fit for HTML Imports. <template> is great for scaffolding out sections of markup for the importing app to use every bit it desires. Wrapping content in a <template> also gives you the added do good of making the content inert until used. That is, scripts don't run until the template is added to the DOM). Blast!
import.html
<template> <h1>How-do-you-do World!</h1> <!-- Img is not requested until the <template> goes alive. --> <img src="earth.png"> <script>warning("Executed when the template is activated.");</script> </template> alphabetize.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 = certificate.importNode(template.content, true); document.querySelector('#container').appendChild(clone); </script> </body> Registering custom elements
Custom Elements is some other Web Component engineering that plays absurdly well with HTML Imports. Imports can execute script, so why non define + annals your custom elements so users don't accept to? Call it..."auto-registration".
elements.html
<script> // Ascertain and register <say-hello>. var proto = Object.create(HTMLElement.image); proto.createdCallback = function() { this.innerHTML = 'How-do-you-do, <b>' + (this.getAttribute('name') || '?') + '</b>'; }; document.registerElement('say-howdy', {prototype: proto}); </script> <template id="t"> <style> ::content > * { colour: carmine; } </style> <span>I'chiliad a shadow-element using Shadow DOM!</span> <content></content> </template> <script> (office() { var importDoc = document.currentScript.ownerDocument; // importee // Define and annals <shadow-element> // that uses Shadow DOM and a template. var proto2 = Object.create(HTMLElement.image); proto2.createdCallback = part() { // go template in import var template = importDoc.querySelector('#t'); // import template into var clone = certificate.importNode(template.content, truthful); var root = this.createShadowRoot(); root.appendChild(clone); }; document.registerElement('shadow-chemical element', {prototype: proto2}); })(); </script> This import defines (and registers) two elements, <say-hi> and <shadow-element>. The first shows a bones custom element that registers itself inside the import. The 2nd example shows how to implement a custom element that creates Shadow DOM from a <template>, so registers itself.
The best part nigh registering custom elements inside an HTML import is that the the importer but declares your element on their page. No wiring needed.
alphabetize.html
<head> <link rel="import" href="elements.html"> </caput> <torso> <say-howdy name="Eric"></say-hi> <shadow-element> <div>( I'm in the calorie-free dom )</div> </shadow-element> </torso> In my opinion, this workflow solitary makes HTML Imports an ideal manner to share Web Components.
Managing dependencies and sub-imports
Yo dawg. I hear yous like imports, so I included an import in your import.
Sub-imports
It can be useful for one import to include another. For case, if you want to reuse or extend another component, use an import to load the other element(southward).
Below is a existent example from Polymer. It's a new tab component (<newspaper-tabs>) that reuses a layout and selector component. The dependencies are managed using HTML Imports.
newspaper-tabs.html (simplified):
<link rel="import" href="atomic number 26-selector.html"> <link rel="import" href="classes/iron-flex-layout.html"> <dom-module id="paper-tabs"> <template> <mode>...</way> <atomic number 26-selector class="layout horizonta center"> <content select="*"></content> </iron-selector> </template> <script>...</script> </dom-module> full source
App developers can import this new chemical element using:
<link rel="import" href="newspaper-tabs.html"> <paper-tabs></paper-tabs> When a new, more crawly <iron-selector2> comes along in the hereafter, yous tin swap out <iron-selector> and showtime using it straight away. You won't break your users thanks to imports and web components.
Dependency management
We all know that loading JQuery more than once per page causes errors. Isn't this going to exist a huge problem for Web Components when multiple components utilise the aforementioned library? Not if we utilise HTML Imports! They can be used to manage dependencies.
By wrapping libraries in an HTML Import, you lot automatically de-dupe resource. The certificate is only parsed in one case. Scripts are only executed once. As an example, say you lot define an import, jquery.html, that loads a copy of JQuery.
jquery.html
<script src="http://cdn.com/jquery.js"></script> This import tin can be reused in subsequent imports similar then:
import2.html
<link rel="import" href="jquery.html"> <div>Hello, I'thousand import 2</div> ajax-element.html
<link rel="import" href="jquery.html"> <link rel="import" href="import2.html"> <script> var proto = Object.create(HTMLElement.epitome); proto.makeRequest = role(url, washed) { return $.ajax(url).washed(function() { done(); }); }; certificate.registerElement('ajax-element', {image: proto}); </script> Even the main page itself tin can include jquery.html if it needs the library:
<head> <link rel="import" href="jquery.html"> <link rel="import" href="ajax-chemical element.html"> </head> <body> ... <script> $(document).ready(function() { var el = document.createElement('ajax-chemical element'); el.makeRequest('http://example.com'); }); </script> </body> Despite jquery.html being included in many different import trees, it'southward certificate is only fetched and processed once by the browser. Examining the network panel proves this:
Performance considerations
HTML Imports are totally awesome but equally with whatever new web technology, you should use them wisely. Web evolution best practices withal concur true. Below are some things to keep in mind.
Concatenate imports
Reducing network requests is always of import. If you lot accept many acme-level import links, consider combining them into a single resource and importing that file!
Vulcanize is an npm build tool from the Polymer team that recursively flattens a set up of HTML Imports into a single file. Call back of it as a concatenation build step for Web Components.
Imports leverage browser caching
Many people forget that the browser'south networking stack has been finely tuned over the years. Imports (and sub-imports) accept advantage of this logic too. The http://cdn.com/bootstrap.html import might have sub-resources, but they'll be cached.
Content is useful only when you add together it
Think of content as inert until you phone call upon its services. Accept a normal, dynamically created stylesheet:
var link = document.createElement('link'); link.rel = 'stylesheet'; link.href = 'styles.css'; The browser won't request styles.css until link is added to the DOM:
document.head.appendChild(link); // browser requests styles.css Another instance is dynamically created markup:
var h2 = document.createElement('h2'); h2.textContent = 'Booyah!'; The h2 is relatively meaningless until you add information technology to the DOM.
The same concept holds true for the import document. Unless you suspend it's content to the DOM, it's a no-op. In fact, the merely thing that "executes" in the import document directly is <script>. Run across scripting in imports.
Optimizing for async loading
Imports block rendering
Imports block rendering of the master folio. This is like to what <link rel="stylesheet"> practise. The reason the browser blocks rendering on stylesheets in the first identify is to minimize FOUC. Imports conduct similarly considering they can contain stylsheets.
To exist completely asynchronous and non block the parser or rendering, use the async attribute:
<link rel="import" href="/path/to/import_that_takes_5secs.html" async> The reason async isn't the default for HTML Imports is because it requires developers to practice more piece of work. Synchronous past default ways that HTML Imports that have custom chemical element definitions inside of them are guaranteed to load and upgrade, in order. In a completely async world, developers would take to manage that trip the light fantastic toe and upgrade timings themselves.
You lot tin can also create an async import, dynamically:
var l = certificate.createElement('link'); l.rel = 'import'; l.href = 'elements.html'; l.setAttribute('async', ''); fifty.onload = function(e) { ... }; Imports do not block parsing
Imports don't block parsing of the main page. Scripts inside imports are processed in order only don't block the importing page. This means yous get defer-like behavior while maintaining proper script order. 1 benefit of putting your imports in the <caput> is that it lets the parser get-go working on the content as before long as possible. With that said, it's critical to call back <script> in the main document still continues to block the page. The first <script> after an import will cake page rendering. That's because an import can have script within that needs to be executed before the script in the master page.
<head> <link rel="import" href="/path/to/import_that_takes_5secs.html"> <script>panel.log('I block page rendering');</script> </caput> Depending on your app structure and use instance, there are several ways to optimize async behavior. The techniques below mitigate blocking the main folio rendering.
Scenario #1 (preferred): you lot don't take script in <head> or inlined in <torso>
My recommendation for placing <script> is to avoid immediately following your imports. Motility scripts as late in the game every bit possible...but you're already doing that best practice, AREN'T YOU!? ;)
Here'due south an example:
<head> <link rel="import" href="/path/to/import.html"> <link rel="import" href="/path/to/import2.html"> <!-- avoid including script --> </head> <trunk> <!-- avoid including script --> <div id="container"></div> <!-- avert including script --> ... <script> // Other scripts n' stuff. // Bring in the import content. var link = document.querySelector('link[rel="import"]'); var post = link.import.querySelector('#web log-postal service'); var container = document.querySelector('#container'); container.appendChild(post.cloneNode(true)); </script> </body> Everything is at the bottom.
Scenario 1.5: the import adds itself
Another option is to take the import add its own content. If the import author establishes a contract for the app developer to follow, the import tin add itself to an area of the master folio:
import.html:
<div id="blog-postal service">...</div> <script> var me = document.currentScript.ownerDocument; var post = me.querySelector('#blog-post'); var container = document.querySelector('#container'); container.appendChild(postal service.cloneNode(truthful)); </script> index.html
<head> <link rel="import" href="/path/to/import.html"> </head> <torso> <!-- no need for script. the import takes intendance of things --> </body> Scenario #2: yous have script in <head> or inlined in <body>
If you lot accept an import that takes a long fourth dimension to load, the first <script> that follows it on the page will block the page from rendering. Google Analytics for example, recommends putting the tracking lawmaking in the <head>, If you can't avert putting <script> in the <head>, dynamically calculation the import will prevent blocking the page:
<head> <script> function addImportLink(url) { var link = document.createElement('link'); link.rel = 'import'; link.href = url; link.onload = function(eastward) { var post = this.import.querySelector('#blog-post'); var container = document.querySelector('#container'); container.appendChild(postal service.cloneNode(true)); }; document.head.appendChild(link); } addImportLink('/path/to/import.html'); // Import is added early on :) </script> <script> // other scripts </script> </caput> <body> <div id="container"></div> ... </body> Alternatively, add the import virtually the end of the <body>:
<head> <script> // other scripts </script> </head> <body> <div id="container"></div> ... <script> part addImportLink(url) { ... } addImportLink('/path/to/import.html'); // Import is added very late :( </script> </body> Annotation: This very final approach is least preferable. The parser doesn't showtime to work on the import content until belatedly in the page.
Things to remember
-
An import'south mimetype is
text/html. -
Resources from other origins demand to be CORS-enabled.
-
Imports from the same URL are retrieved and parsed once. That means script in an import is but executed the start fourth dimension the import is seen.
-
Scripts in an import are processed in gild, but do not block the main document parsing.
-
An import link doesn't hateful "#include the content here". It means "parser, get off an fetch this document and so I can utilize information technology later". While scripts execute at import time, stylesheets, markup, and other resources need to be added to the main page explicitly. Note,
<style>don't need to be added explicitly. This is a major difference between HTML Imports and<iframe>, which says "load and return this content here".
Conclusion
HTML Imports allow bundling HTML/CSS/JS as a single resource. While useful past themselves, this thought becomes extremely powerful in the world of Web Components. Developers can create reusable components for others to consume and bring in to their own app, all delivered through <link rel="import">.
HTML Imports are a unproblematic concept, but enable a number of interesting use cases for the platform.
Use cases
- Distribute related HTML/CSS/JS as a unmarried bundle. Theoretically, you could import an entire web app into some other.
- Code organization - segment concepts logically into different files, encouraging modularity & reusability**.
- Evangelize one or more Custom Element definitions. An import can be used to register and include them in an app. This practices expert software patterns, keeping the element's interface/definition separate from how its used.
- Manage dependencies - resource are automatically de-duped.
-
Chunk scripts - before imports, a big-sized JS library would have its file wholly parsed in order to offset running, which was wearisome. With imports, the library tin can showtime working as soon every bit chunk A is parsed. Less latency!
<link rel="import" href="chunks.html">:<script>/* script clamper A goes here */</script> <script>/* script chunk B goes hither */</script> <script>/* script chunk C goes hither */</script> ... -
Parallelizes HTML parsing - showtime fourth dimension the browser has been able to run ii (or more than) HTML parsers in parallel.
-
Enables switching between debug and non-debug modes in an app, just by irresolute the import target itself. Your app doesn't need to know if the import target is a bundled/compiled resource or an import tree.
How Do I Use A Url To Import A Template,
Source: https://www.html5rocks.com/tutorials/webcomponents/imports/
Posted by: stainbrookmork1972.blogspot.com

0 Response to "How Do I Use A Url To Import A Template"
Post a Comment