简体   繁体   English

防止现有的 CSS 样式注入 HTML/CSS

[英]Prevent existing CSS from styling injected HTML/CSS

I'm working on a project which injects JS+CSS+HTML over web pages which I do not have control over.我正在开发一个项目,该项目在我无法控制的 web 个页面上注入 JS+CSS+HTML。

I am concerned about the host page styling my injected code -- I want my injected code to only obey my styling, and not theirs.我担心主机页面为我注入的代码设置样式——我希望我的注入代码只遵循我的样式,而不是他们的。

At the moment the only method to do this I can think of involves explicitly specifying every possible tag for the container <div> 's class (using pre-defined, known browser defaults) and relying on inheritance for those rules to propagate down to the rest of my injected HTML. This CSS would need to appear at the bottom of the page's <head> tag.目前,我能想到的唯一方法是为容器<div>的 class 明确指定每个可能的标签(使用预定义的已知浏览器默认值),并依靠 inheritance 将这些规则传播到我注入的 rest HTML。这个 CSS 需要出现在页面的<head>标记的底部。

I don't think that's the best solution, though, and I don't look forward to implementing it.不过,我认为这不是最好的解决方案,我也不期待实施它。 Surely there are better ways.当然有更好的方法。

Others have suggested very good ways to prevent your CSS from affecting the page's, as well as making sure that your CSS takes precedence, but you seem most concerned with the page's CSS affecting you - that is, adding a funky, unexpected style (like making all divs have a pink background). 其他人提出了很好的方法来防止你的CSS影响页面,并确保你的CSS优先,但你似乎最关心的是影响你的页面的CSS - 也就是说,添加一个时髦,意想不到的风格(如制作所有div都有粉红色的背景)。

The only way I can think for you to prevent their styling from affecting your injected code would be for you to sandbox what you've injected, like in an iframe . 我能想到的唯一方法是阻止他们的样式影响你注入的代码,这将是你沙盒你注入的东西,比如在iframe Otherwise there's simply too many things that you'd have to define - you'd have to define every single style ( padding , border , margin , background ... the list goes on and on) on the " * " selector (or better yet, " #yourid * ", so you just override your own content), just so that you can guarantee absolute control over your CSS. 否则你需要定义的东西太多了 - 你必须在“ * ”选择器上定义每个单独的样式( paddingbordermarginbackground ......列表继续)(或者更好)但是,“ #yourid * ”,所以你只需覆盖自己的内容),这样你就可以保证对CSS的绝对控制。

Edit: I realize that the latter solution wouldn't necessarily be too painful, if you're using the omni-selector to reset everything to a baseline: 编辑:我意识到如果您使用全向选择器将所有内容重置为基线,后一种解决方案不一定会太痛苦:

#myid * {
    somestyle1: default;
    somestyle2: default;
    ... 
}

I've found someone who has written up such a solution . 我发现有人写了这样的解决方案 If you scroll down far enough on the page, you'll see it (from SuzyUK). 如果你在页面上向下滚动足够远,你会看到它(来自SuzyUK)。 It doesn't look complete, but is a good start for sure. 它看起来并不完整,但肯定是一个好的开始。

(I, too, would be interested to know if there's a good way to prevent this. I've written Greasemonkey scripts before that injects code onto the page, and have had to write CSS to override the page's CSS, but in those cases I knew who my target was and could tailor my CSS directly towards the page.) (我也有兴趣知道是否有一种防止这种情况的好方法。我在编写Greasemonkey脚本之前将代码注入页面,并且必须编写CSS来覆盖页面的CSS,但在那些情况下我知道我的目标是谁,可以直接在页面上定制我的CSS。)

Wrap your injected HTML with a specifically-classed <div> , such as 用特定分类的<div>包装您注入的HTML,例如

<div class="my-super-specialized-unique-wrapper"><!--contents--></div>

Then in your CSS, prefix all rules with .my-super-specialized-unique-wrapper and use !important on every rule. 然后在你的CSS中,使用.my-super-specialized-unique-wrapper所有规则添加前缀,并在每个规则上使用!important That will instruct the client browser to treat your rule as supreme for any elements which match, regardless of any other styles that might target them - even if other rules outside your control are more-specific. 这将指示客户端浏览器将您的规则视为匹配的任何元素的最高要求,而不管可能针对它们的任何其他样式 - 即使您控制之外的其他规则更具体。

You'll just have to be very specific with your CSS selectors. 你只需要对CSS选择器非常具体 That is, much more specific than the host page's CSS rules. 也就是说,比主页的CSS规则更具体。 You might also want to add a kind of global CSS reset modified to only reset your HTML. 您可能还希望添加一种全局CSS重置修改为仅重置HTML。 By that, I mean something which resets all colours, backgrounds, fonts, padding, etc, back to a single standard. 通过这种方式,我的意思是将所有颜色,背景,字体,填充等重置为单一标准。 From there you can build up your own styles. 从那里你可以建立自己的风格。

Why not injecting html elements with inline formatting like this: 为什么不用这样的内联格式注入html元素:

<p style="color:red">This to be injected</p>

inline styling takes precedence over any other rule, and you're already creating the markup in order to insert it. 内联样式优先于任何其他规则,并且您已经创建了标记以便插入它。

Other solution would be to use very specific DOM id's on your elements and then styling them on your added CSS 其他解决方案是在元素上使用非常特定的 DOM id,然后在添加的CSS上设置样式

I'm not sure how should it be used, of the browser support for this, but it is one of the main causes to use http://www.w3.org/TR/shadow-dom/ 我不确定应该如何使用浏览器支持,但它是使用http://www.w3.org/TR/shadow-dom/的主要原因之一

The idea is that you could insert a web-component, that can be fully styled and have specific events that only affect the shadow-DOM (so your module will not affect the rest of the page). 我们的想法是您可以插入一个Web组件,该组件可以完全设置样式并具有仅影响shadow-DOM的特定事件(因此您的模块不会影响页面的其余部分)。

Te best is to use iframe instead of injection html string.最好是使用 iframe 而不是注入 html 字符串。

If you're using a Mozilla browser you can actually (if illegally) add visible DOM content to the <html> element outside the <body> element. 如果您使用的是Mozilla浏览器,实际上(如果是非法的话)可以将可见的DOM内容添加到<body>元素之外的<html>元素中。 This will avoid any styles that match on body and are inherited by your content. 这将避免任何与正文相匹配且由您的内容继承的样式。 It may be possible that some styles match on html, which would defeat this technique, but I've found it useful. 有些样式可能会匹配html,这会打败这种技术,但我发现它很有用。

eg. 例如。 using jquery: $('html').append('<div id="mycontent"> blah blah blah </div>'); 使用jquery:$('html')。append('<div id =“mycontent”> blah blah blah </ div>');

Using a popular library is itself a challenge when you don't want your instance of the library to interfere with the uses of the library defined by the pages you're modifying. 当您不希望库的实例干扰您正在修改的页面定义的库的使用时,使用流行的库本身就是一个挑战。 Greasemonkey's '@require' didn't work for me. Greasemonkey的'@require'对我不起作用。 I found it necessary (but possible!) to save any existing values of the two or three global names assigned by the jquery script, insert my instance of the library into the DOM, wait for it to be loaded (had to use a timer, that's annoying but I couldn't see a way around it), cache the values assigned to the globals within my own namespace for my own use, and restore the saved ones. 我发现有必要(但可能!)保存由jquery脚本分配的两个或三个全局名称的任何现有值,将我的库实例插入DOM,等待它被加载(必须使用计时器,这很烦人,但我看不到它的方法),缓存分配给我自己的命名空间中的全局变量的值供我自己使用,并恢复保存的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM