【问题标题】:What's causing this error in my mutation observer using script?是什么导致我的突变观察者使用脚本出现此错误?
【发布时间】:2019-03-19 11:00:03
【问题描述】:

最初提出的问题已得到解答。此外,Stackoverflow 之外的某个人为我试图通过我的脚本实现的目标提供了完整的解决方案,我已将其添加为我的问题的答案。脚本本身及其解决的具体问题的摘要在我自己的答案中有详细说明。

原问题:

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

我的浏览器在启动几秒钟后用不正确的src 覆盖了正确的img 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'.

【问题讨论】:

  • document.getElementsByTagName('img'); 不是一个节点,它是一个 HTMLcollection 的节点
  • 顺便说一句,像这样运行observer.observe(targetNode, config); observer.disconnect(); 将确保观察者永远不会运行:p
  • 还值得一提的是img.getAttribute('src') 并不总是与img.src 相同——您确定知道哪一个与您的要求相关吗?
  • 谢谢。我明白了,这解释了脚本的一些问题。我不是程序员,所以脚本肯定有不止一件事。是的,我确定我需要img.getAttribute('src') 而不是img.src
  • 脚本在没有变异观察者的情况下工作,但是它依赖于延迟,这并不理想,因为这意味着我实际上会看到 src 的视觉变化被破坏然后修复再次。我想我仍然需要等待好心的人告诉我如何解决我脚本中的主要问题。 (我还更新了脚本以删除observer.disconnect();

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


【解决方案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);
    });
}

【讨论】:

  • 谢谢。我测试了脚本。这确实解决了控制台中给出的错误。似乎该脚本仍然没有按照它的意图做,因为损坏的 src 没有被替换。我还将 initMod 延迟减少到 200,它似乎仍然无法正常工作。哪个,我有点傻眼了。
  • 脚本是否有可能检测到 img 属性的其他变化,但未能找到设置为 https://hyperspace.marquiskurt.net/icons/favicon-32x32.pngsrc,然后停在那里?
  • 控制台日志记录将帮助您找到正在发生的事情
【解决方案2】:

有人非常友好地提供了一个解决方案,完全实现了我想要做的事情。

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();

setTimeout 设置为 0,损坏的 src 会立即得到纠正,而用户可以看到的视觉没有任何变化。如果其他人遇到 Web 浏览器 Vivaldi 错误地修改了特定用户添加的 Web 面板的图标的 src 的问题,则可以修改此脚本以供使用。

【讨论】:

    猜你喜欢
    • 2011-11-14
    • 1970-01-01
    • 2012-09-28
    • 1970-01-01
    • 1970-01-01
    • 2011-01-26
    • 2021-10-28
    • 1970-01-01
    • 2014-08-12
    相关资源
    最近更新 更多