Cancel click handler from mousedown handler - javascript

I’m trying to prevent a click handler from firing based on a condition inside the mousdown handler for the same element. Consider this:
var bool = true;
$('button').click(function() {
console.log('clicked');
}).mousedown(function(e) {
bool = !bool;
if ( bool ) {
// temporary prevent the click handler, how?
}
});
Is there a neat way to cross-communicate between handlers? Here is a bin: http://jsbin.com/ipovon/1/edit

This works, although, I'm not sure it's quite the answer you were looking for. It's basically a double click function, if you set bool=false; initially.
var bool = true;
$('button').mousedown(function(e) {
bool = !bool;
if ( bool ) {
$(this).unbind('click');
}
else
{
$(this).click(function(){
console.log('clicked');
});
}
});
Update
Also, you could pull the click function out of the mousedown like this, if you like:
var bool = true;
function buttonClick(){
console.log('clicked');
}
$('button').mousedown(function(e) {
bool = !bool;
if ( bool ) {
$(this).unbind('click');
}
else
{
$(this).click(buttonClick);
}
});

Related

How to remove previously bind event in jquery

On a checkbox change event, one of a javascript bind the toggle action.
Later on(in a different script) I want to change toggle action based on a condition.
Ex.
script 1:
$(document).ready(function () {
var shipFields = $('.address1 input');
$("input[name = 'same_as_bill']").on("change", function (evt) {
toggleFields(shipFields, !$(this).is(":checked"));
});
function toggleFields(fields, show) {
var inputFields = $("li", fields).not(".sameas, .triggerWrap");
inputFields.toggle(show);
}
}
Script 2:
$(document).ready(function () {
$('li.sameas input').click(function (sender) {
var target = $(sender.target);
var selectedCountryValue = $('li.country select', target.closest('fieldset')).val();
// determine data method based on country selected
if (selectedCountryValue === "xxx") {
ShowAddress(true, target);
} else {
ShowAddress(false, target);
}
});
function kleberShowAddress(show, target) {
if (show) {
$('li.address).hide();
} else {
$('li.address).show();
}
}
});
Issue I have here is, my site load the script 1 first and then the script 2. So by the time script 2 performs the action, toggle action is queued and will trigger that after the changes from script 2, that will revert the changes which I want.
Is there a way to remove the action in the queue? or stop happening first request. I do not want to use .unbind() which will stop triggering script 1 function. I just want to stop the action when ever it meets the condition in script 2.
Please note: above functions are trimmed to show less codes.
add var isActive = true; and use it to check in first script.
In script 2, you can call isActive = false any time you want to disable the first script's function or isActive = true for re-enable them.
Your code will look like:
//script1
var isActive = true;
$(document).ready(function() {
var shipFields = $('.address1 input');
$("input[name = 'same_as_bill']").on("change", function(evt) {
if (isActive) {
toggleFields(shipFields, !$(this).is(":checked"));
}
});
function toggleFields(fields, show) {
if (isActive) {
var inputFields = $("li", fields).not(".sameas, .triggerWrap");
inputFields.toggle(show);
}
}
});
//script2
$(document).ready(function() {
isActive = false;
$('li.sameas input').click(function(sender) {
var target = $(sender.target);
var selectedCountryValue = $('li.country select', target.closest('fieldset')).val();
// determine data method based on country selected
if (selectedCountryValue === "xxx") {
ShowAddress(true, target);
} else {
ShowAddress(false, target);
}
});
function kleberShowAddress(show, target) {
if (show) {
$('li.address').hide();
} else {
$('li.address').show();
}
}
});

Adding and removing events in javascript

I require to keep track on what events are on my dom elements and correspondingly add or remove event-listeners.
The way I keep track of the events right now is as follows ,
To add events :
function addListenerIfNone(addTo,eventType, func) {
if(addTo.id){
if (addedListeners[addTo.id+eventType]===eventType)
{
console.warn('event not added');
return;
}//event is alreaday present
addedListeners[addTo.id+eventType]= eventType;
addTo.addEventListener(eventType, func,true);
console.warn('event added');
}
else{
console.warn("Elements needs to have id attribute");
return false;
}
}
To remove added events:
function removeListenerIfPresent(addTo,eventType, func) {
if(addTo.id){
if (addedListeners[addTo.id+eventType]){ //event present
addedListeners[addTo.id+eventType]= null;
addTo.removeEventListener(eventType, func,true);
console.warn("event removed!");
}
else{
console.warn("event not removed!");
return false;
}
}
else{
console.warn("Elements needs to have id attribute");
return false;
}
}
I have a elements where I need to add click event dynamically as mousemoves overs it to different positions
My code(psuedo):
addListenerIfNone(ele,'mousemove',moveAttackFromHex);
var moveAttackFromHex=function(e){
if (e.pageY='someposition')
{
x='some value';
}
else
{
x='some other value';
}
function moveUnitHandler(){
unitObj.moveToAttackUnit(hexMeshObj.selectedUnit,x);
};
removeListenerIfPresent(ele,'click', moveUnitHandler); //this doesn't remove the event ,even tho it is present and I end up having lot of click events
addListenerIfNone(ele,'click', moveUnitHandler);//add new event listener once the previous is removed
}
I can't keep removeEvent after add event as I it would remove the event right away,
I don't want to use jquery as I have not used it for the entire project but as I last resort I may end up using it.
note: the dom element already has a click event referencing another function,if this makes a difference but I think not..
Thanks
Your code like it is would have problems with the javascript hoisting process. You also need to pass to the removeEventListener function the same callback you registered with the addEventListener function and that it doesn't seem to happen in your code since a new instance of an inner function is created every time in pure javascript.
addedListeners = {};
function addListenerIfNone(addTo, eventType, func) {
if(addTo.id) {
if (addedListeners[addTo.id+eventType] === eventType)
{
console.warn('event not added');
return;
}//event is alreaday present
addedListeners[addTo.id+eventType]= eventType;
addTo.addEventListener(eventType, func, true);
console.warn('event added');
}
else{
console.warn("Elements needs to have id attribute");
return false;
}
}
function removeListenerIfPresent(addTo, eventType, func) {
if(addTo.id){
if (addedListeners[addTo.id+eventType]){ //event present
addedListeners[addTo.id+eventType]= null;
addTo.removeEventListener(eventType, func, true);
console.warn("event removed!");
}
else{
console.warn("event not removed!");
return false;
}
}
else{
console.warn("Elements needs to have id attribute");
return false;
}
}
function moveUnitHandler() {
console.log("moveUnitHandler");
};
var moveAttackFromHex = function(e) {
console.log(addedListeners);
if (e.pageY = 'someposition') {
console.log("if");
}
else {
console.log("else");
}
removeListenerIfPresent(ele, 'click', moveUnitHandler);
addListenerIfNone(ele, 'click', moveUnitHandler);
}
var ele = document.getElementById("ele");
addListenerIfNone(ele, 'mousemove', moveAttackFromHex);
Obs: you probably also have a typo in the statement: if (e.pageY = 'someposition'), maybe it should be: if (e.pageY === 'someposition')

Jquery how to turn .off() to .on()

I have Jquery click event and i want to prevent multiple click before executing my function UpdateItemStatus(this.id);, so i have tried below code using on/off event,
$('#tableItems').on('click', 'tr', function (e) {
if ($(e.target).closest("td").hasClass("cssClick")) {
$(this).off(e);
UpdateItemStatus(this.id);
$(this).on(e);
}
});
but how do i turn .on? as it's not working, not able to click again.
How about having a global variable which decides the button click action?
Something like this?
var clickevent = true;
$('#tableItems').on('click', 'tr', function (e) {
if(clickevent){
if ($(e.target).closest("td").hasClass("cssClick")) {
clickevent = false;
UpdateItemStatus(this.id);
clickevent = true;
}
}
});
if UpdateItemStatus function has ajax then i recommend you to put clickevent = true inside success of that ajax
You don't need to use off() for your code. Use return false:
$('#tableItems').on('click', 'tr', function (e) {
if ($(e.target).closest("td").hasClass("cssClick")) {
return false;
} else{
//do stuff here
}
});
I would probably use something like this :
var inputstate = false;
$('#tableItems').on('click', 'tr', function (e) {
if ($(e.target).closest("td").hasClass("cssClick")) {
if(!inputstate){
inputstate = true;
setTimeout((function(element){
return function(){
UpdateItemStatus(element);
inputstate = false;
};
})(this),50);
}
}
});
the setTimeout used to "defer the call" of your UpdateItemStatus function.
Because if this listener is fired, (an other listener cannot be fired at the same time) the value of the boolean will change to the end state before that the next click will be handled
Seems like your UpdateItemStatus() uses some asynchronous call (ajax?), so here's how i would do it:
$('#tableItems').on('click', 'tr', function (e) {
var $td = $(e.target).closest("td");
if ($td.hasClass("cssClick")) {
$td.toggleClass("cssClick");
UpdateItemStatus(this.id).done(function(){
$td.toggleClass("cssClick");
});
}
});
and in UpdateItemStatus:
function UpdateItemStatus(id){
//do stuff
return $.ajax(...);
}

Detect if the mouse is over an element

How do I get a pretty simple true/false-statement if the mouse is over a div event = true else event = false
var test = $("#main-nav").on("mouseenter", function (e) {
e.preventDefault();
console.log(e.preventDefault());
return true;
});
if (test === true) {
//do something
} else {
//something different
}
If I understand your question correctly:
if($("#main-nav").is(":hover")) {
//do something
}else{
//something different
}
In pseudo code:
if the cursor is over #main-nav
do something
if it's not
do something else
If you want test to always be set:
var test = false;
$("#main-nav").on("mouseenter", function(e){
e.preventDefault();
test = true;
}).on("mouseleave", function(e){
e.preventDefault();
test = false;
});
This way,
if(test === true) {
//do something
}else{
//something different
}
will always work.
You can have a boolean (true/false) variable that will constantly update by doing this:
var hovering;
$("#main-nav").mouseenter(function(){
hovering = true;
});
$("#main-nav").mouseleave(function(){
hovering = false;
});
So whenever it is called it will tell you if the mouse is within your div:
if (hovering){
// mouse within div
} else {
// mouse not within div
}
If you necessarily need is as a variable:
var test = false;
$("#main-nav").on("mouseenter", function (e) {
test = true;
});
$("#main-nav").on("mouseout", function (e) {
test = false;
});
//....
if (test === true) {
//do something
} else {
//something different
}

JS: How to detect whether cursor is in textfield

I want to use some letters ( keys ) as shortcut for some actions in javascript. I want to check whether the cursor is focused on any textfield, form input, etc. so that the shortcut action will be canceled when user is typing something in a form or textfield.
For example, i want an alert() to be executed when user presses 'A'. But if the user is typing some text in a textarea like 'A website' then he will be pressing 'A', this time alert() should not be executed.
$(document).keydown( function( e ) {
if( e.target.nodeName == "INPUT" || e.target.nodeName == "TEXTAREA" ) return;
if( e.target.isContentEditable ) return;
// Do stuff
}
window.onkeydown = function(e){
if ( e.target.nodeName == 'INPUT' ) return;
handle_shortcut();
};
jQuery
$(window).bind('keydown',function(e){
if(e.target.nodeName.toLowerCase() === 'input'){
return;
}
alert('a');
});
or pure js
window.onkeydown = function(e){
if(e.target.nodeName.toLowerCase() === 'input'){
return;
}
alert('a');
};
What you can do in addition to this is define an array of non-alert element types, so input, textarea etc and then check none of those elements are currently the target.
Demo: http://jsfiddle.net/7F3JH/
You can bind and unbind the shortcut events depending on which element currently has focus on your page.
JavaScript
window.onload = initWindow();
function initWindow () {
attachShortcutHandler();
var inputs = document.getElementsByTagName('input');
for (var i = 0, max = inputs.length; i < max; i++) {
inputs[i].onfocus = removeShortcutHandler;
intputs[i].onblur = attachShortcutHandler;
}
}
function removeShortcutHandler () {
window.onkeypress = null;
}
function attachShortcutHandler() {
window.onkeypress = function () {
//your code here
}
}
jQuery
$(function () {
initShortcutHandler();
$('input, [any other element you want]')
.on('focus', function () {
$('body').off('keypress');
})
.on('blur', function () {
initShortcutHandler();
});
});
function initShortcutHandler() {
$('body').on('keypress', function () {
//do your stuff
});
}
jQuery mouseover()
$('element').mouseover(function() {
alert('over');
});
you need to make a flag as global. and set it false when any textbox has focus.
var flag = true;
$('input:type="text").focus(function(txt) {
flag= false; });
if(flag) //shortcut keys works...
Better use the focusOut method defined in JQuery. As per my understanding you can do something like this
$("input").focusout(function() {
if($(this).val() == "A"{
alert("your message");
return false;
}else{
//do other processing here.
}
});
Hope this helps :)

Categories