使用 Javascript 将 CSS 样式表作为字符串注入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15505225/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Inject CSS stylesheet as string using Javascript
提问by Dan Hlavenka
I'm developing a Chrome extension, and I'd like users to be able to add their own CSS styles to change the appearance of the extension's pages (not web pages). I've looked into using document.stylesheets
, but it seems like it wants the rules to be split up, and won't let you inject a complete stylesheet. Is there a solution that would let me use a string to create a new stylesheet on a page?
我正在开发一个 Chrome 扩展程序,我希望用户能够添加他们自己的 CSS 样式来更改扩展程序页面(而不是网页)的外观。我已经研究过 using document.stylesheets
,但它似乎想要拆分规则,并且不会让您注入完整的样式表。有没有一种解决方案可以让我使用字符串在页面上创建新的样式表?
I'm currently not using jQuery or similar, so pure Javascript solutions would be preferable.
我目前没有使用 jQuery 或类似的,所以纯 Javascript 解决方案会更可取。
回答by Liam Newmarch
There are a couple of ways this could be done, but the simplest approach is to create a <style>
element, set its textContentproperty, and append to the page's <head>
.
有几种方法可以做到这一点,但最简单的方法是创建一个<style>
元素,设置它的textContent属性,然后附加到页面的<head>
.
/**
* Utility function to add CSS in multiple passes.
* @param {string} styleString
*/
function addStyle(styleString) {
const style = document.createElement('style');
style.textContent = styleString;
document.head.append(style);
}
addStyle(`
body {
color: red;
}
`);
addStyle(`
body {
background: silver;
}
`);
If you want, you could change this slightly so the CSS is replaced when addStyle()
is called instead of appending it.
如果需要,您可以稍微更改此设置,以便在addStyle()
调用时替换 CSS,而不是附加它。
/**
* Utility function to add replaceable CSS.
* @param {string} styleString
*/
const addStyle = (() => {
const style = document.createElement('style');
document.head.append(style);
return (styleString) => style.textContent = styleString;
})();
addStyle(`
body {
color: red;
}
`);
addStyle(`
body {
background: silver;
}
`);
IE edit:Be aware that IE9 and below only allows up to 32 stylesheets, so watch out when using the first snippet. The number was increased to 4095 in IE10.
IE 编辑:请注意 IE9 及以下版本最多只允许32 个样式表,因此在使用第一个代码段时要小心。这个数字在 IE10 中增加到 4095。
2020 edit:This question is very old but I still get occasional notifications about it so I've updated the code to be slightly more modern and replaced .innerHTML
with .textContent
. This particular instance is safe, but avoiding innerHTML
where possible is a good practice since it can be an XSS attack vector.
2020 年编辑:这个问题很老了,但我仍然偶尔会收到有关它的通知,所以我更新了代码,使其更现代,并替换.innerHTML
为.textContent
. 这个特定的实例是安全的,但innerHTML
尽可能避免是一种很好的做法,因为它可能是 XSS 攻击媒介。
回答by John R Perry
Thanks to this guy, I was able to find the correct answer. Here's how it's done:
多亏了这个人,我才能找到正确的答案。这是它的完成方式:
function addCss(rule) {
let css = document.createElement('style');
css.type = 'text/css';
if (css.styleSheet) css.styleSheet.cssText = rule; // Support for IE
else css.appendChild(document.createTextNode(rule)); // Support for the rest
document.getElementsByTagName("head")[0].appendChild(css);
}
// CSS rules
let rule = '.red {background-color: red}';
rule += '.blue {background-color: blue}';
// Load the rules and execute after the DOM loads
window.onload = function() {addCss(rule)};
fiddle
小提琴
回答by Pat Cullen
I had this same need recently and wrote a function to do the same as Liam's, except to also allow for multiple lines of CSS.
我最近也有同样的需求,并编写了一个与 Liam 相同的函数,除了还允许多行 CSS。
injectCSS(function(){/*
.ui-button {
border: 3px solid #0f0;
font-weight: bold;
color: #f00;
}
.ui-panel {
border: 1px solid #0f0;
background-color: #eee;
margin: 1em;
}
*/});
// or the following for one line
injectCSS('.case2 { border: 3px solid #00f; } ');
The source of this function. You can downloadfrom the Github repo. Or see some more example usage here.
这个函数的来源。您可以从Github 存储库下载。或者在此处查看更多示例用法。
My preference is to use it with RequireJS, but it also will work as a global function in the absence of an AMD loader.
我更喜欢将它与 RequireJS一起使用,但它也可以在没有 AMD 加载器的情况下作为全局函数工作。