0

So I wanted to make a simple script that would replace images on a website (with kitten pics of course). Thing is, I want the script to keep replacing images as I scroll through a site.

E.g. on Google images it will only load kitten images for the immediately loaded pictures, not the other ones that load after.

How can I make it so that the images will replace the newly loaded images? I've thought about maybe detecting content loads but have no idea on how to approach the issue since I'm new to everything web.

Here's my content.js code:

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;
    }
}
  • You'll want to likely use `setTimeout()` and `clearTimeout()` functions to delay by how many seconds you want before changing the image. I have an answer to [a similar question elsewhere](https://stackoverflow.com/questions/1909441/how-to-delay-the-keyup-handler-until-the-user-stops-typing/37494269#37494269). – HoldOffHunger Nov 19 '20 at 16:37
  • Here's a site where I reload the images every 10 seconds. I'll post the code below if you think it'll help: [EarthFluent: Learn French](http://www.earthfluent.com/french/view.php?action=index). – HoldOffHunger Nov 19 '20 at 17:41
  • @HoldOffHunger, that's to replace the images every n seconds, right? What I want to do is to keep replacing images as new images load onto the page. – BunnyRabbit Nov 20 '20 at 02:28

1 Answers1

0

You may wish to look into MutationObserver objects. (https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver)

Basically, what we can do is ask the body of the document to raise an event any time there's a modification to the page that satisfies one of a number of conditions. In your case, you want to watch for subtree modifications, so that you're told every time more content is added to the page and can then review and modify it.

Since your code can be expected to run many times on the one page, you've a dilema. What to do about the images you've already changed? Should they change again or retain their new image? I've used the .dataset api (https://developer.mozilla.org/en-US/docs/Web/API/HTMLOrForeignElement/dataset) to set a flag indicating the image has been changed already and should be ignored on subsequent executions.

Here's a rough example that should get your started. You can delete the horizontal rule element in the browser's element inspector to trigger the behaviour.

<!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>
enhzflep
  • 12,927
  • 2
  • 32
  • 51