359

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

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

4

19 回答 19

490

这是“老派”的做法,希望它适用于所有浏览器。理论上,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);
}

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

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

香草JS

head这是一个使用纯 JavaScript根据 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>

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

于 2009-02-23T09:25:35.197 回答
81

如果你使用 jquery:

$('head').append('<link rel="stylesheet" type="text/css" href="style.css">');
于 2015-10-28T09:13:53.110 回答
55

我想像这个脚本这样的东西会做:

<script type="text/javascript" src="/js/styles.js"></script>

该 JS 文件包含以下语句:

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

如果要引用您的站点,则 javascript 和 css 的地址必须是绝对地址。

这篇“用分支技术对 CSS hacks 说不”一文讨论了许多 CSS 导入技术。

但是“使用 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);
}
//]]>
于 2009-02-22T13:56:26.863 回答
31

Element.insertAdjacentHTML有很好的浏览器支持,可以一行添加一个样式表。

document.getElementsByTagName("head")[0].insertAdjacentHTML(
    "beforeend",
    "<link rel=\"stylesheet\" href=\"path/to/style.css\" />");
于 2018-06-12T17:22:21.637 回答
16

如果您想知道(或等待)直到样式本身已加载,这可行:

// 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);
  });
};
于 2016-12-02T14:01:30.417 回答
12

在现代浏览器中,您可以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!' ); 
        };
    } );
}

那么显然你想要在 CSS 加载后完成一些事情。您可以像这样调用 CSS 加载后需要运行的函数:

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

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

    return DoAfterCSSHasLoaded();
} );

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

关于 Promise 的官方文档

有用的承诺指南

关于承诺的精彩介绍视频

于 2018-07-05T03:41:21.140 回答
11

使用此代码:

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);
于 2017-09-27T04:17:58.460 回答
10

我知道这是一个很老的话题,但我的 5 美分来了。

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

我有一个案例,我希望一个 css 文件只激活一段时间。就像css切换一样。激活 css,然后在另一个事件之后将其停用。

您可以在新 css 中的所有元素前面添加一个类/一个 id,而不是动态加载 css 然后将其删除,然后只需切换 css 基节点的类/id(如 body 标记)。

使用此解决方案,您最初会加载更多的 css 文件,但您有一种更动态的方式来切换 css 布局。

于 2012-01-25T08:04:50.463 回答
6

你听说过承诺吗?它们适用于所有现代浏览器,并且使用起来相对简单。看看这个将 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);
    });
}

您可以按如下方式实现它:

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(err => alert(err));
}

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

要查看多样式加载实现,请参阅:https ://stackoverflow.com/a/63936671/13720928

于 2020-11-04T16:47:15.150 回答
4

有一个通用的 jquery 插件,可以按需加载 css 和 JS 文件同步和异步。它还跟踪已经加载的内容:) 请参阅:http ://code.google.com/p/rloader/

于 2010-12-12T12:01:58.723 回答
4

这是 jQuery 的元素创建方法(我的偏好)和回调的一种方式onLoad

var css = $("<link>", {
  "rel" : "stylesheet",
  "type" :  "text/css",
  "href" : "style.css"
})[0];

css.onload = function(){
  console.log("CSS IN IFRAME LOADED");
};

document
  .getElementsByTagName("head")[0]
  .appendChild(css);
于 2014-10-22T18:18:32.587 回答
4

下面是用于加载 JS 和/或 CSS 的完整代码

function loadScript(directory, files){
  var head = document.getElementsByTagName("head")[0]
  var done = false
  var extension = '.js'
  for (var file of files){ 
    var path = directory + file + extension 
    var script = document.createElement("script")
    script.src = path        
    script.type = "text/javascript"
    script.onload = script.onreadystatechange = function() {
        if ( !done && (!this.readyState ||
            this.readyState == "loaded" || this.readyState == "complete") ) {
            done = true
            script.onload = script.onreadystatechange = null   // cleans up a little memory:
            head.removeChild(script)  // to avoid douple loading
        }
  };
  head.appendChild(script) 
  done = false
 }
}

function loadStyle(directory, files){
  var head = document.getElementsByTagName("head")[0]
  var extension = '.css'
  for (var file of files){ 
   var path = directory + file + extension 
   var link = document.createElement("link")
   link.href = path        
   link.type = "text/css"
   link.rel = "stylesheet" 
   head.appendChild(link) 
 }
}

(() => loadScript('libraries/', ['listen','functions', 'speak', 'commands', 'wsBrowser', 'main'])) ();
(() => loadScript('scripts/', ['index'])) ();

(() => loadStyle('styles/', ['index'])) ();
于 2016-09-06T12:08:12.260 回答
3

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

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

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

于 2020-09-16T18:52:40.883 回答
2

你可以使用这个YUI 库或者使用这篇文章来实现

于 2009-02-22T13:59:34.390 回答
2

YUI 库可能是您正在寻找的。它还支持跨域加载。

如果你使用 jquery,这个插件会做同样的事情。

于 2009-02-22T14:04:31.023 回答
1

我想分享另一种方法,不仅可以加载 css,还可以加载所有资产(js、css、图像)并处理一堆文件的onload事件。async-assets-loader。请参见下面的示例:

<script src="https://unpkg.com/async-assets-loader"></script>
<script>
var jsfile = "https://code.jquery.com/jquery-3.4.1.min.js";
var cssfile = "https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css";
var imgfile = "https://logos.keycdn.com/keycdn-logo-black.png";
var assetsLoader = new asyncAssetsLoader();
assetsLoader.load([
      {uri: jsfile, type: "script"},
      {uri: cssfile, type: "style"},
      {uri: imgfile, type: "img"}
    ], function () {
      console.log("Assets are loaded");
      console.log("Img width: " + assetsLoader.getLoadedTags()[imgfile].width);
    });
</script> 

根据async-assets-loader文档

于 2019-11-26T18:42:43.773 回答
1
var elem = document.createElement('link');
elem.rel = ' stylesheet'
elem.href= 'style.css';//Link of the css file
document.head.appendChild(elem);
于 2020-07-31T10:36:48.390 回答
0
var fileref = document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("th:href", "@{/filepath}")
fileref.setAttribute("href", "/filepath")

我正在使用百里香,这很好用。谢谢

于 2014-10-21T04:45:23.740 回答
0

采用:

document.getElementById("of head/body tag")
        .innerHTML += '<link rel="stylesheet" type="text/css" href="style.css">';
于 2020-08-10T20:04:57.493 回答