Я пытаюсь добавить элемент <img>
в файл <span>
в скрипте содержимого моего расширения chrome. Однако кажется, что приложение добавляет эффект только тогда, когда я добавляю в body
из document
, как описано в content-script.js
. Для воспроизведения этого нажмите на следующую ссылку и открытой средства разработки:Не удалось добавить <img> в <span> в сценарии содержимого расширения Chrome
Поиск для <img>
которого id
является seenIcon
. Он будет определен при добавлении в 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 и получил несколько цепей функций, которые очень похожи на функцию setMutationHandler(), указанную выше, поэтому я переключился на простой таймер согласно [this] (http: // stackoverflow .com/questions/13917047/how-to-get-a-content-script-to-load-after-a-pages-javascript-has-execute/13917682 # comment51201657_13917682) совет. Я не знал, что вы можете наблюдать, как вложенные дети добавляются с помощью 'MutationObserver' ... Я вижу, что аргумент' поддерева 'мог бы быть весьма полезен, чтобы избежать этих цепей. :) – Mitch
Я пробовал это, но '
' все еще не создается для меня, используя мою исходную ссылку. Я добавил пару 'console.log()' 'в обратном вызове' load' и перед вызовом 'insertAdjacentHTML()', но ничего не было напечатано. Я также дал '
' '' id', но не смог найти его после загрузки страницы. –
Mitch
Ваш код работает с 'if (document.readyState ===" complete ")' check, thanks! Возможно, стоит добавить это к вашему ответу, если у кого-то другая проблема. – Mitch