gpt4 book ai didi

css - 如何不继承 chrome 扩展内容脚本中的样式

转载 作者:技术小花猫 更新时间:2023-10-29 11:43:09 25 4
gpt4 key购买 nike

我正在编写一个在每个页面上运行内容脚本的 Google Chrome 扩展程序。在我的内容脚本中,我注入(inject)了一个 <div>与一些<ul><li> child 进入页面。我在样式表中为这些元素指定了一些样式。

但我发现在一些随机页面上,我的元素会继承网页上定义的样式,因为我没有为我的 div 指定每个样式属性。

阻止注入(inject)的元素继承这些样式的最佳方法是什么?

在我看来我可以:

  • 在我的样式表中指定每一个样式(例如,通过查看在没有干扰时计算出的样式是什么),或者
  • 我可以把我的 <div><iframe> 里面.但是,自 chrome:// 以来,我将不得不在我的内容脚本的 iframe 和源页面之间传递消息。我的 iframe src 的 URL 和 http://源页面的 url 将被视为跨源。

最佳答案

我会选择第一个选择——完全指定您使用的元素的样式。但这比我想象的要复杂一些。

首先,您必须完全指定容器元素。然后,对于它的后代,你不得不说他们也应该使用默认值或者从他们的父代继承(直到容器)。最后,您必须指定每个其他元素的外观,这样它们就不会都是普通的跨度。

相关的API是getComputedStyleCSSStyleSheet来自 DOM Level 2 Style 的界面.您可以使用除 width 以外的所有值和 height , 应该是 auto默认情况下。您还需要下载默认样式表,例如 Webkit user agent stylesheet .然后你可以调用下面的函数来创建一个完整的样式表,你可以将它注入(inject)到文档中。

请注意,当您将样式表插入目标文档时,您必须使容器选择器尽可能具体,因为网页可能会给出具有更高 specificity 的规则。比你的规则。例如,在 <html id=a><head id=b><style>#a #b * {weird overrides}</style></head> , #a #b *#yourId div 具有更高的特异性将。但我想这并不常见。

注意:出于某种原因,当我加载 CSS 时,Chrome 会给我错误“无法加载资源”,除非它已经在 <link> 中。当前文件的。所以你也应该在调用这个函数的页面中包含 html.css。

// CSS 2.1 inherited prpoerties
var inheritedProperties = [
'azimuth', 'border-collapse', 'border-spacing', 'caption-side',
'color', 'cursor', 'direction', 'elevation', 'empty-cells',
'font-family', 'font-size', 'font-style', 'font-variant',
'font-weight', 'font', 'letter-spacing', 'line-height',
'list-style-image', 'list-style-position', 'list-style-type',
'list-style', 'orphans', 'pitch-range', 'pitch', 'quotes',
'richness', 'speak-header', 'speak-numeral', 'speak-punctuation',
'speak', 'speech-rate', 'stress', 'text-align', 'text-indent',
'text-transform', 'visibility', 'voice-family', 'volume',
'white-space', 'widows', 'word-spacing'];
// CSS Text Level 3 properties that inherit http://www.w3.org/TR/css3-text/
inheritedProperties.push(
'hanging-punctuation', 'line-break', 'punctuation-trim',
'text-align-last', 'text-autospace', 'text-decoration-skip',
'text-emphasis', 'text-emphasis-color', 'text-emphasis-position',
'text-emphasis-style', 'text-justify', 'text-outline',
'text-shadow', 'text-underline-position', 'text-wrap',
'white-space-collapsing', 'word-break', 'word-wrap');
/**
* Example usage:
var fullStylesheet = completeStylesheet('#container', 'html.css').map(
function(ruleInfo) {
return ruleInfo.selectorText + ' {' + ruleInfo.cssText + '}';
}).join('\n');
* @param {string} containerSelector The most specific selector you can think
* of for the container element; e.g. #container. It had better be more
* specific than any other selector that might affect the elements inside.
* @param {string=} defaultStylesheetLocation If specified, the location of the
* default stylesheet. Note that this script must be able to access that
* locatoin under same-origin policy.
* @return {Array.<{selectorText: string, cssText: string}>} rules
*/
var completeStylesheet = function(containerSelector,
defaultStylesheetLocation) {
var rules = [];
var iframe = document.createElement('iframe');
iframe.style.display = 'none';
document.body.appendChild(iframe); // initializes contentDocument
try {
var span = iframe.contentDocument.createElement('span');
iframe.contentDocument.body.appendChild(span);
/** @type {CSSStyleDeclaration} */
var basicStyle = iframe.contentDocument.defaultView.getComputedStyle(span);
var allPropertyValues = {};
Array.prototype.forEach.call(basicStyle, function(property) {
allPropertyValues[property] = basicStyle[property];
});
// Properties whose used value differs from computed value, and that
// don't have a default value of 0, should stay at 'auto'.
allPropertyValues['width'] = allPropertyValues['height'] = 'auto';
var declarations = [];
for (var property in allPropertyValues) {
var declaration = property + ': ' + allPropertyValues[property] + ';';
declarations.push(declaration);
}
// Initial values of all properties for the container element and
// its descendants
rules.push({selectorText: containerSelector + ', ' +
containerSelector + ' *',
cssText: declarations.join(' ')});

// For descendants, some of the properties should inherit instead
// (mostly dealing with text).
rules.push({selectorText: containerSelector + ' *',
cssText: inheritedProperties.map(
function(property) {
return property + ': inherit;'
}).join(' ')});

if (defaultStylesheetLocation) {
var link = iframe.contentDocument.createElement('link');
link.rel = 'stylesheet';
link.href = defaultStylesheetLocation;
iframe.contentDocument.head.appendChild(link);
/** @type {CSSStyleSheet} */
var sheet = link.sheet;
Array.prototype.forEach.call(
sheet.cssRules,
/** @param {CSSStyleRule} cssRule */
function(cssRule) {
rules.push({
selectorText: containerSelector + ' ' + cssRule.selectorText,
cssText: cssRule.style.cssText});
});
}
return rules;
} finally {
document.body.removeChild(iframe);
}
};

关于css - 如何不继承 chrome 扩展内容脚本中的样式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4966030/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com