使用 javascript 在头部注入 css 代码动态编辑 css 好吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21064431/
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
Is it good to edit the css dynamically with javascript injecting css code in the head?
提问by Paolo
Is it "legal" and working cross browser the injection of CSS code in the head in order to set/change permanently the properties of something?
在头部注入 CSS 代码以永久设置/更改某些东西的属性是否“合法”和跨浏览器工作?
For example (using jQuery):
例如(使用 jQuery):
$('head').append('<style>.myclass { background: #f00;}</style>');
I've tried it in Safari 7 and works.
我已经在 Safari 7 中尝试过并且可以正常工作。
Is it ok and cross browser or is a hack to avoid?
可以跨浏览器还是要避免黑客攻击?
Are there any drawbacks?
有什么缺点吗?
回答by Sean Vieira
Yes, it is legal - and it will be faster than $(".myclass").css({background: "#FF0"})
because you only interact with the DOM oncerather than N
times (where N
is the number of .myclass
elements on the page.) Also, it will be applied to future .myclass
elements automatically.
是的,这是合法的 - 并且它会比$(".myclass").css({background: "#FF0"})
因为您只与 DOM 交互一次而不是N
多次(页面上的元素N
数量在哪里)更快.myclass
。此外,它将.myclass
自动应用于未来的元素。
The disadvantage is that you canrun into specificity issues, so you have to make sure to architect your CSS in a way that will ensure that you can override the background with a single class selector. (jQuery's css
function, since it sets the element's style
attribute directly, has some of the highest specificity by default and so avoids this particular problem).
缺点是您可能会遇到特殊性问题,因此您必须确保以一种方式构建 CSS,以确保您可以使用单个类选择器覆盖背景。(jQuery 的css
函数,因为它style
直接设置元素的属性,默认情况下具有一些最高的特异性,因此避免了这个特殊问题)。
For example, if you had this CSS somewhere in your linked styles:
例如,如果您在链接样式的某处有这个 CSS:
#some-id .myclass { background: #000; }
then the DOM-heavy $(".myclass").css
would override the background, while the dynamically injected style (injecting just .myclass { background: #FF0; }
would not).
那么 DOM-heavy$(".myclass").css
会覆盖背景,而动态注入的样式(注入.myclass { background: #FF0; }
不会)。
The other disadvantage is that old-IE (<=8) only allows you to create 31 of these "dynamic" style sheets. In IE >= 9, this is not a problem.
另一个缺点是旧的 IE (<=8) 只允许您创建 31 个这些“动态”样式表。在 IE >= 9 中,这不是问题。
回答by Simone Conti
I think you are facing a 4 solutions scenario.
我认为您正面临 4 个解决方案场景。
None of these is either really elegant or perfect, but here are my 2 cents:
这些都不是真正优雅或完美的,但这是我的 2 美分:
Inject the css in the head section of your HTML
This is exactly what you suggested in your question. This solution works well, but only if the modification occurs once. If you need to apport many subsequent modification the head section of your HTML might become crowded.
You can detect the insertion of the DOM objects with Javascript and keep them in-sync
Here you are a JSFiddle that does exactly this: http://jsfiddle.net/ITnok/9FQVa/28/
This solution works fine if you (and may be your user) are supposed to do many changes spread in time, BUT only if you have control on DOM object insertion: the key is to create a custom event to trigger each time you insert a new object.
Here the chunk of code from the JSFiddle that handle the custom event:
// This event is the key to keep CSS in sync... in realtime! $( document ) .on( 'mickeymouseadded', '.mickeymouse', function( e ) { $( this ) .attr( 'style', $( this ) .siblings( ':first' ) .attr( 'style' ) ); } );
You can use MutationObserver (new version of old and deprecated Mutation Events)
Here you are the link to the documentation: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
This is an awesome way to handle the problem, but unfortunately it is not compatible with old version of Interdict Exploder (Oops, sorry for the trolling! :-) ). Only IE11 supports them.
This method works even if object insertion is out of your direct control, you are not able to create custom events or do not want to.
You can use a jQuery plugin called livequery
Here you are the link to the Github repo of jQuery livequery: https://github.com/brandonaaron/livequery
Never tried this very plugin, but it looks like it might be a good solution to query the DOM and identify what need to be modified and kept in-sync.
在 HTML 的 head 部分注入 css
这正是您在问题中所建议的。此解决方案效果很好,但前提是修改发生一次。如果您需要进行许多后续修改,则 HTML 的头部部分可能会变得拥挤。
您可以使用 Javascript 检测 DOM 对象的插入并使它们保持同步
在这里,您是一个 JSFiddle,它正是这样做的:http: //jsfiddle.net/ITnok/9FQVa/28/
如果您(并且可能是您的用户)应该及时进行许多更改,则此解决方案可以正常工作,但前提是您可以控制 DOM 对象插入:关键是创建一个自定义事件以在每次插入新事件时触发目的。
这是来自处理自定义事件的 JSFiddle 的代码块:
// This event is the key to keep CSS in sync... in realtime! $( document ) .on( 'mickeymouseadded', '.mickeymouse', function( e ) { $( this ) .attr( 'style', $( this ) .siblings( ':first' ) .attr( 'style' ) ); } );
您可以使用 MutationObserver(旧的和已弃用的 Mutation Events 的新版本)
这是文档的链接:https: //developer.mozilla.org/en-US/docs/Web/API/MutationObserver
这是处理问题的绝佳方法,但不幸的是它与旧版本的 Interdict Exploder 不兼容(哎呀,对不起!:-))。只有 IE11 支持它们。
即使对象插入不受您的直接控制,您也无法创建自定义事件或不想创建自定义事件,此方法仍然有效。
您可以使用名为 livequery 的 jQuery 插件
这是 jQuery livequery 的 Github 存储库的链接:https: //github.com/brandonaaron/livequery
从来没有尝试过这个插件,但看起来它可能是一个很好的解决方案来查询 DOM 并确定需要修改的内容并保持同步。
All these solution are based on the presence of Javascript
所有这些解决方案都基于 Javascript 的存在
but as far as I know from what you told us this would not be an issue for you! ;-)
但据我所知,你告诉我们这对你来说不是问题!;-)
Hope it helps...
希望能帮助到你...
回答by Pierre Emmanuel Lallemant
If the user disabled javascript in his browser (faster to load pages), it should be a problem.
如果用户在他的浏览器中禁用了 javascript(加载页面更快),这应该是一个问题。
You should:
你应该:
- write the fixed css of your site in the css files
- use js only if you have some parsing to do (if you want to insert in each
<span class="to_change">...</span>
some css per example).
- 在 css 文件中写入站点的固定 css
- 仅当您需要进行一些解析时才使用 js(如果您想在每个
<span class="to_change">...</span>
示例中插入一些 css)。