📜 ⬆️ ⬇️

Another way to load CSS via RequireJS

In the process of developing JS modules that claim to be reusable, it is often necessary, in addition to js-code and markup, to also load a file with styles. As you know, styles themselves can be added to a document in three ways: via the link tag, via the style tag, and through the style attribute. Depending on the chosen method, you can get different pros and cons. I propose to look at the method consisting of using the link tag, but free from the problem of the absence of the event of the end of loading the stylesheet from the browser.

for those who only code
define(["text!myCSS.css"], function(cssText) { 'use strict'; var link = document.createElement("link"); link.rel = "stylesheet"; link.type = "text/css" link.href = "data:text/css,"+encodeURI(cssText); var cssLinks = document.querySelectorAll("link[rel=stylesheet]"); if (cssLinks.length > 0) { cssLinks[0].parentElement.insertBefore(link, cssLinks[0]); } else { document.querySelector("head").appendChild(link); } }); 


Let's start with the answer to the question “Why is it via the link tag?”

The fact is that from the module you usually want to be able to conveniently customize its visual presentation.
If we want to use the style attribute directly in our markup, then later on when reusing, we will have to somehow change these attributes - super inconvenient and not flexible.

If we want to use the style tag, there is a problem with the fact that to customize such styles, we will also have to insert a style tag with the necessary content into the document, which is also not very convenient.
')
If we want to use the link tag, we can simply connect our own style sheet after it is loaded and correct the default view for immediate needs.

It follows from the above that the option with the link tag is the most flexible, since allows you to override styles when using a component in the largest number of ways.

As written in the RequireJS documentation, you can use the following code to load css:

 function loadCss(url) { var link = document.createElement("link"); link.type = "text/css"; link.rel = "stylesheet"; link.href = url; document.getElementsByTagName("head")[0].appendChild(link); } 

It’s not bad for everyone, except that you don’t know when your css will be loaded (and if at all, you could, for example, be sealed in the ways). This problem is fraught with the fact that it can cause the ugly behavior of the picture, if the page renders before the end of the file download.

And I want to write a component like this:

 define(["text!myCSS.css", "text!myHTML.html"], function(cssText, htmlText) { 'use strict'; ... }); 

But then how to push the resulting text css in our page? The style tag could help us, but it was previously decided that our option is the link.

The proposed solution is the Data URL (if anyone does not know what it is, you can see here ).

We will add something like this:

  var link = document.createElement("link"); link.rel = "stylesheet"; link.type = "text/css" link.href = "data:text/css,"+encodeURI(cssText); var cssLinks = document.querySelectorAll("link[rel=stylesheet]"); if (cssLinks.length > 0) { cssLinks[0].parentElement.insertBefore(link, cssLinks[0]); } else { document.querySelector("head").appendChild(link); } 

The method undoubtedly has some drawbacks, of the obvious - base64 encoding increases the amount of data, theoretically, you can encounter restrictions on the length of the URL for some browsers. But if the volume of styles is small, then the method looks quite working.

UPD:
Thanks oledje for the hint, base64 encoding for the text is not needed, URL encoding is better, corrected the code.

Source: https://habr.com/ru/post/307094/


All Articles