如何使用Javascript加载CSS文件?

Cli*_*ote 297 html javascript css dhtml

是否可以使用Javascript将CSS样式表导入html页面?如果是这样,怎么办呢?

PS javascript将托管在我的网站上,但我希望用户能够放入<head>他们网站的标签,并且它应该能够将我服务器上托管的css文件导入到当前的网页中.(css文件和javascript文件都将托管在我的服务器上).

小智 392

这是"老派"的做法,希望能在所有浏览器中使用.从理论上讲,setAttribute不幸的是IE6并不能始终如一地支持它.

var cssId = 'myCss';  // you could encode the css path itself to generate id..
if (!document.getElementById(cssId))
{
    var head  = document.getElementsByTagName('head')[0];
    var link  = document.createElement('link');
    link.id   = cssId;
    link.rel  = 'stylesheet';
    link.type = 'text/css';
    link.href = 'http://website.com/css/stylesheet.css';
    link.media = 'all';
    head.appendChild(link);
}
Run Code Online (Sandbox Code Playgroud)

此示例检查是否已添加CSS,因此仅添加一次.

将该代码放入javascript文件中,让最终用户只包含javascript,并确保CSS路径是绝对的,以便从服务器加载.

VanillaJS

下面是一个使用纯JavaScript head根据URL的文件名部分将CSS链接注入元素的示例:

<script type="text/javascript">
var file = location.pathname.split( "/" ).pop();

var link = document.createElement( "link" );
link.href = file.substr( 0, file.lastIndexOf( "." ) ) + ".css";
link.type = "text/css";
link.rel = "stylesheet";
link.media = "screen,print";

document.getElementsByTagName( "head" )[0].appendChild( link );
</script>
Run Code Online (Sandbox Code Playgroud)

在结束head标记之前插入代码,并在呈现页面之前加载CSS.使用外部JavaScript(.js)文件将导致出现无格式内容(FOUC)的Flash .

  • 也许最好为文档快捷方式使用与$不同的字符,因为它可以轻松地干扰jQuery(就像我的情况一样);) (9认同)
  • 一旦CSS文件加载后运行回调怎么办? (5认同)
  • 要可靠地做到这一点相当复杂。现在流行的 Javascript 库通常具有某种形式的回调加载 javascript 和样式表。作为示例,请参阅 [YUI Get](http://yuilibrary.com/yui/docs/get/)。 (2认同)
  • @ zathrus-writer尝试jQuery.noConflic(); http://api.jquery.com/jQuery.noConflict/ (2认同)
  • @jonnybojangles使用jQuery.noConflict意味着将所有对jQuery的引用重命名为$.为CSS加载器使用不同的变量名称会简单得多. (2认同)
  • @jchook 我能够通过在追加之前添加`link.onload = function(){ ... }` 来附加回调 (2认同)

Bou*_*TAC 70

如果你使用jquery:

$('head').append('<link rel="stylesheet" type="text/css" href="style.css">');
Run Code Online (Sandbox Code Playgroud)

  • 仅当在页面加载之前注入样式表时,这才有效,对吗?当我在控制台内的加载页面上运行此命令时,该页面包含我托管在 dropbox 上的 css 文件,它将无法工作。知道我如何才能完成这项工作: `$('head').append('&lt;link rel="stylesheet" type="text/css" href="https://dl.dropboxusercontent.com/s/ep1nzckmvgjq7jr /remove_transitions_from_page.css"&gt;');` (3认同)

Von*_*onC 49

我想像这样的脚本会做的事情:

<script type="text/javascript" src="/js/styles.js"></script>
Run Code Online (Sandbox Code Playgroud)

该JS文件包含以下语句:

if (!document.getElementById) document.write('<link rel="stylesheet" type="text/css" href="/css/versions4.css">');
Run Code Online (Sandbox Code Playgroud)

如果要引用您的网站,javascript和css的地址必须是绝对的.

许多CSS导入技术在这篇"使用分支技术对CSS hack说"中的文章中进行了讨论.

但是"使用JavaScript动态添加Portlet CSS样式表"文章还提到了CreateStyleSheet的可能性(IE的专有方法):

<script type="text/javascript">
//<![CDATA[
if(document.createStyleSheet) {
  document.createStyleSheet('http://server/stylesheet.css');
}
else {
  var styles = "@import url(' http://server/stylesheet.css ');";
  var newSS=document.createElement('link');
  newSS.rel='stylesheet';
  newSS.href='data:text/css,'+escape(styles);
  document.getElementsByTagName("head")[0].appendChild(newSS);
}
//]]>
Run Code Online (Sandbox Code Playgroud)


Tal*_*lha 17

调用以下函数以动态加载CSS或JavaScript文件.

function loadjscssfile(filename, filetype) {
  if (filetype == "js") { //if filename is a external JavaScript file
    // alert('called');
    var fileref = document.createElement('script')
    fileref.setAttribute("type", "text/javascript")
    fileref.setAttribute("src", filename)
    alert('called');
  } else if (filetype == "css") { //if filename is an external CSS file
    var fileref = document.createElement("link")
    fileref.setAttribute("rel", "stylesheet")
    fileref.setAttribute("type", "text/css")
    fileref.setAttribute("href", filename)
  }
  if (typeof fileref != "undefined")
    document.getElementsByTagName("head")[0].appendChild(fileref)
}
Run Code Online (Sandbox Code Playgroud)

使用名称作为filename参数传递完整文件路径.

  • 这段代码来自[link](http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml),没有给出任何评分,很酷。 (4认同)

dan*_*ans 11

Element.insertAdjacentHTML具有非常好的浏览器支持,并且可以在一行中添加样式表。

document.getElementsByTagName("head")[0].insertAdjacentHTML(
    "beforeend",
    "<link rel=\"stylesheet\" href=\"path/to/style.css\" />");
Run Code Online (Sandbox Code Playgroud)


san*_*rom 9

如果您想知道(或等待)样式本身已加载,这将起作用:

// this will work in IE 10, 11 and Safari/Chrome/Firefox/Edge
// add ES6 poly-fill for the Promise, if needed (or rewrite to use a callback)

let fetchStyle = function(url) {
  return new Promise((resolve, reject) => {
    let link = document.createElement('link');
    link.type = 'text/css';
    link.rel = 'stylesheet';
    link.onload = function() { resolve(); console.log('style has loaded'); };
    link.href = url;

    let headScript = document.querySelector('script');
    headScript.parentNode.insertBefore(link, headScript);
  });
};
Run Code Online (Sandbox Code Playgroud)


Igl*_*rdo 9

你听说过 Promise 吗?它们适用于所有现代浏览器,并且使用起来相对简单。看看这个将 css 注入 html 头部的简单方法:

function loadStyle(src) {
    return new Promise(function (resolve, reject) {
        let link = document.createElement('link');
        link.href = src;
        link.rel = 'stylesheet';

        link.onload = () => resolve(link);
        link.onerror = () => reject(new Error(`Style load error for ${src}`));

        document.head.append(link);
    });
}
Run Code Online (Sandbox Code Playgroud)

您可以按如下方式实现:

window.onload = function () {
    loadStyle("https://fonts.googleapis.com/css2?family=Raleway&display=swap")
        .then(() => loadStyle("css/style.css"))
        .then(() => loadStyle("css/icomoon.css"))
        .then(() => {
            alert('All styles are loaded!');
        }).catch(console.error);
}
Run Code Online (Sandbox Code Playgroud)

真的很酷,对吧?这是一种使用 Promise 来决定样式优先级的方法。

要查看多样式加载实现,请参阅:/sf/answers/4475567001/


Joh*_*erg 8

我知道这是一个非常古老的线程,但这是我的5美分.

根据您的需求,还有另一种方法可以做到这一点.

我有一个案例,我希望css文件只活动一段时间.像css切换.激活css然后在另一个事件之后将其取消激活.

不是动态加载css然后删除它,你可以在新css中的所有元素前添加一个Class/an id,然后只需切换css基本节点的class/id(如body标签).

您可以使用此解决方案初始加载更多css文件,但您有一种更动态的切换css布局的方法.


Igl*_*rdo 8

下面是一个单行示例,它使用纯 JavaScript 根据 URL 的文件名部分将 CSS 链接注入到 head 元素中:

document.head.innerHTML += '<link rel="stylesheet" href="css/style.css">';

大多数浏览器都支持它。查看浏览器兼容性


Art*_*sov 7

在现代浏览器中,您可以promise像这样使用。创建一个带有promise的加载器函数:

function LoadCSS( cssURL ) {

    // 'cssURL' is the stylesheet's URL, i.e. /css/styles.css

    return new Promise( function( resolve, reject ) {

        var link = document.createElement( 'link' );

        link.rel  = 'stylesheet';

        link.href = cssURL;

        document.head.appendChild( link );

        link.onload = function() { 

            resolve(); 

            console.log( 'CSS has loaded!' ); 
        };
    } );
}
Run Code Online (Sandbox Code Playgroud)

那么显然您希望在CSS加载后完成一些工作。您可以像这样在CSS加载后调用需要运行的函数:

LoadCSS( 'css/styles.css' ).then( function() {

    console.log( 'Another function is triggered after CSS had been loaded.' );

    return DoAfterCSSHasLoaded();
} );
Run Code Online (Sandbox Code Playgroud)

有用的链接,如果您想深入了解它是如何工作的:

承诺的官方文档

有用的诺言指南

关于诺言的精彩介绍视频


Ani*_*mar 6

来自未来的答案。2022 年,我们拥有用于导入 css 文件的导入断言 api。

import mycss from "./style/mycss.css" assert { type: "css" };
    document.adoptedStyleSheets = [sheet];
    shadowRoot.adoptedStyleSheets = [sheet];
Run Code Online (Sandbox Code Playgroud)

浏览器支持:到 2022 年 9 月,仅支持基于 chromium 的浏览器和 safari。

阅读更多内容: v8 导入断言帖子

tc39 github t39 导入断言提案


Gau*_*thi 5

使用此代码:

var element = document.createElement("link");
element.setAttribute("rel", "stylesheet");
element.setAttribute("type", "text/css");
element.setAttribute("href", "external.css");
document.getElementsByTagName("head")[0].appendChild(element);
Run Code Online (Sandbox Code Playgroud)