so I am working on a really small chrome extension. There is a webpage and I want to click the buttons on this webpage. After I click all of them I want to click the next page button and keep doing the same thing.
I have no problem finding the buttons or the nextpagebutton. I am also able to do it using setInterval functions but I feel like it is kind of a hacky way to do this.
The below code is what I have so far
function clickButtons(){
var followButtons = $('.buttonClass');
var numberOfButtons = followButtons.length;
for(var i=0; i<numberOfButtons; i++){
followButtons[i].click();
}
setTimeout(nextPage, 500);
}
function nextPage(){
var nextPageBtn = $('.nextPageButtonClass');
nextPageBtn.click();
setTimeout(clickButtons,500);
}
so my question is
1. My for loop to click all the buttons is not working. Is there a better way to click every button class?
2. I need to call the second function after the first one. And when the second one is finished, I need to call the first one again and they must follow each other constantly. I tried setting a timeout and calling the other one ın both functions. But it is not working. How can I do this?
This code basically doesn't do anything. And I have been scratching my head. Sorry I am a huge javascript noob
Related
Hello I want to click a button multiple times when on a specific website. I have no idea whats wrong but maybe someone can help me out
function pay(){
document.getElementsByClassName("btn btn--lg btn--full u-margin-b--xl js-place-order2 js-place-order-btn")[0].click();
}
if(window.location.href.includes("https://www.revolveclothing.fr/r/ReviewConfirm.jsp?enteraccount")){
var sleep = setTimeout(pay, 50)
}
The element I am Clicking is the correct one since it works in the chrome console
I hope someone can help me
Since you're using setTimeout, the button will only be pressed once after 50ms is elapsed.
Assuming you want it to be pressed consistently every 50ms, you should change the setTimeout to setInterval like so:
var sleep = setInterval(pay, 50);
I have a difficult question to explain and I'm way out of my comfort zone as far as expertise in Javascript, TrueType, Angular and MxGraph are concerned... Hope to be able to explain.
I have an Angular component displaying and MxGraph. I was able to integrate MxGraph with Angular following this link (How to integrate mxGraph with Angular 4?). Even if I use Angular 7, the solution still works...
The graph is displayed correctly on the page and everything works fine, including my override of the function graphHandlerMouseUp, which I do with this code:
// Save the position of the mouse when releasing the button: used for
// detecting the target in a drag and drop
mx.graphHandlerMouseUp = mx.mxGraphHandler.prototype.mouseUp;
mx.mxGraphHandler.prototype.mouseUp = function( graph, evt ) {
currentdropX = evt.graphX;
currentdropY = evt.graphY;
mx.graphHandlerMouseUp.apply(this, arguments);
}
When I run this page for the first time, no problem happens.
Then through a button I call a page with another component (through routing). If from this page I go back to the first component (again through a routerlink) the page and the component with the MxGraph loads correctly, BUT when I use this function (i.e., release the mouse button).
It seems to me a recoursive problem, as when I put a console output like this:
// Save the position of the mouse when releasing the button: used for
// detecting the target in a drag and drop
mx.graphHandlerMouseUp = mx.mxGraphHandler.prototype.mouseUp;
mx.mxGraphHandler.prototype.mouseUp = function( graph, evt ) {
currentdropX = evt.graphX;
currentdropY = evt.graphY;
// INIFINTE LOOP HERE
console.log("Test");
mx.graphHandlerMouseUp.apply(this, arguments);
}
The "Test" is written a number of times which is continuously growing. Yet, if I understood, this was the correct way of overriding the function. Of course on the first load of the page, "Test" is displayed once. Passing to another component and then back on this it is displayed an "infinite" number of times (until I reach the: "ERROR RangeError: Maximum call stack size exceeded")...
I tried also to remove that override, and besides the obvious lack of the functionality, the very same problem happened to the function "mxDragSource", which is overridden with the same approach.
As I said: I'm not expert enough in javascript, truetype, MxGraph or Angular, so any hint, even if obvious, is very welcome!
Thanks!
The first time you run your code, you store mx library's mouseUp event in a variable and you assign a new function to mouseUp event in which you call the old mouseUpEvent.
The second time you run your code, you store your current mouseUp event (that you have modified) and you assign a function in which you call the old mouseUpEvent, which is the same you stored previously. There goes your recursion !
What you need to do is override the third-party function properly, so you don't execute your code twice.
How to do it ?
You can create a mixin and use this mixin in your componentB/ If you have no idea what is it and how to do it, please reproduce your problem in a stackblitz I'll be glad to help you to implement it.
I want to automate this page to generate exam results. I want to generate exam results from one particular date to some other particular date. On clicking the submit button, the page generates another page in a new tab.
Manually clicking 10 times will generate 10 tabs. But see the following code:
for(let i=0;i<10;i++)
{
document.querySelector('#reg1').click();
console.log(`clicked ${i}th time`)
}
I want to trigger a click 10 times and it should generate 10 tabs accordingly. But the problem is that the click works only works on the 10th iteration and spawns 1 tab only. Help me.
see
Edit:
#Jesse
See my utility full code:
var dateFrom=new Date('2017-01')
var dateTo=new Date('2019-01')
for(var i=dateFrom;i<dateTo;i.setMonth(i.getMonth()+1))
{
// console.log(`${i.getFullYear()}-${i.getMonth()}`);
// var dd=`${i.getFullYear()}-${i.getMonth()}`;
var dd=new Date(i).toISOString().substr(0,7);
console.log(dd);
document.querySelector("input#picker.form-control").value=dd;
var type='Supplementary'
document.querySelector("select#result_type.form-control.form-email.selectoption").value=type;
document.querySelector('#reg1').click();
}
Somehow you have to execute the subsequence clicking in an asynchronous manner. I got this work by this:
let i=0;
(function doClick(){
document.querySelector('#reg1').click();
i++;
if(i<10) setTimeout(() => doClick());
})()
Another approach using async function:
(async function doClick() {
for(let i=0;i<10;i++) {
document.querySelector('#reg1').click();
await new Promise(setTimeout);
}
})()
I just figured out that my browser's popup blocker is stopping the subsequent tabs from being opened.
Try turning off your popup blocker. I was able to trigger the behavior you're after with mine off.
It works when you click it because it's a user interaction, so the blocker assumes it's something you're actively trying to do. If you trigger it programmatically, repeatedly, it gets blocked. This makes sense given that one of your browser's popup blocker's primary functions is to prevent sites from trapping you in infinite popup hell.
It's because you're using the same ID. Either switch to using a class or change the ID names so they aren't identical.
i am trying to use the confirm method but for some reason the confirm window pops up several times. I googled and tried different things but unfortunately I can't get it running properly. The code is the following:
//user clicks on the delete button
$("#deletePopUpImage").click(function(){
console.log("deletePopUpimageCalled");
//get the id of the image
id = ($(this).parent().prop("id"));
//create the ajax request
data = "typ=function&functionType=deleteUserImage&id="+id;
//open the confirm box
var r = confirm("Are you sure that you want to delete this image?");
if (r == true) {
console.log("loadAjaxCAlled");
//Ajax call
loadAjax(data);
//hide the image and the loader
hideImagePopup();
} else {
//do nothing
}
});
The strange thing is that sometimes the confirm window pops up twice, sometimes three times and sometimes as expected once. That's why inserted the two console.logs.
"deletePopUpimageCalled" always appears just once. However "loadAjaxCAlled" appears several times.
In the success callback of the Ajax request I am just hiding the thumbnail div.
Do you know what's wrong with my code above?
Thanks
Stefan
Probably the code that attaches the event:
$("#deletePopUpImage").click(function(){...});
is invoked several times. Every invocation of .click(...) makes a new handler that fires when the button is clicked.
Some browsers stack up log the same entries into one (so the log doesn't extend so fast), that could be the reason you don't see "deletePopUpimageCalled" many times.
It would the best to check this by debugging it in the browser.
Ok I found the problem. In the Ajax success handler I set the div of the image, that was deleted, to display:none instead of deleting it. Thus divIds could occur twice, three times, etc. After changing the code to delete, it worked smoothly.
I've edited the default alert() function like this:
window.alert = function(str){
//custom alert
}
Essentially, the new function will show an HTML <div> modal.
Backstory:
I want to answer to this question because I am having a problem. The alert is hidden and will show when the custom alert function is called. So the custom alert is basically showing the element and changing it's text. Therefore, when I have multiple alert() calls, only the last message is displayed! :(
But, unlike the default alert box. It of course won't pause the webpage until the alert goes away like the default alert() function.
Is it possible to imitate this "pause the webpage" behavior?
Also, is there another way other then using setTimeout() to check if isCustomAlertOpen == true to delay another custom alert from triggering until the current one is dismissed?
Edit:
Is there a way to queue up the custom alerts?
I don't mind jQuery, but I thought it might be overpowered here.
My question title is bad. Can someone think of a better title for me please?
There is no way to block the execution because JavaScript is asynchronous (except obviously 3 modal functions and XmlHttpRequest).
For the same reason, you can't wait for a previous alert to be closed, but you can use events to create a stack of alerts using this pattern:
window.alert = (function() {
var stack = [];
var showNextAlert = function() {
var div = document.createElement("div");
/* Here, configure the div, show the string from stack[0] and add it to the document ... */
var okButton = /* ... */;
okButton.addEventListener("click", function() {
div.parentNode.removeChild(div);
stack = stack.slice(1);
if(stack.length > 0) {
showNextAlert();
}
});
}
return function(msg) {
stack.push(msg);
if(stack.length == 1) {
// Show it immediately if the stack is empty
showNextAlert();
}
};
})();
You should also use another name for this function instead of changing native properties (here window.alert).
Is it possible to imitate this "pause the webpage" behavior?
The answer to this is no. There are ways to block the ui (sync ajax call, long loop etc). But you wouldn't be able to stop these when the user has click the ok button.
A better approach would be to restructure the code so that it didn't run synchronously. Ie you wouldn't need to block the ui while waiting for the user.
Also, is there another way other then using setTimeout() to check if isCustomAlertOpen == true to delay another custom alert from triggering until the current one is dismissed?
One way to do this is: instead of setting a flag in one place and checking it repeatedly in another. You can use the concept of events. One part of code is waiting for an event to be triggered and another part triggers it. There is a library in jQuery which can do this for you or you could read up on it and write your own.