How to wait for the page to load before clicking in javascript?

I want to manipulate an Intranet site with Javascript and I have done the following functions which work well, but if I run them one by one:

1: function (){ 
var list = document.getElementsByName("filter");
for (var i=0; i<list.length; i++) list[i].click();
 },

2: function (){  
var list = document.getElementsByClassName("ui-icon ui-icon-pencil tiptip");
for (var i=0; i<list.length; i++) list[i].click(); 
 },

3: function (){  
for(var i = 0, len = document.links.length; i < len; i += 1) {
    if(document.links[i].textContent === "Configuration ") {
        document.links[i].click();
    }
}
 },

4: function (){  
var x = document.getElementsByName("configurations[]");
    var i;
    for (i = 0; i < x.length; i++) {
        if (x[i].type == "checkbox") {
            x[i].checked = true;
        }
    }
 },

My goal is to launch all the functions at once but I have to wait for the page to load before making the second click then the third then the fourth.
with the following code I have to run my function four times to get the four clicks

function (){ 
//function 1
var list = document.getElementsByName("filter");
for (var i=0; i<list.length; i++) list[i].click();
//function 2
var list = document.getElementsByClassName("ui-icon ui-icon-pencil tiptip");
for (var i=0; i<list.length; i++) list[i].click();
//function 3
for(var i = 0, len = document.links.length; i < len; i += 1) {
    if(document.links[i].textContent === "Configuration ") {
        document.links[i].click();
    }
}
//function 4
var x = document.getElementsByName("configurations[]");
    var i;
    for (i = 0; i < x.length; i++) {
        if (x[i].type == "checkbox") {
            x[i].checked = true;
        }
    }
 
},

the method

`setTimeout(() => {
 var list = document.getElementsByName("filter");
for (var i=0; i<list.length; i++) list[i].click();
 }, 3000)
setTimeout(() => {
 var list = document.getElementsByClassName("ui-icon ui-icon-pencil tiptip");
for (var i=0; i<list.length; i++) list[i].click();
 }, 3000)`

and the method

document.addEventListener("DOMContentLoaded", () => {
  var list = document.getElementsByName("filter");
for (var i=0; i<list.length; i++) list[i].click();
});
document.addEventListener("DOMContentLoaded", () => {
  var list = document.getElementsByClassName("ui-icon ui-icon-pencil tiptip");
for (var i=0; i<list.length; i++) list[i].click();
});

Also don’t work, If you have any idea please i will be grateful.

See:

Also, if a document has an iframe then they would have their own events. And if the page has JavaScript then a script might add more to the page and then there would be additional events for the additional content. There is an event or are events for the beginning of the additional content but I forget what that or they are named.

1 Like

Hi SamuelCalifornie,

excuse me but I forgot to say the most interesting thing is a function that I launch from my chrome extension so I have to modify my following files:

Extension.js

window.addEventListener('DOMContentLoaded', setUpStuff, false);
function setUpStuff(){
document.getElementById("inpt").focus();
  let optionsButton = document.getElementById('btn');
    optionsButton.addEventListener('click', function() {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
	chrome.tabs.sendMessage(tabs[0].id, {functionnum: document.getElementById("inpt").value.toUpperCase()});

		});
      });
}

window.addEventListener('load', function() {

var list = document.getElementsByName("filter");
for (var i=0; i<list.length; i++) list[i].click();

var list = document.getElementsByClassName("ui-icon ui-icon-pencil tiptip");
for (var i=0; i<list.length; i++) list[i].click();

for(var i = 0, len = document.links.length; i < len; i += 1) {
    if(document.links[i].textContent === "Configuration ") {
        document.links[i].click();
    }
}

var x = document.getElementsByName("configurations[]");
    var i;
    for (i = 0; i < x.length; i++) {
        if (x[i].type == "checkbox") {
            x[i].checked = true;
        }
    }
},false);

And popup.js

chrome.runtime.onMessage.addListener(
  function(request, sender) {
	let functions = {
0: function () { window.location.reload(true); },
1: function () { 
var list = document.getElementsByName("filter");
for (var i=0; i<list.length; i++) list[i].click();

var list = document.getElementsByClassName("ui-icon ui-icon-pencil tiptip");
for (var i=0; i<list.length; i++) list[i].click();

for(var i = 0, len = document.links.length; i < len; i += 1) {
    if(document.links[i].textContent === "Configuration ") {
        document.links[i].click();
    }
}

var x = document.getElementsByName("configurations[]");
    var i;
    for (i = 0; i < x.length; i++) {
        if (x[i].type == "checkbox") {
            x[i].checked = true;
        }
    }
 
},

	}

	functions[request.functionnum]();
});

Now when I run my function the page runs non-stop I think the problem is in the code on Extension.js but I don’t know how to adapt it if you can help me please and thank you in advance.

It seems to me that the code from the last post won’t work, because the DOMContentLoaded event fires before the extension scripts are loaded.

1 Like

Is it possible to use the setTimeout() method in this case? because I don’t really know how to do it with :

window.addEventListener("load", function load(event){ 
  window.removeEventListener("load", load, false); //remove listener, no longer needed 
  //enter here the action you want to do once loaded
  },false);

or

var loadfunction = window.onload; 
window.onload = function(event){ 
  //enter here the action you want to do once loaded 
if(loadfunction) loadfunction(event); 
}

Hi,
Do you have any ideas or suggestions please?

I have some experience with Chrome extensions, but unfortunately, I don’t have the time to dissect your code and find out why it’s not working.

What I can offer is that if you stick your extension up on GitHub for me to clone and if you make a demo page (either online or locally) which I can use to recreate the problem you are having, then I don’t mind taking a look.

2 Likes

Thank you

For more details here is the source code with screenshots of the 4 buttons

Button 1 “Rechercher”

Button 2 “Editer”

Button 3 “Configuration”

Button 4 “checkbox M and D”

I manage to click the buttons with the following code but I can’t manage to configure a setTimeout to wait for the buttons are displayed before the clicks.

//Button 1 "Rechercher"
var list = document.getElementsByName("filter");
for (var i=0; i<list.length; i++) list[i].click();
 
//Button 2 "Editer"
var list = document.getElementsByClassName("ui-icon ui-icon-pencil tiptip");
for (var i=0; i<list.length; i++) list[i].click();
 
//Button 3 "Configuration"
for(var i = 0, len = document.links.length; i < len; i += 1) {
    if(document.links[i].textContent === "Configuration ") {
        document.links[i].click();
    }
}
 
//Button 4  "checkbox M and D"
var x = document.getElementsByName("configurations[]");
    var i;
    for (i = 0; i < x.length; i++) {
        if (x[i].type == "checkbox") {
            x[i].checked = true;
        }
    }

Thanks for that, but what you have posted doesn’t really aid me in easily recreating your problem.

Why not chuck the extension up on GitHUb, then make a dummy page for me to test against. That would make things a lot easier.

Hi @James_Hibbard,

thank you for your answer, sorry because the codes of the extension contain confidential information of my company. do you have an idea how to adapt my code with one of the following two examples:

https://jsfiddle.net/a64c8pk1/
or
https://jsfiddle.net/mahdiweb/L2o8nrwq/9/

my Code:

//Button 1 "Rechercher"
var list = document.getElementsByName("filter");
for (var i=0; i<list.length; i++) list[i].click();
 
//Button 2 "Editer"
var list = document.getElementsByClassName("ui-icon ui-icon-pencil tiptip");
for (var i=0; i<list.length; i++) list[i].click();
 
//Button 3 "Configuration"
for(var i = 0, len = document.links.length; i < len; i += 1) {
    if(document.links[i].textContent === "Configuration ") {
        document.links[i].click();
    }
}
 
//Button 4  "checkbox M and D"
var x = document.getElementsByName("configurations[]");
    var i;
    for (i = 0; i < x.length; i++) {
        if (x[i].type == "checkbox") {
            x[i].checked = true;
        }
    }

Hey,

I’m afraid your missing the point a little. The confidential nature of the code is irrelevant to the problem at hand. What I need is some way to reproduce your problem.

Reading through the post it seems to me that:

  • you have an intranet page
  • you have a Chrome extension
  • when the intranet page loads you would like the code in the extension to simulate some clicks on said page
  • this is not working as you would like (due to some timing issues)

Did I get that right?

If so, it would be really helpful if you could a) make a dummy intranet page containing the relevant HTML elements, b) make a dummy Chrome extension that we can use to reproduce your problem.

When I say dummy page/extension, I mean strip out anything that is not relevant to the problem.

This post on SO explains it well: https://stackoverflow.com/help/minimal-reproducible-example

If you can do that, I will happily take a look. If that’s not possible, fair enough. Maybe someone else will have an idea why this isn’t working :slight_smile:

Hey,

Thank you for the interest you are really nice.

Hey @James_Hibbard ,

Here is the content of my Chrome extension:

manifest.json

{
	"name": "Zero",
	"version": "1.0",
	"manifest_version": 3,
	"description": "Auto fill form GRC",
	"action": {
		"default_popup": "popup.html",
		"default_icon": "icon/icon.png"
	},
	"content_scripts": [{
		"matches": [
			"http://*/*",
			"https://*/*"
		],
		"js": ["extension.js"]
	}],
	"permissions": [
		"activeTab",
		"scripting"
	]
}

popup.html

<!doctype html>
<html>
    <head>
        <style>
            body {
			min-width: 120px;
			overflow-x: hidden;
			font-family: Arial, sans-serif;
			font-size: 12px;
            }
			
            input, textarea {
			width: 140px;
            }
			
            input#save {
			font-weight: bold;
			width: auto;
			
            }
		</style>
		
	</head>
    <body>
		<h1>GRC</h1>
		<center>
            <div>
                <label><b>Veuillez saisir un code</b></label>
                <input name="inpt" id="inpt" autocomplete="off"/>
                <p>
                    <button id="btn">Enter</button>
				</p>
			</div>
		</center>
	</body>
	<script src="popup.js"></script>
</html>

popup.js

	window.addEventListener('DOMContentLoaded', setUpStuff, false);
function setUpStuff(){
    let optionsButton = document.getElementById('btn');
    optionsButton.addEventListener('click', function() {
        chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
            chrome.tabs.sendMessage(tabs[0].id, {functionnum: document.getElementById("inpt").value.toUpperCase()});
        });
      });
}

extension.js

chrome.runtime.onMessage.addListener(
  function(request, sender) {
	let functions = {
	1: function () {
document.getElementById("topsearch-text").value += "google";
var list = document.getElementsByClassName("go");
for (var i=0; i<list.length; i++) list[i].click();
document.querySelector('img[src="https://fdn2.gsmarena.com/vv/bigpic/google-pixel7-pro-new.jpg"]').click(); 
},
	2: function () { alert(2); },
	3: function () { alert(3); },
	}
	functions[request.functionnum]();
});

as you can see on the extension.js file I have the number 1 function which is executed for example on the website: https://www.gsmarena.com/
I have to write in the search field the word google then press the go button and I have to wait for the result then press the model google_pixel_7_pro.

I used the setTimeout method but without success the code stops after the second click here is a demonstration video in gif format

MĂ©dia

I hope I have explained my need well and thank you for your help.

Hi,

Thanks for the explanation and giving me an example I could work with.

Your problem is that when you click the Go button, this causes a new page to be loaded and your content script is aborted.

1: function () {
  document.getElementById("topsearch-text").value += "google";

  // Click Go button. This causes a redirect
  document.querySelector("#quick-search-button > input").click();
   
  // This code is never reached
  var list = document.getElementsByClassName("go");
  for (var i=0; i<list.length; i++) list[i].click();
  document.querySelector('img[src="https://fdn2.gsmarena.com/vv/bigpic/google-pixel7-pro-new.jpg"]').click(); 
},

Unfortunately there is no way (that I am aware of) for a browser extension to redirect to a new page in the middle of a function and then resume the same function once the new page has loaded.

This doesn’t seem like the best use case for an extension. You could do this quite easily with some browser automation software though (e.g. Puppeteer) if that would fit your use case.


Edit Your example doesn’t actually contain any code to click the button, so I added it in. Please let me know if I have misunderstood and you are doing something else to cause the redirect.

1 Like

Hi,

Ok it doesn’t matter thank you for your help and your kindness.

No worries :slight_smile:

But have we hit a brick wall here? How does this apply to your actual use case (I assume this was just a demo)?

1 Like

I have to dig into the wall, I have no choice and I’m sure to find other workarounds. :slightly_smiling_face:

1 Like