当可点击div在较大的可点击区域内时,是否阻止事件传播?

时间:2018-10-04 14:36:20

标签: reactjs google-chrome-extension dom-events dom-manipulation

我正在创建一个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;
}

0 个答案:

没有答案