在正文中使用 javascript 将样式表添加到 Head

IT技术 javascript css
2021-01-29 16:00:38

我正在使用阻止我们编辑头部部分的 CMS。我需要将 css 样式表添加到站点,紧跟在标签之后。有没有办法用 JS 做到这一点,我可以在页面底部添加一个脚本(我可以在标签之前添加脚本),然后将样式表注入头部?

4个回答

更新:根据规范link正文中不允许元素。但是,大多数浏览器仍然可以很好地呈现它。因此,要回答评论中的问题 - 确实必须添加linkhead页面的 ,而不是body.

function addCss(fileName) {

  var head = document.head;
  var link = document.createElement("link");

  link.type = "text/css";
  link.rel = "stylesheet";
  link.href = fileName;

  head.appendChild(link);
}

addCss('{my-url}');

或者使用 jquery 更容易一点

function addCss(fileName) {
   var link = $("<link />",{
     rel: "stylesheet",
     type: "text/css",
     href: fileName
   })
   $('head').append(link);
}

addCss("{my-url}");

原答案

您不一定需要将其添加到头部,只需将其添加到 body 标签的末尾即可。

$('body').append('<link rel="stylesheet" type="text/css" href="{url}">')

正如 Juan Mendes 提到的,您可以将样式表插入头部

$('head').append('<link rel="stylesheet" type="text/css" href="{url}">')

没有 jQuery 也是一样(见上面的代码)

嗨,vittore,我在 </body> 标签之前添加了您提到的第二个脚本,但是,它似乎没有在 head 部分加载 CSS... 想法?主要问题是我们正在创建一个新的样式表来覆盖 CMS 强制我们使用的样式表。所以我们创建了一个新的样式表来覆盖他们的设置。我们希望它在加载他们的样式表后立即加载......否则,他们的样式表会加载并显示站点,然后几秒钟后,我们的更改就会显示出来......
2021-03-14 16:00:38
我尝试了将链接元素附加到头部的方法,发现它有效,但是,这会导致浏览器中出现非常明显的闪烁,因为所有内容都被重新渲染。我在谷歌浏览器上观察到了这一点,但所有不同浏览器的用户都报告了它。我在两个不同的产品中尝试了这个,结果相同,它们都有非常不同的 HTML,这表明无论存在什么 HTML,都会发生flash。长话短说,我不建议将链接添加到头部。
2021-03-14 16:00:38
您可以使用几乎相同的东西将其附加到头部。
2021-03-23 16:00:38
@Juan Mendes,我知道,但我要说的是它只能插入体内
2021-03-28 16:00:38
有谁知道,作为最佳实践或性能,这两个变体(头部与身体中的动态 css)之间有什么不同吗?
2021-04-13 16:00:38

这将以一种智能的方式做你想做的事。也使用纯JS。

function loadStyle(href, callback){
    // avoid duplicates
    for(var i = 0; i < document.styleSheets.length; i++){
        if(document.styleSheets[i].href == href){
            return;
        }
    }
    var head  = document.getElementsByTagName('head')[0];
    var link  = document.createElement('link');
    link.rel  = 'stylesheet';
    link.type = 'text/css';
    link.href = href;
    if (callback) { link.onload = function() { callback() } }
    head.appendChild(link);
}
赞成考虑可能会添加多个样式表的用例。我为我的特定场景使用了 index of 以使其正常工作,还必须检查 null 因为某种原因其中一个 href 为 null。if (document.styleSheets[i].href != null && document.styleSheets[i].href.indexOf(href) != -1)
2021-04-07 16:00:38
我已经编辑以i在 for 循环中添加缺少的内容:if(document.styleSheets[i].href == href){
2021-04-09 16:00:38
解决方案也是通过JS控制渲染。就像之前加载 css 一样,它用于加载什么。您可以添加回调参数并在函数内放置一个 onload 事件。这将告诉您何时可以使用。框架、脚本等其他元素也是如此。
2021-04-09 16:00:38
我尝试了将链接元素附加到头部的方法,发现它有效,但是,这会导致浏览器中出现非常明显的闪烁,因为所有内容都被重新渲染。我在谷歌浏览器上观察到了这一点,但所有不同浏览器的用户都报告了它。我在两个不同的产品中尝试了这个,结果相同,它们都有非常不同的 HTML,这表明无论存在什么 HTML,都会发生flash。长话短说,我不建议将链接添加到头部
2021-04-13 16:00:38

我修改Eddie的功能来删除切换样式表或关闭。它还将返回样式表的当前状态。这很有用,例如,如果您想在您的网站上为视障用户设置一个切换按钮,并且需要将他们的偏好保存在 cookie 中。

function toggleStylesheet( href, onoff ){
    var existingNode=0 //get existing stylesheet node if it already exists:
    for(var i = 0; i < document.styleSheets.length; i++){
        if( document.styleSheets[i].href && document.styleSheets[i].href.indexOf(href)>-1 ) existingNode = document.styleSheets[i].ownerNode
    }
    if(onoff == undefined) onoff = !existingNode //toggle on or off if undefined
    if(onoff){ //TURN ON:
        if(existingNode) return onoff //already exists so cancel now
        var link  = document.createElement('link');
        link.rel  = 'stylesheet';
        link.type = 'text/css';
        link.href = href;
        document.getElementsByTagName('head')[0].appendChild(link);
    }else{ //TURN OFF:
        if(existingNode) existingNode.parentNode.removeChild(existingNode)
    }
    return onoff
}

示例用法:

toggleStylesheet('myStyle.css') //toggle myStyle.css on or off

toggleStylesheet('myStyle.css',1) //add myStyle.css

toggleStylesheet('myStyle.css',0) //remove myStyle.css
显然这是一个选项,第二次打开会快一点,但这需要函数中的第三种情况来处理已经存在于禁用状态的样式表,所以函数会更长一点。
2021-03-23 16:00:38
如何使用.disabled样式表上的标准属性打开/关闭它
2021-04-12 16:00:38

您可以在现代浏览器中使用纯 JavaScript 并保持优雅。

const range = document.createRange()
const frag = range.createContextualFragment(`THE CONTENT IS THE SAME AS THE HTML.`)
document.querySelector("YOUR-NODE").append(frag) 

添加任何 HTML 代码非常容易。

文档

示例 1

通过javascript在头部添加样式。

<head></head><body><button class="hover-danger">Hello World</button></body>
<script>
  const range = document.createRange()
  const frag = range.createContextualFragment(`
<style>
  .hover-danger:hover{
    background-color: red;
    font-weight: 900
  }
</style>
`
)
  document.querySelector("head").append(frag)  
</script>

示例 2

导入 CSS、JS 并修改现有样式表。

<head></head>
<body><button class="btn btn-primary hover-danger">Hello world</button></body>

<script>
  const range = document.createRange()
  const frag = range.createContextualFragment(`
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"/>
`)
  document.querySelector("head").append(frag)

  window.onload = () => {
    // 👇 If you don't want to import the new source, you can consider adding the data to exists source.
    const nodeLink = document.querySelector(`link[href^="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css"]`) // ^: match begin with my input
    if (nodeLink)  { // !== null
      const stylesheet = nodeLink.sheet
      const myCSS = `
background-color:red;
font-weight: 900;
`
      stylesheet.insertRule(`.hover-danger:hover{ ${myCSS} }`, stylesheet.cssRules.length)
    }
  }
</script>

📙你必须有权限直接修改CSS

如果您收到错误:

无法从“CSSStyleSheet”读取“cssRules”属性:无法访问规则,

那么你可以参考:https : //stackoverflow.com/a/49994161/9935654

非常感谢,这是我觉得最好的答案。
2021-03-25 16:00:38