使用Javascript将CSS样式表作为字符串注入
Inject CSS stylesheet as string using Javascript
我正在开发一个Chrome扩展,我希望用户能够添加自己的CSS样式来改变扩展的页面(不是网页)的外观。我已经研究过使用document.stylesheets
,但它似乎希望将规则分开,并且不允许您注入完整的样式表。有没有一种解决方案可以让我使用字符串在页面上创建新的样式表?
我目前没有使用jQuery或类似的,所以纯Javascript解决方案将是可取的。
有几种方法可以做到这一点,但最简单的方法是创建一个<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;
}
`);
如果你想,你可以稍微改变一下,当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:请注意IE9及以下版本只允许最多32个样式表,所以在使用第一个代码片段时要小心。在IE10中增加到4095。
2020编辑:这个问题是非常古老的,但我仍然偶尔得到关于它的通知,所以我已经更新了代码稍微更现代,并用.textContent
取代了.innerHTML
。这个特定的实例是安全的,但是尽可能避免innerHTML
是一个很好的实践,因为它可能是一个XSS攻击向量。
多亏了这个家伙,我才能找到正确的答案。如下所示:
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)};
小提琴
你听说过诺言吗?它们适用于所有现代浏览器,使用起来相对简单。看一下这个将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来决定样式优先级的方法。
或者,如果你想同时导入所有的样式,你可以这样做:
function loadStyles(srcs) {
let promises = [];
srcs.forEach(src => promises.push(loadStyle(src)));
return Promise.all(promises);
}
像这样使用:
loadStyles([
'css/style.css',
'css/icomoon.css'
]);
你可以实现你自己的方法,比如按优先级导入脚本,同时导入脚本,或者同时导入样式和脚本。如果我得到更多的投票,我将公布我的实现。
如果你想了解更多关于Promises的信息,请点击这里阅读
我认为最简单的方式注入任何HTML字符串是通过:insertAdjacentHTML
// append style block in <head>
const someStyle = `
<style>
#someElement { color: green; }
</style>
`;
document.head.insertAdjacentHTML('beforeend', someStyle);
我最近也有同样的需求,并编写了一个函数来做与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; } ');
该函数的源代码。你可以从Github仓库下载。或者在这里查看更多示例用法。
我的偏好是将它与RequireJS一起使用,但在没有AMD加载器的情况下,它也可以作为全局函数使用。
创建一个style
标签,并将css样式作为字符串添加到textContent
属性中。将这些附加在文档头部。你就可以走了。
var styles = document.createElement("style");
styles.setAttribute("type", "text/css");
styles.textContent = `#app{background-color:lightblue;}`;
document.head.appendChild(styles);
- 如何在JavaScript中将字符串转换为函数引用
- jQuery中是否内置了任何字符串格式化函数
- 注入的HTML仅在Dom中解释为字符串
- 用PHP到javascript的引号注入一个字符串
- 在特定的HTML元素中注入并执行JavaScript字符串
- 使用C#在BHO中注入javascript-如何正确地转义字符串
- 如何将字符串注入 Android WebView
- Javascript eval() for Json 字符串注入了全局作用域函数
- 注入脚本以播放音频文件,如果 InnerText 与字符串不匹配
- 我应该使用哪种方法注入javascript?(字符串ByEvaluatingJavaScriptFromString)
- Angular UI-Router最小化错误-如何将Resolve语法改为基于字符串注入
- 在找到的字符串后面注入HTML并保留原始HTML
- AngularJS -从模型中注入字符串到HTML's标签名
- Javascript HTML字符串-注入到文档中
- 在jquery ajax调用中注入JSON字符串中的回调函数
- 使用Javascript将CSS样式表作为字符串注入
- 我如何使用切片javascript函数注入字符串到表单字段
- 如何解析URL查询字符串,然后将解析后的变量注入HTMLDOM
- 如何在JavaScript字符串中注入变量
- Windows 8应用程序- Webview控件(c#).注入JavaScript来改变用户代理字符串