无法将 <img> 附加到 Chrome 扩展的内容脚本中的 <span>
Unable to append <img> into <span> in content script of Chrome extension
我正在尝试将 <img>
元素附加到我的 chrome 扩展的内容脚本中的 <span>
中。但是,似乎只有当我追加到 document
的 body
时,追加才有效,如 content-script.js
中所述。要重现这一点,请单击以下 link 并打开开发工具:
搜索 id
为 seenIcon
的 <img>
。它将在附加到 body
时定义,但在所有其他情况下为 undefined
。
manifest.json
{
"manifest_version": 2,
"name": "Finn.no Property Blacklist",
"description": "Hides finn.no property search results that you've marked as \"seen\".",
"version": "1.0",
"permissions": [
"activeTab",
"http://kart.finn.no/*",
"storage"
],
"content_scripts": [
{
"matches": ["http://kart.finn.no/*"],
"js": ["content-script.js"]
}
],
"web_accessible_resources": [
"*.png"
]
}
content-script.js
console.log("content script!")
function getIconSpanIfExists() {
var spanClassName = "imagePoi";
var matchingElements = document.getElementsByClassName(spanClassName);
if (matchingElements.length > 1) {
console.error(failureMessage("wasn't expecting more than one element with class name " + spanClassName));
return null;
}
if (matchingElements.length === 0) {
return null;
}
return matchingElements[0].parentNode;
}
function htmlReady() {
return getIconSpanIfExists();
}
function addIcons() {
var iconSpan = getIconSpanIfExists();
// Append into body - works.
// var icon = document.createElement("img");
// icon.id = "seenIcon";
// icon.src = chrome.extension.getURL("seen.png");
// document.body.appendChild(icon);
// console.log("appended " + icon.id + " into body");
// Append into span - doesn't work, even though it says childNodes.length is 2.
var icon = document.createElement("img");
icon.id = "seenIcon";
icon.src = chrome.extension.getURL("seen.png");
icon.style.left = "200px";
icon.style.top = "200px";
iconSpan.appendChild(icon);
console.log("appended " + icon.id + " into span with class imagePoi" + " new children: " + iconSpan.childNodes.length);
// Modify innerHTML of span - doesn't work, even though innerHTML has the icon.
// iconSpan.innerHTML += "\n<img id=\"seenIcon\""
// + "src=\"" + chrome.extension.getURL("seen.png") + "\""
// + "style=\"left: 200px; top: 200px;\">";
// console.log(iconSpan.parentNode.id, iconSpan.innerHTML);
}
function init() {
console.log("initialising content script");
if (!htmlReady()) {
console.log("not all HTML is loaded yet; waiting");
var timer = setInterval(waitForHtml, 200);
function waitForHtml() {
console.log("waiting for required HTML elements...");
if (htmlReady()) {
clearInterval(timer);
console.log("... found them!");
addIcons();
}
}
return;
}
}
if (document.readyState === "complete") {
console.log("document is complete")
init();
} else {
console.log("document is not yet ready; adding listener")
window.addEventListener("load", init, false);
}
seen.png
为什么更改没有反映在 DOM 中?
该节点由站点重新创建,因此您需要在它首次出现后稍等片刻,然后再添加新图像。
我用 MutationObserver 使用简单的用户脚本对其进行了测试,每次将 .imagePoi
添加到文档时都会添加新图标,包括前两次出现和随后出现的 zoom-in/out。
setMutationHandler(document, '.imagePoi', function(observer, node) {
node.parentNode.insertAdjacentHTML('beforeend',
'<img src="http://www.dna-bioscience.co.uk/images/check-mark.gif">');
});
function setMutationHandler(baseNode, selector, cb) {
var ob = new MutationObserver(function(mutations) {
for (var i=0, ml=mutations.length, m; (i<ml) && (m=mutations[i]); i++)
for (var j=0, nodes=m.addedNodes, nl=nodes.length, n; (j<nl) && (n=nodes[j]); j++)
if (n.nodeType == 1)
if (n = n.matches(selector) ? n : n.querySelector(selector))
if (!cb(ob, n))
return;
});
ob.observe(baseNode, {subtree:true, childList:true});
}
您可以利用 .imagePoi
的突变记录的 target
在其 class 列表中包含 finnPoiLayer
这一事实来简化处理程序。但是当网站布局稍有变化时,它很容易崩溃。
我正在尝试将 <img>
元素附加到我的 chrome 扩展的内容脚本中的 <span>
中。但是,似乎只有当我追加到 document
的 body
时,追加才有效,如 content-script.js
中所述。要重现这一点,请单击以下 link 并打开开发工具:
搜索 id
为 seenIcon
的 <img>
。它将在附加到 body
时定义,但在所有其他情况下为 undefined
。
manifest.json
{
"manifest_version": 2,
"name": "Finn.no Property Blacklist",
"description": "Hides finn.no property search results that you've marked as \"seen\".",
"version": "1.0",
"permissions": [
"activeTab",
"http://kart.finn.no/*",
"storage"
],
"content_scripts": [
{
"matches": ["http://kart.finn.no/*"],
"js": ["content-script.js"]
}
],
"web_accessible_resources": [
"*.png"
]
}
content-script.js
console.log("content script!")
function getIconSpanIfExists() {
var spanClassName = "imagePoi";
var matchingElements = document.getElementsByClassName(spanClassName);
if (matchingElements.length > 1) {
console.error(failureMessage("wasn't expecting more than one element with class name " + spanClassName));
return null;
}
if (matchingElements.length === 0) {
return null;
}
return matchingElements[0].parentNode;
}
function htmlReady() {
return getIconSpanIfExists();
}
function addIcons() {
var iconSpan = getIconSpanIfExists();
// Append into body - works.
// var icon = document.createElement("img");
// icon.id = "seenIcon";
// icon.src = chrome.extension.getURL("seen.png");
// document.body.appendChild(icon);
// console.log("appended " + icon.id + " into body");
// Append into span - doesn't work, even though it says childNodes.length is 2.
var icon = document.createElement("img");
icon.id = "seenIcon";
icon.src = chrome.extension.getURL("seen.png");
icon.style.left = "200px";
icon.style.top = "200px";
iconSpan.appendChild(icon);
console.log("appended " + icon.id + " into span with class imagePoi" + " new children: " + iconSpan.childNodes.length);
// Modify innerHTML of span - doesn't work, even though innerHTML has the icon.
// iconSpan.innerHTML += "\n<img id=\"seenIcon\""
// + "src=\"" + chrome.extension.getURL("seen.png") + "\""
// + "style=\"left: 200px; top: 200px;\">";
// console.log(iconSpan.parentNode.id, iconSpan.innerHTML);
}
function init() {
console.log("initialising content script");
if (!htmlReady()) {
console.log("not all HTML is loaded yet; waiting");
var timer = setInterval(waitForHtml, 200);
function waitForHtml() {
console.log("waiting for required HTML elements...");
if (htmlReady()) {
clearInterval(timer);
console.log("... found them!");
addIcons();
}
}
return;
}
}
if (document.readyState === "complete") {
console.log("document is complete")
init();
} else {
console.log("document is not yet ready; adding listener")
window.addEventListener("load", init, false);
}
seen.png
为什么更改没有反映在 DOM 中?
该节点由站点重新创建,因此您需要在它首次出现后稍等片刻,然后再添加新图像。
我用 MutationObserver 使用简单的用户脚本对其进行了测试,每次将 .imagePoi
添加到文档时都会添加新图标,包括前两次出现和随后出现的 zoom-in/out。
setMutationHandler(document, '.imagePoi', function(observer, node) {
node.parentNode.insertAdjacentHTML('beforeend',
'<img src="http://www.dna-bioscience.co.uk/images/check-mark.gif">');
});
function setMutationHandler(baseNode, selector, cb) {
var ob = new MutationObserver(function(mutations) {
for (var i=0, ml=mutations.length, m; (i<ml) && (m=mutations[i]); i++)
for (var j=0, nodes=m.addedNodes, nl=nodes.length, n; (j<nl) && (n=nodes[j]); j++)
if (n.nodeType == 1)
if (n = n.matches(selector) ? n : n.querySelector(selector))
if (!cb(ob, n))
return;
});
ob.observe(baseNode, {subtree:true, childList:true});
}
您可以利用 .imagePoi
的突变记录的 target
在其 class 列表中包含 finnPoiLayer
这一事实来简化处理程序。但是当网站布局稍有变化时,它很容易崩溃。