我正在创建一个Google Chrome扩展程序,该扩展程序在Instagram个人资料页面上每个缩略图的左上角添加了上传按钮。
(由于Instagram是一个惰性加载的React网站,它使用XHR逐步填充页面,因此我不得不使用polling和MutationObserver的混合物将按钮添加到缩略图中。由于按钮没有不会添加到前十二个按钮中。)
但是我的问题是关于事件传播。当我单击上传按钮时,事件会冒泡到父容器div。我已经尝试过同时使用event.stopPropagation()和event.stopImmediatePropagation(),但是都没有用。他们只是直接将我带到单击图像的页面。
如何做到这一点,所以单击上传按钮不会导致单击父元素?
// manifest.json
{
"name": "Instagram to Imgur",
"version": "0.0.1",
"description": "Easily upload instagram pics to Imgur.",
"manifest_version": 2,
"icons": {
"16": "icons/icon_16.png",
"32": "icons/icon_32.png",
"48": "icons/icon_48.png",
"128": "icons/icon_128.png"
},
"content_scripts": [
{
"matches": ["https://www.instagram.com/*"],
"css": ["styles/styles.css"],
"js": ["scripts/content/domInject.js"],
"run_at": "document_end"
}
]
}
// domInject.js
window.onload = function() {
console.log("fired!");
init();
};
/**
* Polls to find the target node which contains all the imgs we want to add buttons to. If it takes
* too long to find the target node, the poller stops. Otherwise, it adds buttons to nodes.
*/
function init() {
let targetNode;
let intervalCounter = 0;
const poller = window.setInterval(function() {
targetNode = document.body.querySelector("article.FyNDV div div");
if (targetNode) {
clearInterval(poller); // stop polling, since targetNode found
listenOnTargetNode(targetNode);
} else if (intervalCounter < 8) {
intervalCounter++; // Failed to find targetNode, give it a few more tries.
} else {
clearInterval(poller); // Taking too long to find targetNode. Just stop.
console.log("Instagram to Imgur extension timed out.")
}
}, 250);
}
/* Listens on the actual target node that gets updated when new Instagram thumbnails are added to the page. */
function listenOnTargetNode(targetNode) {
console.log("target node: ", targetNode);
const observer = new MutationObserver(function(mutationsList, observer) {
mutationsList.forEach(function(mutation) {
if (mutation.type === "childList" && mutation.addedNodes.length) {
Array.prototype.forEach.call(mutation.addedNodes, function(node) {
findImagesAndAddButtons(node);
})
}
});
});
observer.observe(targetNode, { childList: true, subtree: true });
}
/**
* Finds img elements in the node, and then adds buttons on top of them.
* @param node - a Node which contains an image somewhere among its descendants
*/
function findImagesAndAddButtons(node) {
const imgs = node.querySelectorAll("img"); // Find the children of the node which are imgs
imgs.forEach(function(img) {
// console.log(img);
addButton(img);
});
}
/**
* Adds a (div) button to the top left hand corner of the Instagram thumbnail area.
* @param img
*/
function addButton(img) {
const button = document.createElement("div");
button.appendChild(document.createTextNode("UPLOAD"));
button.classList.add("imgurUploadButton"); // CSS in styles/styles.css
button.onclick = function(event) {
console.log("clicked");
console.log(event);
event.stopImmediatePropagation();
};
img.parentNode.insertBefore(button, img);
}
/* styles.css */
.imgurUploadButton {
position: absolute;
background-color: white;
color: black;
z-index: 10002;
border-radius: 12px;
display: inline-block;
padding: 6px;
margin: 6px;
opacity: 0.5;
font-family: sans-serif;
}