是什么导致我使用脚本的变异观察器出现此错误?

时间:2019-03-19 11:00:04

标签: javascript html google-chrome google-chrome-devtools mutation-observers

已回答原始问题。另外, Stackoverflow之外的人已经为我的脚本提供了完整的解决方案,我将其添加为我的问题的答案。我自己的答案中详细描述了脚本本身以及所解决的特定问题的摘要。

原始问题:

不幸的是,我不是程序员,所以我的经验非常有限。

启动后的几秒钟,我的浏览器用错误的img覆盖了正确的src src

我的脚本的预期功能是一种变通办法,可在我的浏览器覆盖正确的src时,立即用正确的src再次替换损坏的src

function getElementsBySrc(srcValue) {
  var nodes = [];
  var e = document.getElementsByTagName('img');

  for (var i = 0; i < e.length; i++) {
    if (e[i].hasAttribute('src') && e[i].getAttribute('src') == srcValue) {
      nodes.push(e[i]);
    }
  }

  return nodes;
}

function initMod(){
    if(!document.querySelector("#browser")){
        setTimeout(initMod, 1000);
        return;
    }

var targetNode = document.getElementsByTagName('img');
var config = { attributes: true, childList: false, subtree: false, characterData: false };

var callback = function(mutationsList, observer) {
    for(var mutation of mutationsList) {
        if (mutation.type == 'attributes') {

            console.log('The ' + mutation.attributeName + ' attribute was modified.');

            var n = getElementsBySrc('https://hyperspace.marquiskurt.net/icons/favicon-32x32.png');
            for (var i = 0; i < n.length; i++) {
                n[i].setAttribute('src', 'chrome://favicon/https://hyperspace.marquiskurt.net/app/');
            }

        }
    }
};

var observer = new MutationObserver(callback);

observer.observe(targetNode, config);

}
initMod();

该脚本在我的浏览器启动时直接加载。我的Chrome Devtools控制台显示错误:

Uncaught TypeError: Failed to execute 'observe' on 'MutationObserver': parameter 1 is not of type 'Node'.

2 个答案:

答案 0 :(得分:1)

document.getElementsByTagName('img');返回元素的列表,而不是节点,因此不能使用targetNode(因为它不是节点)

这里我改用document.querySelectorAll,结果相同,但是它有一个forEach方法,可用于为每个IMG创建突变观测器

function initMod() {
    if(!document.querySelector("#browser")){
        setTimeout(initMod, 1000);
        return;
    }

    const callback = (mutationsList, observer) => {
        for(let mutation of mutationsList) {
            if (mutation.type == 'attributes') {
                console.log('The ' + mutation.attributeName + ' attribute was modified.');
                const n = getElementsBySrc('https://hyperspace.marquiskurt.net/icons/favicon-32x32.png');
                for (let e of n) {
                    e.setAttribute('src', 'chrome://favicon/https://hyperspace.marquiskurt.net/app/');
                }
            }
        }
    };
    const config = { attributes: true, childList: false, subtree: false, characterData: false };
    document.querySelectorAll('img').forEach(targetNode => {
        const observer = new MutationObserver(callback);
        observer.observe(targetNode, config);
    });
}

答案 1 :(得分:0)

Someone very kindly provided a solution that achieved exactly what I was trying to do.

const selector = "#panels img[src='https://hyperspace.marquiskurt.net/icons/favicon-32x32.png']";
function fixImages() {
    const maybeBadImage = document.querySelector(selector);
    if(maybeBadImage){
        maybeBadImage.src = "chrome://favicon/https://hyperspace.marquiskurt.net/app/";
    }
}
const observer = new MutationObserver(fixImages);
function initMod() {
    if(!document.querySelector(selector)){
        setTimeout(initMod, 0);
        return;
    }
    observer.observe(document.querySelector(selector), { attributes: true });
    fixImages();
}
initMod();

With setTimeout set to 0, the broken src is immediately corrected without any visual change that the user can see. This script can be modified for use if anyone else is having the issue where the web browser Vivaldi incorrectly modifies the src for the favicon of a specific user-added web panel.