Temporarily ignore click event in Meteor Template - javascript

I want to temporarily ignore any click events on a button #firstBtn for 5 seconsd after it has been clicked on.
Template.sidebar.events({
'click #firstBtn': function () {
//...
}
})
How can this be done? Looked into
$('#firstBtn').unbind('click', eventHandler)
Meteor.setTimeout(function(){
$('#firstBtn').bind('click', eventHandler)
}, 5000)
but how should we refer to the click event handler in template sidebar?

Try something like this:
First, initialize a variable to set the timeout, and a variable to say if the button has been clicked. This is needed for the conditional statement.
var timeout = 5000; //5000 milliseconds is equal to 5 seconds
var isClickable = true;
Then, Try some conditional testing like this:
$('#firstBtn').click(function(){
if(isClickable){
...
//standard link handling code
...
isClickable = false;
setTimeout(function(){isClickable = true;},timeout)
}else{
return;
}
});
This will only allow the click event's handling code to execute if the timeout is comeplete.
Good Luck!

Related

jQuery preventing click event to be executed in case of double or multiple clicks by user

I have some code in which I want to stop user from clicking a button multiple times. I have tried multiple things including disabling button on click and enabling it at the end but nothing is working perfectly.
I want to stop "click" event of jQuery (single click) from being executed in case user has clicked on it two or more times.
This is my js fiddle: https://jsfiddle.net/tm5xvtc1/6/
<p id="clickable">Click on this paragraph.</p>
<p id="main">
I will change on clicking
</p>
$("#clickable").click(function(){
$('#main').text('Single click');
});
$("#clickable").dblclick(function(){
$('#main').text('Double click')
});
If i try double clicking, the behavior is:
Single click gets executed first => Then double click gets executed.
I want to prevent single click event to be executed in case user clicks on button multiple times. Suggestions?
According to the jquery documentation:
It is inadvisable to bind handlers to both the click and dblclick events for the same element. The sequence of events triggered varies from browser to browser, with some receiving two click events before the dblclick and others only one. Double-click sensitivity (maximum time between clicks that is detected as a double click) can vary by operating system and browser, and is often user-configurable.
That being said, you can accomplish what you want by using $('#main').addClass('clicked-once'); and testing for the existence of that class before executing the code inside the single click handler.
$("#clickable").click(function(){
if($(this).hasClass('clicked-once')){
return false;
} else {
$(this).addClass('clicked-once');
$('#main').text('Single click');
}
});
$("#clickable").dblclick(function(){
$('#main').text('Double click')
});
jsfiddle: https://jsfiddle.net/nbj1s74L/
This is bit tricky. You need to calculate the time taken for double click and trigger events. Try the below code
$(function() {
var clicks = 0;
var timer = null;
$("#clickable").on("click", function(e) {
clicks++; // Increment click counter
if (clicks === 1) {
timer = setTimeout(function() {
$('#main').text('Single click');
clicks = 0; //Reset
}, 800); // Increase or decrease if there is slowness or speed
} else {
clearTimeout(timer); //prevent single-click action
$('#main').text('Double click')
clicks = 0; // Reset
}
});
$("#clickable").on("dblclick", function(e) {
e.preventDefault(); //Prevent double click
});
});
Demo : https://jsfiddle.net/cthangaraja/e9e50jht/2/
I found the answer for this.
$(document).on('click', '#clickable', function () {
$(this).prop('disabled', true);
//LOGIC
setTimeout(function () { $(this).prop('disabled', false); }, 500);
});
Its working for me. The set timeout for 500ms doesn't allow code to be re-entrant which is working fine for me at various network/device speeds.
Slight change in the answer given by maverick.
In the set timeout method, reference of this is changed. Hence the code should be changed to:
$(document).on('click', '#clickable', function () {
var self = this;
$(this).prop('disabled', true);
//LOGIC
setTimeout(function () { $(self).prop('disabled', false); }, 500);
});
window.numOfClicks = 0
$("#clickable").click(function(){
window.numOfClicks += 1;
//rest of code
});
Record the number of clicks to use for your functions, example:
if (window.numOfClicks > 1){ //do this}
If you need it reset just put a timeout in the .click()
var resetClicks = function(){ window.numOfClicks = 0 }
$("#clickable").click(function(){
//your other code
setTimeout(resetClicks,5000); //reset every 5 seconds
});

Prevent certain functionality based on element clicked

I've got a button .btn-1 that when clicked also triggers click on .btn-2 I can't think of a way to do the following: when .btn-2 is clicked also trigger click on .btn-1 however in this case dismiss its functionality to trigger click on '.btn-2' to prevent infinite loop. Is there a way to achieve this?
You can pass additional data to your handler using .trigger() method:
$('.btn-2').on('click', function(event, skip) {
// if the skip parameter is a truthy value
// don't trigger the event
if ( !skip ) {
$('.btn-1').trigger('click', [true]);
}
});
$('.btn-2').trigger('click', [true]);
you can use a boolean that switches:
var done=true;
$('.btn-1').click(function(){
$('log').html($('log').html()+'bt1 pressed<br>')
if(done){
done=false;
$('.btn-2').click()
}
done=true;
})
http://jsfiddle.net/2o3k5wet/
A more elegant way to do this:
$('.btn-1, .btn-2').on('click', function() {
// do common stuff
if ($(this).is('.btn-1')) {
// do stuff only for 1
}
// do common stuff
});

Jquery disabled an event, and re activate it later

1 - I've gat an html tag with data-needlogged attribute.
2 - I would like to disable all click events on it.
3 - When the user click on my element, I want to display the authentification popin.
4 - When the user will be logged, I would like to launch the event than I disabled before.
I try something like the following code but it miss the "...?" part.
Play
<script>
// 1 - some click events has been plug on the tag.
jQuery('[data-btnplay]').on('click', function() {
alert('play');
return false;
});
// 2 - disabled all click events
jQuery('[data-needlogged]').off('click');
// 3 - Add the click event to display the identification popin
var previousElementClicked = false;
jQuery('body').on('click.needlogged', '[data-needlogged]="true"', function() {
previousElementClicked = jQuery(this);
alert('show the identification popin');
return false;
});
jQuery(document).on('loginSuccess', function() {
// 4 - on loginSuccess, I need to remove the "the show the identification popin" event. So, set the data-needlogged to false
jQuery('[data-needlogged]')
.data('needlogged', 'false')
.attr('data-needlogged', 'false');
// 4 - enable the the initial clicks event than we disabled before (see point 2) and execute then.
// ...?
jQuery('[data-needlogged]').on('click'); // It doesn't work
if (previousElementClicked) {
previousElementClicked.get(0).click();
}
});
</script>
Thanks for your help
Thank for your answer.
It doesn't answer to my problem.
I will try to explain better.
When I declare the click event on needlogged element, I don't know if there is already others click event on it. So, in your example how you replace the alert('play'); by the initial event ?
I need to find a way to
1 - disable all click events on an element.
2 - add a click event on the same element
3 - and when a trigger is launch, execute the events than I disabled before.
So, I found the solution on this stackoverflow
In my case, I don't realy need to disable and enable some event but I need to set a click event before the other.
Play
<script>
// 1 - some click events has been plug on the tag.
jQuery('[data-btnplay]').on('click', function() {
alert('play');
return false;
});
// [name] is the name of the event "click", "mouseover", ..
// same as you'd pass it to bind()
// [fn] is the handler function
jQuery.fn.bindFirst = function(name, fn) {
// bind as you normally would
// don't want to miss out on any jQuery magic
this.on(name, fn);
// Thanks to a comment by #Martin, adding support for
// namespaced events too.
this.each(function() {
var handlers = $._data(this, 'events')[name.split('.')[0]];
// take out the handler we just inserted from the end
var handler = handlers.pop();
// move it at the beginning
handlers.splice(0, 0, handler);
});
};
var previousElementClicked = false;
// set the needlogged as first click event
jQuery('[data-needlogged]').bindFirst('click', function(event) {
//if the user is logged, execute the other click event
if (userIsConnected()) {
return true;
}
//save the click element into a variable to execute it after login success
previousElementClicked = jQuery(this);
//show sreenset
jQuery(document).trigger('show-identification-popin');
//stop all other event
event.stopImmediatePropagation();
return false;
});
jQuery(document).on('loginSuccess', function() {
if (userIsConnected() && lastClickedElement && lastClickedElement.get(0)) {
// if the user has connected with success, execute the click on the element who has been save before
lastClickedElement.get(0).click();
}
});

How Store and Disable Event of another element Temporary

I am looking for a way to manage the events. I have a hover function for element A, and click function for element B. I want to disable A`s hover function temporary while the second click of B.
I am looking for a way that not necessary to rewrite the hole function of A inside of B. Something very simply just like "Store and Disable Event, Call Stored Function"
I found some technique like .data('events') and console.log. I tired but failed, or maybe I wrote them in a wrong way.
Please help and advice!
$(A).hover();
$(b).click(
if($.hasData($(A)[0])){ // if A has event,
//STORE all the event A has, and disable
}else{
//ENABLE the stored event for A
}
);
Try this
var hoverme = function() {
alert('Hover Event Fired');
};
$('.A').hover(hoverme);
var i = 0;
$('.B').on('click', function(){
if(i%2 === 0){
// Unbind event
$('.A').off('hover');
}
else{
// Else bind the event
$('.A').hover(hoverme);
}
i++;
});
Check Fiddle
I think that what you want to do is something like this (example for JQuery 1.7.2):
$("#a").hover(function(){alert("test")});
$("#a")[0].active=true;
$("#b").click(function(){
if($("#a")[0].active){
$("#a")[0].storedEvents = [];
var hoverEvents = $("#a").data("events").mouseover;
jQuery.each(hoverEvents , function(key,handlerObj) {
$("#a")[0].storedEvents.push(handlerObj.handler);
});
$("#a").off('hover');
}else{
for(var i=0;i<$("#a")[0].storedEvents.length;i++){
$("#a").hover($("#a")[0].storedEvents[i]);
}
}
$("#a")[0].active = ($("#a")[0].active)==false;
});​
JSFiddle Example
But there are a couple of things that you must have in consideration:
This will only work if you add the events with JQuery, because JQuery keeps an internal track of the event handlers that have been added.
Each version of JQuery handles data("events") differently, that means that this code may not work with other version of JQuery.
I hope that this helps.
EDIT:
data("events") was an internal undocumented data structure used in JQuery 1.6 and JQUery 1.7, but it has been removed in JQuery 1.8. So in JQuery 1.8 the only way to access the events data is through: $._data(element, "events"). But keep in mind the advice from the JQuery documentation: this is not a supported public interface; the actual data structures may change incompatibly from version to version.
You could try having a variable that is outside the scope of functions a and b, and use that variable to trigger the action to take in function b on function a.
var state;
var a = function() {
if(!state) {
state = true;
// Add hover action and other prep. I'd create a third function to handle this.
console.log(state);
};
var b = function() {
if(state) {
state = false;
// Do unbinding of hover code with third function.
} else {
state = true;
// Do whatever else you needed to do
}
}
Without knowing more about what you're trying to do, I'd try something similar to this.
It sounds like you want to disable the click hover event for A if B is clicked.
$("body").on("hover", "#a", function(){
alert("hovering");
});
$("#b").click( function(){
$("body").off("hover", "#a", function() {
alert("removed hovering");
});
});
You can use the jQuery off method, have a look at this fiddle. http://jsfiddle.net/nKLwK/1/
Define a function to assign to hover on A element, so in b click, call unbind('hover') for A element and in second click on b element define again a function to hover, like this:
function aHover(eventObject) {
// Todo when the mouse enter object. You can use $(this) here
}
function aHoverOut(eventObject) {
// Todo when the mouse leave the object. You can use $(this) here
}
$(A).hover(aHover, aHoverOut);
// ...
$(b).click(function(eventObject) {
if($.hasData($(A)[0])){ // if A has event,
$(A).unbind('mouseenter mouseleave'); // This is because not a event hover, jQuery convert the element.hover(hoverIn, hoverOut) in element.bind('mouseenter', hoverIn) and element.bind('mouseleave', hoverOut)
}else{
$(A).hover(aHover, aHoverOut);
}
});
There are provably better ways to do it, but this works fine, on document ready do this:
$("#a")[0].active=false;
$("#b").click(function(){
$("#a")[0].active = ($("#a")[0].active)==false;
if($("#a")[0].active){
$("#a").hover(function(){alert("test")});
}else{
$("#a").off('hover');
}
});
JSFiddle example
You can use .off function from jQuery to unbind the hover on your "a" element.
function hoverA() {
alert('I\'m on hover');
}
$('#a').hover( hoverA );
var active = true;
$('#b').on('click', function(){
if(active){
$('#a').off('hover');
active = false;
} else{
$('#a').hover(hoverA);
active = true;
}
});
Live demo available here : http://codepen.io/joe/pen/wblpC

JavaScript - Hook in some check on all 'click' events

So I have a regular onclick event attached to a few buttons, each function that handles the onclick event does something different (so I can't reuse the same function for both events).
element1.onclick = function() {
if(this.classList.contains('disabled') {
return false;
}
// For example make an AJAX call
};
element2.onclick = function() {
if(this.classList.contains('disabled') {
return false;
}
// For example hide a div
};
I'm writing duplicate code for this 'disabled' class check, I want to eliminate this by hooking in some common onclick check then fire the regular onclick event if that check passes.
I know the below won't work but I think it will illustrate what I'm trying to do:
document.addEventListener('click', function() {
// 1. Do the disabled check here
// 2. If the check passes delegate the event to the proper element it was invoked on
// 3. Otherwise kill the event here
});
I'm not using any JavaScript library and I don't plan to, in case someone comes up with 'Just use jQuery' type answers.
EDIT: Had to pass boolean third argument to addEventListener as true and everything is fine.
Use event capturing, like so:
document.addEventListener('click', function(event) {
if (/* your disabled check here */) {
// Kill the event
event.preventDefault();
event.stopPropagation();
}
// Doing nothing in this method lets the event proceed as normal
},
true // Enable event capturing!
);
Sounds like you need to set the capture flag to true and then use .stopPropagation() on the event if a certain condition is met at the target, f.ex:
document.addEventListener('click', function(e) {
if ( condition ) {
e.stopPropagation();
// do soemthing else, the default onclick will never happen
}
}, true);​​​​​​​​​​​​​​​​​​​​​​
Here is a demo: http://jsfiddle.net/v9TEj/
You can create a generic function that receives a callback:
//check everything here
function handleOnclick(callback) {
if(this.classList.contains("disabled")) {
return false;
} else {
callback(); //callback here
}
}
//and now on every onclick, just pass the custom behavior
element1.onclick = function() {
handleOnClick(function() {
console.log('element1 onclick fire'); // For example hide a div
});
};
element2.onclick = function() {
handleOnClick(function() {
console.log('element2 onclick fire'); // For example ajax request
});
};
Edit
Based on your latest comment, let me know if this rewrite works for you... only one biding this time.
element1.customFunction = function() {
handleOnClick(function() {
console.log('element1 onclick fire'); // For example hide a div
});
};
element2.customFunction = function() {
handleOnClick(function() {
console.log('element2 onclick fire'); // For example ajax request
});
};
document.addEventListener('click', function() {
//1. grab the element
//2. check if it has the customFunction defined
//3. if it does, call it, the check will be done inside
};

Categories