首页 > 解决方案 > 加载时替换图像

问题描述

所以我想制作一个简单的脚本来替换网站上的图片(当然是小猫图片)。问题是,我希望脚本在我滚动浏览网站时不断替换图像。

例如,在 Google 图片上,它只会为立即加载的图片加载小猫图片,而不是之后加载的其他图片。

我怎样才能使图像替换新加载的图像?我考虑过可能检测内容加载,但不知道如何解决这个问题,因为我对所有网络都是新手。

这是我的 content.js 代码:

if (document.readyState === 'loading') {
     document.addEventListener('DOMContentLoaded', replace);
 } else {
     replace();
 }

function replace() {
    let filenames = [
        "0.jpg",
        "1.jpg",
        "2.jpg",
        "3.jpg",
        "4.jpg",
        "5.jpg",
        "6.jpg",
        "7.jpg",
        "8.jpg",
        "9.jpg",
        "10.jpg"
    ];

    let imgs = document.getElementsByTagName('img');
    for (image of imgs) {
        let ran = Math.floor(Math.random() * 10);
        console.log(ran);

        let file = 'cat/' + filenames[ran];
        let url = chrome.extension.getURL(file);
        image.src = url;
    }
}

标签: javascriptweb

解决方案


您可能希望查看 MutationObserver 对象。( https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver )

基本上,我们可以做的是在任何时候对满足多个条件之一的页面进行修改时,要求文档正文引发一个事件。在您的情况下,您希望监视子树修改,以便每次向页面添加更多内容时都会被告知,然后可以查看和修改它。

由于您的代码可能会在一页上运行多次,因此您进退两难。如何处理您已经更改的图像?他们应该再次改变还是保留他们的新形象?我已经使用了.datasetapi ( https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/dataset ) 来设置一个标志,指示图像已经被更改,应该在后续执行中被忽略。

这是一个粗略的示例,可以帮助您入门。您可以在浏览器的元素检查器中删除水平规则元素以触发该行为。

<!doctype html>
<html>
<head>
<script>
"use strict";
window.addEventListener('load', onWindowLoaded, false);
function onWindowLoaded(evt)
{
    const targetNode = document.body;
    const config = {attributes:true, childList:true, subtree: true};
    
    const observer = new MutationObserver(callbackFunc);
    observer.observe(targetNode, config);
    
    function callbackFunc(mutationsList, observer)
    {
        for (const mutation of mutationsList)
        {
            if (mutation.type == 'childList')
                updateImageSources();
        }
    }
}

function updateImageSources()
{
    let allImages = document.querySelectorAll('img');
    allImages.forEach( imgFunc );
    
    function imgFunc(img, index, collection)
    {
        let filenames = ['0.jpg', '1.jpg', '2.jpg', '3.jpg', '4.jpg', '5.jpg',
                         '6.jpg', '7.jpg', '8.jpg', '9.jpg', '10.jpg'];
        if (img.dataset.replaced == undefined)
        {
            img.dataset.replaced = true;
            let randomIndex = Math.floor( filenames.length * Math.random() );
            img.src = filenames[randomIndex];
        }
    }
}
</script>
</head>
<body>
    <img><img><img>
    <hr>
</body>
</html>

推荐阅读