Click event on a button with SetInterval Method - javascript

I'm not able to figure out how this can be accomplished. I'm working on the chrome extension and I have a setInterval method which monitors a button on a page and when its clicked, it runs a function. but the problem is, when I click the button, the function runs multiple times and I clearly understand this is because of the Interval function, but I want the setInterval to run always on this page so that I can monitor if the button is clicked or not. Below is my code
$(function(){
var url=window.location.href;
findAction(url);
}
function findAction(url){
setInterval(()=>{
Acceptbtn = $("[slot=primary-content-area")[4].querySelector("sn-inbox");
if(Acceptbtn !== undefined && Acceptbtn !== null){
Acceptbtn.addEventListener('click', myFunction);
}
function myFunction() {
console.log("clicked");
runAction(url)
};
},1000);
}
Is there any way to tackle this situation or have I made something simple, complicated or Is my approach completely wrong.?
Below is the Div which my extension monitors for the Accept button -
And once the Accept button is clicked, this is what happens
The Interval method keeps checking for this button and once found and I click on it, I want the runAction(url) function to execute. With my current code, the function gets executed but multiple times

Only add an event listener once
Also the selector is incorrect if sn-inbox is a class and [slot=primary-content-area] was missing a ]
Here I delegate - if you delegate to the closest static container (here document, because I do not know the closest container in your case), you can ALWAYS find the button when it is there:
const url = window.location.href;
$(document).on("click", "[slot=primary-content-area]", function() {
if ($(this).index() === 3) { // 0 based - so the 4th slot
const $inbox = $(this).find(".sn-inbox");
if ($inbox.length > 0) {
$inbox.html("running");
runAction(url)
}
}
})
Example code to execute the functions:
https://jsfiddle.net/mplungjan/p93cj0Le/
$(function() {
const runAction = url => console.log("running", url);
const url = window.location.href;
$(document).on("click", "[slot=primary-content-area]", function() {
if ($(this).index() === 3) { // 0 based
const $inbox = $(this).find(".sn-inbox");
if ($inbox.length > 0) {
$inbox.html("running");
runAction(url)
}
}
})
// testing the code
setInterval(() => {
$("#container").html(`<div>
<div slot="primary-content-area"></div>
<div slot="primary-content-area"></div>
<div slot="primary-content-area"></div>
<div slot="primary-content-area"><button class="sn-inbox">Click</button></div>
</div>`)
}, 5000)
setTimeout(() => $("#container").html(""), 2000)
})
<div id="container">
</div>

Related

JavaScript - getElementById doesn't work on specific page

I want to automate clicking the agree button to Google's cookie policies.
(I clean cookies after closing a tab, and I don't want to create a google account, so I get asked every time I use google)
There is a div element with the ID "introAgreeButton" that I'm trying to access with my script:
<div role="button" id="introAgreeButton" [...]></div>
However, document.getElementById('introAgreeButton') always returns null.
My first thought was that the element wasn't loaded by the time my function was executed. But it doesn't work if I execute it on window.onload, or even if I run it in a loop until the element is definitely there:
window.onload = function() {
var x = document.getElementById('introAgreeButton')
console.log(x)
}
Output:
null
function loop() {
var x = document.getElementById('introAgreeButton')
if (x) {
console.log('success')
} else {
loop()
}
}
Output:
null
null
null
...
Can be tested on https://www.google.com/search?hl=en&q=test
Anyone have an idea why this is and how to solve it?
Edit: I execute the script via the browser extension TamperMonkey
You can use setInterval to check if element is rendered in DOM like this :
document.addEventListener('DOMContentLoaded', function () {
var intervalID = null;
function checkElementInDOM () {
var element = document.getElementById('introAgreeButton');
if (element) {
clearInterval(intervalID);
// DO YOUR STUFF HERE ...
}
}
intervalID = setInterval(checkElementInDOM, 100);
});
To be used intelligently, however, so as not to have a setInterval which works continuously. Maybe think about adding a maximum number of attempts.

jquery .on accumulates click events

I have a component wich manages a view that contains arcticles with games and to preventing overload of memory and spend time using a for with every article if it is open on a new window or reloads the current page (with a checkbox), I made this code, when the user clicks on an article(each one has the class "flashgame"), depending of user's choice it will go to a game and, or reload the current page, or, open in another window and play the game
this is my code :
jQuery(document).on('click', '.flashgame', function () {
console.log(this);
let denom = jQuery(this).find('.urlGame').data('denom');
let val = jQuery(this).find('.urlGame').data('val');
if (denom != "") {
let gamear = denom.toString().split(',');
let orderset: any[] = gamear;
if (orderset.length > 1) {
that.multidenoms = orderset.sort((a, b) => { return a - b; });
that.gameId = val;
console.log("modalflash is showing");
that.modalflash.show();
}
else {
that.goToFlash(val, gamear);
}
}
else {
that.goToFlash(val);
}
});
and this is the article:
but for any reason when I made this change in the project, the page has been accumulate the number of clicks, for instance :
Hard reload and the number of "clicks" starts in zero, i go to another page and then go back, the click has incremented by one, an so on.
So, what should I do?, Is there any workaround to prevent this "clicks" overload?
What I like to do is use .off before .on when rebinding event handlers.
So something like this:
jQuery(document).off('click', '.flashgame').on('click', '.flashgame', function () { ...

How to use setInterval to have Refresh on by default but off with a switch

I would like to use setInterval to control a refresh of my page. I would like to have it running by default (on when the page loads) but I need to be able to turn it off at certain times. So I've written what you see below. The problem is that the refresh is not on when the page first displays. It only comes on after I click the button twice to re-activate the update the setInterval controls.
My html button definition looks like this;
<button id="autoref" type="button" name="autoref" onclick="stopAutoRef();">Stop Auto Ref</button>
My stopAutoRef function looks like this;
function stopAutoRef() {
if ($("#autoref").text() == "Stop Auto Ref") {
$("#autoref").html('Start Auto Ref'); // You see this if Refresh is not automatically happening
clearInterval();
}else {$("#autoref").html('Stop Auto Ref'); // You see this if Refresh is automatically happening
setInterval(function() {showActivities(document.getElementById("select1").value);}, 60000);
}
}
setInterval returns an ID which must be passed to clearInterval to stop it. You'd also want to call your function, startAutoRef(), immediately in addition to on click to initiate the default behavior of refreshing.
var autoRefId = null;
function stopAutoRef() {
if (autoRefId !== null) {
$("#autoref").html('Start Auto Ref'); // You see this if Refresh is not automatically happening
clearInterval(autoRefId);
autoRefId = null;
} else {
$("#autoref").html('Stop Auto Ref'); // You see this if Refresh is automatically happening
autoRefId = setInterval(function() {showActivities(document.getElementById("select1").value);}, 60000);
}
}
stopAutoRef();
clearinterval generally requires a argument of which function to stop. so try this maybe?
try this:
HTML:
<button id = 'b' onclick = 'stop(this)' value = 'true'>Stop ref</button>
Javascript:
var myfunc = setInterval(function(){
location.reload();
},1000);;
function stop(button){
if(button.innerHTML == 'Stop ref'){
button.innerHTML = 'Start ref';
clearInterval(myfunc);
}
else{
button.innerHTML = 'Stop ref';
myfunc = setInterval(function(){
location.reload();
},1000);;
}
}

How to start javascript setinterval once cleared?

I have a setinterval that runes every 5 seconds. this works fine on page load.
I have the following scenarios:
Load page with interval (WORKS)
press button and load new content and stopp interval(WORKS)
Once the new content is no longer desiered, dissmiss it, return to first content and start interval again(DOES NOT WORK)
I have saftys suchs as events for window.blur that also stops the interval so that the browser does not commponsate for all the missing intervals if i would change tabs or something. Keep in mind that step 3 did not work BUT if i would after step 3 change a tab and then return to my original page(execute blur) the interval would start working again.
NOTE all content loading here exept page load is done with ajax calls.
My code:
initializing:
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function() {
$.automation.tanks.tableInit();
});
binding function:
bindIntervalEvent: function (target, url, callback) {
$(window)
.on("focus.mine",
function() {
$.automation.worker.setUpdateInterval(target, url, callback);
})
.on("blur",
function() {
$.automation.worker.stopUpdateInterval();
}).trigger("focus.mine");
}
interval function:
setUpdateInterval: function (target, url, callback) {
if ($.automation.globals.globalInterval.value.length === 0) {
$.automation.globals.globalInterval.value.push(window.setInterval(
function () {
var options = {
loadTarget: target
}
$.automation.worker.getView(url,
function() {
if (callback)
callback();
},
options);
},
5000));
}
}
the function that stops the interval:
stopUpdateInterval: function () {
if ($.automation.globals.globalInterval.value.length === 0)
return;
console.log("deleting");
for (var i = 0; i <= $.automation.globals.globalInterval.value.length; i++) {
window.clearInterval($.automation.globals.globalInterval.value[i])
$.automation.globals.globalInterval.value.splice(i, 1);
console.log($.automation.globals.globalInterval.value.length);
}
}
when stopping the interval i also remove the window bindings:
unBindIntervalEvent: function() {
$(window).off("focus.mine");
$(window).unbind("blur");
}
Back to step 3:
My sucess method in the callback to my getviewfunction is identical to what i execute in the beginning
code:
$(".updatelatest")
.on("click",
function () {
var _this = $(this);
var options = {
loadTarget:"#TanksContent"
}
$.automation.worker.getView("/Tank/GetTanks",
function (data) {
$(_this).switchClass("col-md-5", "col-md-1", 1000, function() {
$(_this).addClass("hidden");
$(".search").switchClass("col-md-5", "col-md-12", 1000, "easeInOutQuad");
})
$.automation.tanks.tableInit();
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function () {
$.automation.tanks.tableInit();
});
$(window).trigger("blur");
}, options);
});
but this does not start the interval. it is clearly initialized since it works when window.blur is executed for example when I change tab but for some reason this is not working beyond that.
i tried triggering the windows blur event and nothing happened, i tried triggering my custom window event "focuse.mine" but nothing happens.
I did not notice this while developing since I had firebug open and every time i checked scripts or css or the console the blur function was executed so I assumed that my code worked as intended but now that it is deployed I notice this.
My head is pounding beyond reason and I can't for figure out where I have gone wrong.
Well this was a fun one. I simply found that when calling the setUpdateInterval(); function directly it gave me the desiered result.
I realized that the reason I had them split like I did was becaouse of the blur event. "Focus.mine" is triggered to start the inteval again ocne a user comes back to the page.

How to create timer in my case?

I am trying to have my button doing two things.
init a timer to call a function
call the same function
I have something like the following
test.prototype.setupEvent= function(){
var instance = this;
$('#btn').on('click', function(){
clearInterval(instance.timer);
this.showStuff()
instance.timer=setInterval(function(){
instance.showStuff()
},10000);
})
}
test.prototype.showStuff= function(btnID){
//jump to another page
}
My problem is that I want the user be able to see some contents after 10 second when they first click it, however, if they click the button again before 10 second is up, they can see the contents too. I am not sure how to distinguish the two different states with one click event. Can anyone help me out? Thanks!
Try
test.prototype.setupEvent = function () {
var instance = this;
$('#btn').on('click', function () {
//if there is a timer running then clear the timer, show the content and delete the timer reference
if (instance.timer) {
clearInterval(instance.timer);
instance.showStuff();
delete instance.timer
return;
}
//also you may want to use setTimeout() not setInverval()
instance.timer = setInterval(function () {
instance.showStuff();
delete instance.timer
}, 10000);
})
}
test.prototype.showStuff = function (btnID) {
//jump to another page
}

Categories