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);
        });
halfer
  • 18,701
  • 13
  • 79
  • 158
hmnilp
  • 33
  • 4
  • querySelector returns a list. Try `querySelector[0]` – Peter S Apr 29 '20 at 23:13
  • 1
    @PLZHELP You're thinking of `querySelectorAll` – Barmar Apr 29 '20 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. – Barmar Apr 29 '20 at 23:15
  • You need to use `setTimeout()` or `setInterval()` to run something periodically. – Barmar Apr 29 '20 at 23:15
  • @Barmar adding on, here is what a properly implemented sleep may look like: https://stackoverflow.com/questions/951021/what-is-the-javascript-version-of-sleep – Peter S Apr 29 '20 at 23:16
  • Or you can add an event listener for the `load` event on the image. – Barmar Apr 29 '20 at 23:16
  • Typo: `document.querySelector("image")` should be `document.querySelector(".image")` and `ClickOnImage` should be `clicker` (or vice versa) – Barmar Apr 29 '20 at 23:17
  • @Barmar I don't get the problem with sleep. I already tried to set an event listener for the image, but doesn't work. And yes, I copied wrong snippets of code for the two things. I'll correct it instantly – hmnilp Apr 29 '20 at 23:23
  • Meanwhile I don't have any idea on how to implement setInterval in this case – hmnilp Apr 29 '20 at 23:25

1 Answers1

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);
});
Barmar
  • 596,455
  • 48
  • 393
  • 495
  • 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". – hmnilp Apr 30 '20 at 07:24
  • ok, I finally solved by adding the image assignement in the clickOnImage function and by using your setInterval solution – hmnilp Apr 30 '20 at 08:52
  • 1
    I added it to the `DOMContentLoaded` function. – Barmar Apr 30 '20 at 14:29