I want to destroy the session on tab close using jquery and java script.
In this I am able to track the keyboard event like F5 or ctrl+r. But I am facing issues in tracking browser back, forward, refresh and tab close buttons.I know that on all the above mention button, same function is called that is window.onbeforeunload.
Here is my code..
function endSession() {
console.log(validNavigation);
alert("You are about to close your page and session");
$.ajax({
type: "POST",
url: base_url+"destroy-session",
beforeSend : function(){
console.log('hjkl');
},
success: function(response){
console.log(response);
},
error: function(response){
console.log(response);
}
});
}
function wireUpEvents() {
window.onbeforeunload = function() {
if (validNavigation == false) {
endSession();
}
}
//window.onbeforeunload=goodbye
// Attach the event keypress to exclude the F5 refresh
$(document).bind('keypress keydown keyup', function(e) {
if(e.keyCode === 116 || e.keyCode==8 || e.keyCode==13) {
validNavigation = true;
}
if(e.ctrlKey && e.keyCode==82) {
validNavigation = true;
}
if(e.ctrlKey && e.keyCode==76) {
validNavigation = true;
}
});
// Attach the event click for all links in the page
$("a").bind("click", function() {
validNavigation = true;
});
// Attach the event submit for all forms in the page
$("form").bind("submit", function() {
validNavigation = true;
});
$("input[type=button]").bind("click", function () {
validNavigation = true;
});
// Attach the event click for all inputs in the page
$("input[type=submit]").bind("click", function() {
validNavigation = true;
});
}
// Wire up the events as soon as the DOM tree is ready
$(document).ready(function() {
wireUpEvents();
});
I'm trying to prevent a link click from firing if accidentally touched while scrolling in mobile? I have never tried something like this before and am having trouble getting it to work right. I am testing this on a desktop for the time being.
My buttons are structured similar to:
<a href="http://www.google.com">
<div style="width:100%;height:80px;margin-bottom:50px;">test</div>
</a>
I am trying to use the preventDefault() function to override default click actions and check if a the page is being scrolled, or it the click was accidental before allowing it to work. The logic to check seems to work, however the links navigate on click no matter what i do. I assume this has something to do with the links behaviour being propogated to the child div, but am not sure.
Below is my script, the problem is in the last $('a').click(); function.
UPDATE:
I still need a better way to do it using just the $('a') selector if anyone knows how. Kind of a hack but, if i change the selector to $('a>div') and change the 'targetLink' to $(this).parent().attr('href') it seems to work, Is there a way to do this using $('a') only because some of my buttons have more children.
//Mobile accidental scroll click fix:---
//- prevent clicked link from executing if user scrolls after mousedown, until next mousedown.
//- prevent clicked link from executing if user is still scrolling and mouse is down(for slow scrolls)
$(document).ready(function(){
var self = this,
scrolling = false,
mouseDown = false,
scrollAfterPress = false;
scrollDelay = 1500,
linkConditionCheckDelay = 700;
$(window).scroll(function() {
self.scrolling = true;
console.log('scrolling:' + self.scrolling);
clearTimeout( $.data( this, "scrollCheck" ) );
$.data( this, "scrollCheck", setTimeout(function() {
self.scrolling = false;
console.log('scrolling:' + self.scrolling);
}, scrollDelay) );
});
$(document).mousedown(function(){
self.scrollAfterPress = false;
int00 = setInterval(function() { checkScrollAfterPress(); }, 100);//execute every 100ms (while mouse is down)
self.mouseDown = true;
console.log('mousedown:'+ self.mouseDown);
}).mouseup(function(){
clearInterval(int00);
self.mouseDown = false;
console.log('mousedown:'+ self.mouseDown);
});
function checkScrollAfterPress(){
if(self.scroll === true){
self.scrollAfterPress = true;
}
}
$('a').click(function(e){
//prevent default click event behaviour
var targetLink = $(this).attr('href');
console.log('clicked on:'+targetLink);
setTimeout(function() {
if(!self.scrolling && !self.mouseDown && !self.scrollAfterPress && targetLink !== undefined){
window.location.href = targetLink;
}
}, linkConditionCheckDelay); //add small delay to prevent immeditiate responses between mouse up and start of scroll.
e.stopPropagation();
e.preventDefault();
});
});
You can use return false or e.preventDefault
But when you click on that link why your adding window.location.href = targetLink;?? which will redirect the user to the given location.Same as link
Try my code below i have removed it.
$(document).ready(function(){
var self = this,
scrolling = false,
mouseDown = false,
scrollAfterPress = false;
scrollDelay = 1500,
linkConditionCheckDelay = 700;
$(window).scroll(function() {
self.scrolling = true;
console.log('scrolling:' + self.scrolling);
clearTimeout( $.data( this, "scrollCheck" ) );
$.data( this, "scrollCheck", setTimeout(function() {
self.scrolling = false;
console.log('scrolling:' + self.scrolling);
}, scrollDelay) );
});
$(document).mousedown(function(){
self.scrollAfterPress = false;
int00 = setInterval(function() { checkScrollAfterPress(); }, 100);//execute every 100ms (while mouse is down)
self.mouseDown = true;
console.log('mousedown:'+ self.mouseDown);
}).mouseup(function(){
clearInterval(int00);
self.mouseDown = false;
console.log('mousedown:'+ self.mouseDown);
});
function checkScrollAfterPress(){
if(self.scroll === true){
self.scrollAfterPress = true;
}
}
$('a').click(function(e){
//prevent default click event behaviour
var targetLink = $(this).attr('href');
console.log('clicked on:'+targetLink);
setTimeout(function() {
if(!self.scrolling && !self.mouseDown && !self.scrollAfterPress && targetLink !== undefined){
//window.location.href = targetLink;
}
}, linkConditionCheckDelay); //add small delay to prevent immeditiate responses between mouse up and start of scroll.
return false;
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a href="http://www.google.com">
<div style="width:100%;height:80px;margin-bottom:50px;">test</div>
</a>
I will suggest another approach and use jQuery Mobile Events. Something like this:
*untested, but is the idea
// set global var 'locked'
var locked = false;
// locked var true while scrolling
jQuery(document).on('scrollstart', function() { locked = true; });
// locked var back to false when finish
jQuery(document).on('scrollstop', function() { locked = false; });
// bind 'tap' & 'click' events to 'a' tag
jQuery(document).on('tap click', 'a', function(event) {
// But before proceed, check locked var
if (locked) {
event.preventDefault;
return false;
} else {
// ok, proceed with the click and further events...
}
});
Docs/ref:
scrollstart event
scrollstop event
tap event
vclick event
.click()
Use in your $'a'.click(function(e){...} part return false; to prevent the default behavior.
In your case:
$('a').click(function(e){
var targetLink = $(this).attr('href');
console.log('clicked on:'+targetLink);
setTimeout(function() {
if(!self.scrolling && !self.mouseDown && !self.scrollAfterPress && targetLink !== undefined){
window.location.href = targetLink;
}
}, linkConditionCheckDelay);
return false;//Stops default behavior
});
Perhaps there is something I am missing, but I do not see why your code cannot be made as simple as the following:
$(document).ready(function () {
var is_scrolling = false;
var timeout = null;
$(window).scroll(function () {
is_scrolling = true;
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(function () {
is_scrolling = false;
}, 1500);
});
$('a').click(function (e){
if (is_scrolling) {
e.preventDefault();
}
});
});
I added a redirect function when refresh button or user try to exit the page they get redirected but what I want to happen is this function to be unload or not executed when they click my button
<a onClick="alert(you are going to tweeter);"href="http://twitter.com" class="tweetbutton" >I Like Twitter</a>
so what happens is it conflicts and two alerts shows up, what I was needing is when the tweetbutton button is click the onclick alert will the one to appear then get redirected to twitter.com without the function below being executed
(function() {
setTimeout(function() {
var __redirect_to = 'http://facebook.com';
var _tags = ['btn', 'input'],
_go, _i, _i2;
for (_i in _tags) {
_els = document.getElementsByTagName(_tags[_i]);
for (_i2 in _go) {
if ((_tags[_i] == 'input' && _go[_i2].type != 'btn' && _go[_i2].type != 'submit' && _go[_i2].type != 'image') || _go[_i2].target == '_blank') continue;
_els[_i2].onclick = function() {
window.onbeforeunload = function() {};
}
}
}
window.onbeforeunload = function() {
setTimeout(function() {
window.onbeforeunload = function() {};
setTimeout(function() {
document.location.href = __redirect_to;
});
});
return 'you are leaving this page'
}
});
});
Update you code as follows:
<a "href="http://twitter.com" class="tweetbutton" >I Like Twitter</a>
Add this to your js
document.addEventListener('click', function (e) {
if (e.target.className == 'tweetbutton') alert('you are going to twitter');
});
Hey guys i was just going through the carasoul.js code and came across the following lines of code :
if (slideEvent.isDefaultPrevented()) return
now the documentation of isDefaultPrevented() gives the foolowing example :
$( "a" ).click(function( event ) {
alert( event.isDefaultPrevented() ); // false
event.preventDefault();
alert( event.isDefaultPrevented() ); // true
});
but i am not attaching a click event so how is isDefaultPrevented of any assists here ? , the entire function code can be seen below ::
Carousel.prototype.slide = function (type, next) {
var $active = this.$element.find('.item.active')
var $next = next || this.getItemForDirection(type, $active)
var isCycling = this.interval
var direction = type == 'next' ? 'left' : 'right'
var that = this
if ($next.hasClass('active')) return (this.sliding = false)
var relatedTarget = $next[0]
var slideEvent = $.Event('slide.bs.carousel', {
relatedTarget: relatedTarget,
direction: direction
})
this.$element.trigger(slideEvent)
if (slideEvent.isDefaultPrevented()) return
this.sliding = true
isCycling && this.pause()
if (this.$indicators.length) {
this.$indicators.find('.active').removeClass('active')
var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
$nextIndicator && $nextIndicator.addClass('active')
}
var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
if ($.support.transition && this.$element.hasClass('slide')) {
$next.addClass(type)
$next[0].offsetWidth // force reflow
$active.addClass(direction)
$next.addClass(direction)
$active
.one('bsTransitionEnd', function () {
$next.removeClass([type, direction].join(' ')).addClass('active')
$active.removeClass(['active', direction].join(' '))
that.sliding = false
setTimeout(function () {
that.$element.trigger(slidEvent)
}, 0)
})
.emulateTransitionEnd(Carousel.TRANSITION_DURATION)
} else {
$active.removeClass('active')
$next.addClass('active')
this.sliding = false
this.$element.trigger(slidEvent)
}
isCycling && this.cycle()
return this
}
Why the use of isDefaultPrevented() ?
The Bootstrap carousel triggers events at interesting moments, for example before and after it slides. If you want to do something when these events happen, you can react to them like so:
$('.carousel').on('slide.bs.carousel', function (e) {
// do something before a carousel slides
});
And if you want to prevent the carousel from it's default behaviour, you can do that like so:
$('.carousel').on('slide.bs.carousel', function (e) {
// prevent the carousel from sliding
e.preventDefault();
});
Bootstrap then checks if an event handler called preventDefault() and stops its default behaviour if it happened:
if (slideEvent.isDefaultPrevented()) return
Is there something in jquery that would allow me to differentiate between behavior on double click and single click?
When I bind both to same element only the single click gets executed.
Is there a way that wait for some time before execution of the single click to see if the user clicks again or not?
Thanks :)
I found that John Strickler's answer did not quite do what I was expecting. Once the alert is triggered by a second click within the two-second window, every subsequent click triggers another alert until you wait two seconds before clicking again. So with John's code, a triple click acts as two double clicks where I would expect it to act like a double click followed by a single click.
I have reworked his solution to function in this way and to flow in a way my mind can better comprehend. I dropped the delay down from 2000 to 700 to better simulate what I would feel to be a normal sensitivity. Here's the fiddle: http://jsfiddle.net/KpCwN/4/.
Thanks for the foundation, John. I hope this alternate version is useful to others.
var DELAY = 700, clicks = 0, timer = null;
$(function(){
$("a").on("click", function(e){
clicks++; //count clicks
if(clicks === 1) {
timer = setTimeout(function() {
alert("Single Click"); //perform single-click action
clicks = 0; //after action performed, reset counter
}, DELAY);
} else {
clearTimeout(timer); //prevent single-click action
alert("Double Click"); //perform double-click action
clicks = 0; //after action performed, reset counter
}
})
.on("dblclick", function(e){
e.preventDefault(); //cancel system double-click event
});
});
The solution given from "Nott Responding" seems to fire both events, click and dblclick when doubleclicked. However I think it points in the right direction.
I did a small change, this is the result :
$("#clickMe").click(function (e) {
var $this = $(this);
if ($this.hasClass('clicked')){
$this.removeClass('clicked');
alert("Double click");
//here is your code for double click
}else{
$this.addClass('clicked');
setTimeout(function() {
if ($this.hasClass('clicked')){
$this.removeClass('clicked');
alert("Just one click!");
//your code for single click
}
}, 500);
}
});
Try it
http://jsfiddle.net/calterras/xmmo3esg/
Sure, bind two handlers, one to click and the other to dblclick. Create a variable that increments on every click. then resets after a set delay. Inside the setTimeout function you can do something...
var DELAY = 2000,
clicks = 0,
timer = null;
$('a').bind({
click: function(e) {
clearTimeout(timer);
timer = setTimeout(function() {
clicks = 0;
}, DELAY);
if(clicks === 1) {
alert(clicks);
//do something here
clicks = 0;
}
//Increment clicks
clicks++;
},
dblclick: function(e) {
e.preventDefault(); //don't do anything
}
});
You could probably write your own custom implementation of click/dblclick to have it wait for an extra click. I don't see anything in the core jQuery functions that would help you achieve this.
Quote from .dblclick() at the jQuery site
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.
Look at the following code
$("#clickMe").click(function (e) {
var $this = $(this);
if ($this.hasClass('clicked')){
alert("Double click");
//here is your code for double click
return;
}else{
$this.addClass('clicked');
//your code for single click
setTimeout(function() {
$this.removeClass('clicked'); },500);
}//end of else
});
Demo goes here http://jsfiddle.net/cB484/
I've written a jQuery plugin that allow also to delegate the click and dblclick events
// jQuery plugin to bind both single and double click to objects
// parameter 'delegateSelector' is optional and allow to delegate the events
// parameter 'dblclickWait' is optional default is 300
(function($) {
$.fn.multipleClicks = function(delegateSelector, clickFun, dblclickFun, dblclickWait) {
var obj;
if (typeof(delegateSelector)==='function' && typeof(clickFun)==='function') {
dblclickWait = dblclickFun; dblclickFun = clickFun; clickFun = delegateSelector; delegateSelector = null; // If 'delegateSelector' is missing reorder arguments
} else if (!(typeof(delegateSelector)==='string' && typeof(clickFun)==='function' && typeof(dblclickFun)==='function')) {
return false;
}
return $(this).each(function() {
$(this).on('click', delegateSelector, function(event) {
var self = this;
clicks = ($(self).data('clicks') || 0)+1;
$(self).data('clicks', clicks);
if (clicks == 1) {
setTimeout(function(){
if ($(self).data('clicks') == 1) {
clickFun.call(self, event); // Single click action
} else {
dblclickFun.call(self, event); // Double click action
}
$(self).data('clicks', 0);
}, dblclickWait || 300);
}
});
});
};
})(jQuery);
This solution works for me
var DELAY = 250, clicks = 0, timer = null;
$(".fc-event").click(function(e) {
if (timer == null) {
timer = setTimeout(function() {
clicks = 0;
timer = null;
// single click code
}, DELAY);
}
if(clicks === 1) {
clearTimeout(timer);
timer = null;
clicks = -1;
// double click code
}
clicks++;
});
i am implementing this simple solution , http://jsfiddle.net/533135/VHkLR/5/
html code
<p>Click on this paragraph.</p>
<b> </b>
script code
var dbclick=false;
$("p").click(function(){
setTimeout(function(){
if(dbclick ==false){
$("b").html("clicked")
}
},200)
}).dblclick(function(){
dbclick = true
$("b").html("dbclicked")
setTimeout(function(){
dbclick = false
},300)
});
its not much laggy
var singleClickTimer = 0; //define a var to hold timer event in parent scope
jqueryElem.click(function(e){ //using jquery click handler
if (e.detail == 1) { //ensure this is the first click
singleClickTimer = setTimeout(function(){ //create a timer
alert('single'); //run your single click code
},250); //250 or 1/4th second is about right
}
});
jqueryElem.dblclick(function(e){ //using jquery dblclick handler
clearTimeout(singleClickTimer); //cancel the single click
alert('double'); //run your double click code
});
I made some changes to the above answers here which still works great: http://jsfiddle.net/arondraper/R8cDR/
Below is my simple approach to the issue.
JQuery function:
jQuery.fn.trackClicks = function () {
if ($(this).attr("data-clicks") === undefined) $(this).attr("data-clicks", 0);
var timer;
$(this).click(function () {
$(this).attr("data-clicks", parseInt($(this).attr("data-clicks")) + 1);
if (timer) clearTimeout(timer);
var item = $(this);
timer = setTimeout(function() {
item.attr("data-clicks", 0);
}, 1000);
});
}
Implementation:
$(function () {
$("a").trackClicks();
$("a").click(function () {
if ($(this).attr("data-clicks") === "2") {
// Double clicked
}
});
});
Inspect the clicked element in Firefox/Chrome to see data-clicks go up and down as you click, adjust time (1000) to suit.
(function($){
$.click2 = function (elm, o){
this.ao = o;
var DELAY = 700, clicks = 0;
var timer = null;
var self = this;
$(elm).on('click', function(e){
clicks++;
if(clicks === 1){
timer = setTimeout(function(){
self.ao.click(e);
}, DELAY);
} else {
clearTimeout(timer);
self.ao.dblclick(e);
}
}).on('dblclick', function(e){
e.preventDefault();
});
};
$.click2.defaults = { click: function(e){}, dblclick: function(e){} };
$.fn.click2 = function(o){
o = $.extend({},$.click2.defaults, o);
this.each(function(){ new $.click2(this, o); });
return this;
};
})(jQuery);
And finally we use as.
$("a").click2({
click : function(e){
var cid = $(this).data('cid');
console.log("Click : "+cid);
},
dblclick : function(e){
var cid = $(this).data('cid');
console.log("Double Click : "+cid);
}
});
Same as the above answer but allows for triple click. (Delay 500)
http://jsfiddle.net/luenwarneke/rV78Y/1/
var DELAY = 500,
clicks = 0,
timer = null;
$(document).ready(function() {
$("a")
.on("click", function(e){
clicks++; //count clicks
timer = setTimeout(function() {
if(clicks === 1) {
alert('Single Click'); //perform single-click action
} else if(clicks === 2) {
alert('Double Click'); //perform single-click action
} else if(clicks >= 3) {
alert('Triple Click'); //perform Triple-click action
}
clearTimeout(timer);
clicks = 0; //after action performed, reset counter
}, DELAY);
})
.on("dblclick", function(e){
e.preventDefault(); //cancel system double-click event
});
});
This is a method you can do using the basic JavaScript, which is works for me:
var v_Result;
function OneClick() {
v_Result = false;
window.setTimeout(OneClick_Nei, 500)
function OneClick_Nei() {
if (v_Result != false) return;
alert("single click");
}
}
function TwoClick() {
v_Result = true;
alert("double click");
}
If you don't want to create separate variables to manage the state, you can check this answer https://stackoverflow.com/a/65620562/4437468