How can I stop triggering click event after the first trigger? - javascript

Using a triggered click on my website (Its not on the website not due to the bug).
Website: 3six-d.co.uk
setTimeout(function() {
$('a[href$="#about"]').trigger('click');
}, 5000);
However as you could possible guess, that works fine. Until someone click the Enter button faster than 5 seconds, and they goes to a different tab. Say I clicked enter then went to the contact form. After the 5 seconds it would then redirect me back to about us. If there a way that if the user has already clicked enter it stops the trigger?
Thanks

You can try this
var isClicked = false;
setTimeout(function() {
if (!isClicked) {
isClicked = true;
$('a[href$="#about"]').trigger('click');
}
}, 5000);
With the former approach you guarantee that the click is only triggered once. No matter how often the user clicks.

How about a global Boolean variable that is set to true once the trigger is clicked? If the global Boolean is true, it does not allow the trigger event to run again. And, when the global is set to true, another timer is started that resets it to false after five or six seconds?

Detect when a user click the "Enter" button (look this up, its easy) then clear the timeouts using:
var id = window.setTimeout(function() {}, 0);
while (id--) {
window.clearTimeout(id);
}

Related

Fire clicks inside of setInterval only one time with jQuery or Javascript

A website shows a cookie consent after arround 1-2 seconds, if a user has not give a consent. That means, the consent is not in the source directly but in the dom after 1-2 seconds.
I have to detect if a user clicks on a button inside of the consent div. If I use the document ready function, the click is not detected. I have to use setInterval because setTimeout doesn't work. The reason is that another window has to be opened in the Consent and therefore I cannot use a fixed time as with a timeout.
The Consent div is sourrended by a div with the class name "cmp-consent". I check the dom with setInterval every 1800ms for that div. If the div is not existend after 1800ms the user has already given the consent and I clear the setInterval.
BUT:
If the div exists, it waits until the user clicks on the second button in the consent header. When this click is made, another click is made and the window is closed. This is working very well.
The problem is, if a user does not click this button (consent-header button: eq (1)) immediately, the setInterval will of course continue to run. You can see the counter in front of the console.log is increasing. If a user then clicks the button, the subsequent clicks are carried out as often as there is a setInverval. This takes too long if a user waits, for example, longer then a minute. The question is, how do you manage that an action is only carried out once in a setInterval.
Here is my script:
var userConsent = window.setInterval(function() {
if ($(".cmp-consent")[0]){
console.log('consent exists');
$( ".consent-header button:eq(1)" ).click(function(){
console.log('User clicked the button');
$(".primary button").click();
$(".close-icon").click();
window.clearInterval(userConsent);
});
} else {
console.log('consent given, remove interval');
window.clearInterval(userConsent);
}
}, 1800);
Here is a working example of #cloned's suggustion.
document.addEventListener("click", function(e) {
for (var target=e.target; target && target!=this; target=target.parentNode) {
// loop parent nodes from the target to the delegation node
if (target.matches('.consent-header')) {
handler.call(target, e);
break;
}
}
}, false);
function handler() {
console.log('do stuff');
}
<div class="consent-header">
<button>I agree</button>
</div>

Fire event when user stops to click

I'm able to detect a click on a button using jQuery
$('#myButton').click(function(){
// do something
});
but, when the user clicks many times on the button, it fires unnecessary intermediaries events.
I would like to fire the event only on the last click on the button.
Something like:
$('#myButton').lastClickOnASequenceOfClicks(function(){
// ignore the multiple clicks followed
// do something only on the last click of a sequence of clicks
});
With that, if the user clicks 10 times (with a little interval of time), it should fires an event only on the tenth click.
Each click resets the timer.
var timer;
$("#myButton").click(function () {
var timeToWait = 1000;
clearTimeout(timer);
timer = setTimeout(function () {
// do something only on the last click
}, timeToWait);
}
Update
Another way to solve this problem of handling 'multiple click events' generated by the user is to do what was mentioned in the OP comments section. do something on the first click THEN disable the button so the user cannot click it anymore (maybe also set a time for the button to become enabled again)
var timer, timeToWait = 5000, selector ="#myButton";
$(selector).click(function (e) {
$(this).attr("disabled", "disabled");
// do something
// Then wait a certain amount of time then remove the disabled attr on your button
timer = setTimeout(function () {
$(selector).removeAttr("disabled");
}, timeToWait);
})

How to create a dialog box that appears without any event triggered in jQuery?

I'm using jQuery 1.9.1, and jQuery Mobile 1.3.1, and I want to create a dialog box, with only one button, informing the user that their time is up in my game. The point is that, as long as I can see dialogs in jQuery appear after certain eventType. For example, after a button is clicked the dialog can appear. But in my situation I don't have any event, it must just appear automatically when the condition in the if statement is true. And when the user clicks OK button on the widget, he/she should be transferred to the page referred below. Any idea how to achieve it?
function showTimer() {
if (timestamp.getMinutes().pad(2) == "59" && timestamp.getSeconds().pad(2) == "59") {
// dialog goes here...
$.mobile.navigate("#finalPage");
}
return false;
}
It's all possible using jQuery:
//Initialise the dialog first
var dialog = $('<p>Are you sure?</p>').dialog({
autoOpen:false,
buttons: {
"Cancel": function () {
$.mobile.navigate("#finalPage"); // Your custom code for navigation on button click
}
}
});
setTimeout(function(){ // When your condition is met, just call the dialog using this code
dialog.dialog('open');
},2000);
Here,I have used timeout just to show how you can open the dialog at any stage without triggering any click.
Demo : http://jsfiddle.net/lotusgodkk/GCu2D/175/
start a timer with setInterval, and check the condition every x milliseconds

Call a function after specified amount of time without changes to the DOM

Suppose you want to display an alert 3 seconds after there no changes in the DOM just after pressing a button that triggers a lot of changes.
An example with a button gotten via jQuery:
$someButton.on('click',function(){
setInterval(function(){
if( noChangesSinceLastTime()){
time += 100;
}
else{
time = 0;
}
if( time == 3000){
alert("3 seconds without changes!");
}
},100);
});
Assume that the click event on that button has some other binding that excecutes a series of functions for DOM manipulation.
How could I achieve something as the noChangesSinceLastTime()function?
More on my specific problem
I have an HTML+JS+CSS slideshow which works with many simultaneous clients in a network.
When a new client joins, he is automatically sent to the start of the current slide being watched by others.
What I want to do is that, just after it finishes loading the current slide, trigger the clicks necessary to sync the new client with others (since every click inside a slide triggers an animation step, and most slides have multiple steps).
I cannot add a callback in the JS slideware, since it's an obfuscated JS not made by me.
This is just pseudo code, but you could try something like this:
timer = setTimeout(function(){
alert("3 seconds without changes!");
}, 3000);
if(/*some change happens*/) {
clearTimeout(timer);
}
You could listen to all of the DOM Mutatation events and set a flag if any of those are were triggered.
Then in you interval function, you could check that flag and do whatever logic you want. =).
Regards,

Way to know if user clicked Cancel on a Javascript onbeforeunload Dialog?

I am popping up a dialog box when someone tries to navigate away from a particular page without having saved their work. I use Javascript's onbeforeunload event, works great.
Now I want to run some Javascript code when the user clicks "Cancel" on the dialog that comes up (saying they don't want to navigate away from the page).
Is this possible? I'm using jQuery as well, so is there maybe an event like beforeunloadcancel I can bind to?
UPDATE: The idea is to actually save and direct users to a different webpage if they chose cancel
You can do it like this:
$(function() {
$(window).bind('beforeunload', function() {
setTimeout(function() {
setTimeout(function() {
$(document.body).css('background-color', 'red');
}, 1000);
},1);
return 'are you sure';
});
});
The code within the first setTimeout method has a delay of 1ms. This is just to add the function into the UI queue. Since setTimeout runs asynchronously the Javascript interpreter will continue by directly calling the return statement, which in turn triggers the browsers modal dialog. This will block the UI queue and the code from the first setTimeout is not executed, until the modal is closed. If the user pressed cancel, it will trigger another setTimeout which fires in about one second. If the user confirmed with ok, the user will redirect and the second setTimeout is never fired.
example: http://www.jsfiddle.net/NdyGJ/2/
I know this question is old now, but in case anyone is still having issues with this, I have found a solution that seems to work for me,
Basically the unload event is fired after the beforeunload event. We can use this to cancel a timeout created in the beforeunload event, modifying jAndy's answer:
$(function() {
var beforeUnloadTimeout = 0 ;
$(window).bind('beforeunload', function() {
console.log('beforeunload');
beforeUnloadTimeout = setTimeout(function() {
console.log('settimeout function');
$(document.body).css('background-color', 'red');
},500);
return 'are you sure';
});
$(window).bind('unload', function() {
console.log('unload');
if(typeof beforeUnloadTimeout !=='undefined' && beforeUnloadTimeout != 0)
clearTimeout(beforeUnloadTimeout);
});
});
EDIT: jsfiddle here
Not possible. Maybe someone will prove me wrong... What code do you want to run? Do you want to auto-save when they click cancel? That sounds counter-intuitive. If you don't already auto-save, I think it makes little sense to auto-save when they hit "Cancel". Maybe you could highlight the save button in your onbeforeunload handler so the user sees what they need to do before navigating away.
I didn't think it was possible, but just tried this idea and it works (although it is some what of a hack and may not work the same in all browsers):
window.onbeforeunload = function () {
$('body').mousemove(checkunload);
return "Sure thing";
};
function checkunload() {
$('body').unbind("mousemove");
//ADD CODE TO RUN IF CANCEL WAS CLICKED
}
Another variation
The first setTimeout waits for the user to respond to the browser's Leave/Cancel popup. The second setTimeout waits 1 second, and then CancelSelected is only called if the user cancels. Otherwise the page is unloaded and the setTimeout is lost.
window.onbeforeunload = function(e) {
e.returnValue = "message to user";
setTimeout(function () { setTimeout(CancelSelected, 1000); }, 100);
}
function CancelSelected() {
alert("User selected stay/cancel");
}
window.onbeforeunload = function() {
if (confirm('Do you want to navigate away from this page?')) {
alert('Saving work...(OK clicked)')
} else {
alert('Saving work...(canceled clicked)')
return false
}
}
with this code also if user clicks on 'Cancel' in IE8 the default navigation dialog will appear.

Categories

Resources