CSS 在 chrome 扩展中修复了 positioning/z-index

CSS fixed positioning/z-index in chrome extension

我正在构建一个 Chrome 扩展,在单击固定在浏览器右侧的黄色条后,它会从浏览器 window 的右侧滑动。当我点击黄色条时,绿色和黄色条会滑动。黄色的是正确的 "on the top" 页面 - 它覆盖了页面的内容。不幸的是,滑动后的绿色在某些页面元素下。例如,在 Whosebug 网站上,搜索 window、提问按钮和类似问题部分下方有一个绿色条。我该如何解决?

manifest.json

{
"manifest_version":         2,
"content_scripts":          [ {
    "js":       [ "injection.js", "jquery.js",  "jquery-ui.min.js"],
    "matches":  [   "http://whosebug.com/questions/*"
    ]
} ],
"description":              "Inject a complete, premade web page",
"name":                     "Inject whole web page",
"version":                  "1",
"web_accessible_resources": ["test.css", "jquery-ui.min.css"]
}

test.css

#intro_button {
background-color: yellow;
height : 100%;
width : 100px;
top: 0;
right: 0;
position : fixed;
cursor: pointer;    
}
#extension {
height: 100%;
width: 200px;
position: fixed;
right: -200px;
background-color: green;
}

injection.js

// Injecting button (div)
var divElement = document.createElement("DIV");
divElement.id = "intro_button";
divElement.style.right = "0px";
divElement.onclick = function () {
    if (this.style.right === "0px") {
        $(this).animate({ "right": "+=200" }, 800);
        $("#extension").animate({ "right": "+=200" }, 800);
    }
    else if (this.style.right === "200px") {
        $(this).animate({ "right": "-=200" }, 800);
        $("#extension").animate({ "right": "-=200" }, 800);
    }
}
var textnode = document.createTextNode("zzz");    
divElement.appendChild(textnode);
document.body.appendChild(divElement, document.body.firstChild);

// Injecting extenion (div)
var divExtension = document.createElement("DIV");
divExtension.id = "extension";
var textnode = document.createTextNode("yyy");
divExtension.appendChild(textnode);
document.body.insertBefore(divExtension, document.body.firstChild);

// Injecting CSS files
var head  = document.getElementsByTagName('head')[0];
var link  = document.createElement('link');
link.rel  = 'stylesheet';
link.type = 'text/css';
link.href = chrome.extension.getURL('test.css');
head.appendChild(link);

var head  = document.getElementsByTagName('head')[0];
var link  = document.createElement('link');
link.rel  = 'stylesheet';
link.type = 'text/css';
link.href = chrome.extension.getURL('jquery-ui.min.css');
head.appendChild(link);

// Injecting Jqueries
var s  = document.createElement('script');
s.src = "jquery.js";
document.getElementsByTagName("head")[0].appendChild(s);

var s  = document.createElement('script');
s.src = "jquery-ui.min.js";
document.getElementsByTagName("head")[0].appendChild(s);

通常这是通过向定位元素添加 z-index: 9999999 CSS 属性 来解决的(如果您可以控制其他元素的 z 顺序,则添加更合理的数字)。

为什么会这样?

不正确分层的元素被插入到.insertBefore的正文之前:

document.body.insertBefore(divExtension, document.body.firstChild);

这会将元素放在 <body> 之外(在它之前),并导致 z-index 其他 position: absolute / fixed 元素出现问题。

正确分层的元素在正文中附加.appendChild:

document.body.appendChild(divElement, document.body.firstChild);

这是将元素 放在 <body> 中(它应该在的位置)并且 在它的所有其他子元素 之后。


使用自然 z 分层,absolute / fixed 元素 将被其后的相似元素重叠 :

div {
  position: absolute;
  width: 100px;
  height: 100px;
}
.red {
  background: red;
  left: 20px;
  top: 10px;
}
.green {
  background: green;
  left: 30px;
  top: 20px;
}
.blue {
  background: blue;
  left: 40px;
  top: 30px;
}
.purple {
  background: purple;
  left: 50px;
  top: 40px;
}
<div class="red">Red is underneath all its siblings</div>
<div class="green">Green overlaps red</div>
<div class="blue">Blue overlaps green</div>
<div class="purple">Purple overlaps blue</div>


问题重现

请注意 .incorrect div 是如何放置在 body 标签之前的。它的行为方式与示例中错误插入的元素相同,并且与 <body>

中的内容 div 重叠

// Injecting button (div)
var divElement = document.createElement("DIV");
divElement.id = "intro_button";
var textnode = document.createTextNode("zzz");
divElement.appendChild(textnode);
document.body.appendChild(divElement, document.body.firstChild);

// Injecting extenion (div)
var divExtension = document.createElement("DIV");
divExtension.id = "extension";
var textnode = document.createTextNode("yyy");
divExtension.appendChild(textnode);
document.body.appendChild(divExtension, document.body.firstChild);

// Injecting CSS files
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = chrome.extension.getURL('test.css');
head.appendChild(link);

var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = chrome.extension.getURL('jquery-ui.min.css');
head.appendChild(link);

// Injecting Jqueries
var s = document.createElement('script');
s.src = "jquery.js";
document.getElementsByTagName("head")[0].appendChild(s);

var s = document.createElement('script');
s.src = "jquery-ui.min.js";
document.getElementsByTagName("head")[0].appendChild(s);
.content {
  height: 500px;
  width: 500px;
  margin: 100px;
  background: #F00;
  position: absolute;
}
#intro_button {
  background-color: yellow;
  height: 100%;
  width: 100px;
  top: 0;
  right: 0;
  position: fixed;
  cursor: pointer;
}
#extension {
  height: 100%;
  width: 100px;
  position: fixed;
  background-color: green;
}
.incorrect {
  position: fixed;
  height: 200px;
  width: 500px;
  background: orange;
}
<div class="incorrect"></div>

<body>
  <div class="content">Content</div>
</body>


我们如何解决这个问题?

您应该在注入的元素上使用较大的 z-index 值,以绝对确保它们始终位于顶部并且...

确保两个元素都插入正文中 .appendChild:

// Injecting button (div)
var divElement = document.createElement("DIV");
divElement.id = "intro_button";
divElement.style.right = "0px";
divElement.onclick = function () {
    if (this.style.right === "0px") {
        $(this).animate({ "right": "+=200" }, 800);
        $("#extension").animate({ "right": "+=200" }, 800);
    }
    else if (this.style.right === "200px") {
        $(this).animate({ "right": "-=200" }, 800);
        $("#extension").animate({ "right": "-=200" }, 800);
    }
}
var textnode = document.createTextNode("zzz");    
divElement.appendChild(textnode);
document.body.appendChild(divElement, document.body.firstChild);

// Injecting extenion (div)
var divExtension = document.createElement("DIV");
divExtension.id = "extension";
var textnode = document.createTextNode("yyy");
divExtension.appendChild(textnode);
document.body.appendChild(divExtension, document.body.firstChild);
// ## Changed to appendChild here ##

// Injecting CSS files
var head  = document.getElementsByTagName('head')[0];
var link  = document.createElement('link');
link.rel  = 'stylesheet';
link.type = 'text/css';
link.href = chrome.extension.getURL('test.css');
head.appendChild(link);

var head  = document.getElementsByTagName('head')[0];
var link  = document.createElement('link');
link.rel  = 'stylesheet';
link.type = 'text/css';
link.href = chrome.extension.getURL('jquery-ui.min.css');
head.appendChild(link);

// Injecting Jqueries
var s  = document.createElement('script');
s.src = "jquery.js";
document.getElementsByTagName("head")[0].appendChild(s);

var s  = document.createElement('script');
s.src = "jquery-ui.min.js";
document.getElementsByTagName("head")[0].appendChild(s);