3

So I'm trying to write a script for tampermonkey for a site in which the image changes everytime you click on it. My goal is to click until I get the final image. The problem is that the script doesn't click anything and, if I try to print on console what is the object I'm trying to click it shows [object HTMLImageElement]. The code I'm using is:

var image;
document.addEventListener("DOMContentLoaded", function(){
        sleep(1);
        clicker();
    });

    

function clicker()
{
   var counter = 0;
   console.log("current image: " + document.querySelector(".image"))
   while(document.querySelector(".image").src != "https://site/image/4.gif" && counter < 10)
   {
      console.log("image at start: " + document.querySelector(".image"));
      document.querySelector(".image").click();
      counter ++;
      console.log("click" + counter);
      console.log("image at end: " + document.querySelector(".image"));
      sleep(1);
   }
   
    };
    
/*function random(min,max)
{
   return min + (max - min) * Math.random();
};*/

function sleep(s)
{
   var now = new Date().getTime();
   while(new Date().getTime() < now + (s*1000));
}

the image on the site is like:

<div>
<img data="" src="/image/2.gif" class="image">
</div>

the final output is: click1 image at end: [object HTMLImageElement]

image at start: [object HTMLImageElement] click2 image at end: [object HTMLImageElement]

[...]

I tried various things such as storing the queryselector in a variable or write down another function that returns me the image. The funny things is that if I run document.querySelector(".image").click(); on the console it works!

Edit

I finally solved by using a solution in the answers. Here the snippet:

var image;
var counter = 0;
var clickInterval;


function clickOnImage()
{
  image = document.querySelector(".image");
  if (image.src != "https://site/image/4.gif" && counter < 10) {
    image.click();
    counter++;
  } else {
     clearInterval(clickInterval);
  }
}

 window.addEventListener("DOMContentLoaded", function() {
        clickInterval = setInterval(clickOnImage, 1000);
        });

9
  • querySelector returns a list. Try querySelector[0] Commented Apr 29, 2020 at 23:13
  • 1
    @PLZHELP You're thinking of querySelectorAll Commented Apr 29, 2020 at 23:14
  • 1
    JavaScript is single-threaded. Your sleep() function is a busy-wait, it never returns to the main event loop, so the event listener for the click never runs. Commented Apr 29, 2020 at 23:15
  • You need to use setTimeout() or setInterval() to run something periodically. Commented Apr 29, 2020 at 23:15
  • @Barmar adding on, here is what a properly implemented sleep may look like: stackoverflow.com/questions/951021/… Commented Apr 29, 2020 at 23:16

1 Answer 1

2

One way is to use an event listener for the load event that checks the URL.

var image = document.querySelector(".image");
var counter = 0;
function clickOnImage() {
  if (image.src != "https://site/image/4.gif" && counter < 10) {
    image.click();
    counter++;
  } else {
    image.removeEventListener("load", clickOnImage)
  }
}
window.addEventListener("DOMContentLoaded", function() {
  image.addEventListener("load", clickOnImage);
});

If this doesn't work, use setInterval() to run something periodically.

var image;
var counter = 0;
var clickInterval;

function clickOnImage() {
  if (image.src != "https://site/image/4.gif" && counter < 10) {
    image.click();
    counter++;
  } else {
    clearInterval(clickInterval);
  }
}
window.addEventListener("DOMContentLoaded", function() {
  image =  = document.querySelector(".image");
  clickInterval = setInterval(clickOnImage, 1000);
});

Sign up to request clarification or add additional context in comments.

3 Comments

First of all, thanks for the answer. I tried both of them, but I got another error: "Uncaught TypeError: Cannot read property 'src' of null at clickOnImage".
ok, I finally solved by adding the image assignement in the clickOnImage function and by using your setInterval solution
I added it to the DOMContentLoaded function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.