Did conditions with click events work with negative statements? - javascript

I have an eventListener with a click event and want to trigger my function always but with two exceptions. This is my code (that works):
function setCookieTrueOnClick (event) {
if (event.target.pathname === '/info' || event.target.classList.contains('NoTrigger') ) {
} else {
triggerTheFunction('true');
}
}
window.addEventListener("click", setCookieTrueOnClick, false);
The event triggers always but not when the user click the box that has "NoTrigger" class or when the user clicks on a link that goes to /info.
Now, on the other hand, when I use a negative condition the code doesn't work (it triggers the function all the time):
function setCookieTrueOnClick (event) {
if (event.target.pathname !== '/info' || !event.target.classList.contains('NoTrigger') ) {
triggerTheFunction('true');
}
}
window.addEventListener("click", setCookieTrueOnClick, false);
I don't understand why, I also tried setting the eventListener with "true" argument, but it's always the same.

As #Prerak Sola commented, you have reversed the conditional checks but not the condition as a whole.
if(!event.target.pathname === '/info' && !event.target.classList.contains('NoTrigger'))
You will need to also inverse the || into and &&
.Try it out and let us know

Related

react js, trying to remove a nested event listener

I'm trying to create a game and the goal currently is do draw a line (narrow div) from player position to mouse hovering position, so that the line displays the trajectory of ability, like in diablo games or modern moba's, but only when left click is held down.
Currently I listen for mouse down and mouse up and add or remove classes when I need to.
But now I need to make it so that while the left click is pressed, I need to get mousemove coordinates.
My code assigns mouse move listener when the left click is down, but I can't remove the mousemove listener when the left click is up
function detectLeftButton(event) {
if (event.metaKey || event.ctrlKey || event.altKey || event.shiftKey) {
return false;
} else if ('buttons' in event) {
return event.buttons === 1;
} else if ('which' in event) {
return event.which === 1;
} else {
return (event.button === 1 || event.type === 'click');
}
try {
map.addEventListener('mousedown', (event) => {
if (detectLeftButton(event) === true) {
handleMouseDown();
map.onmousemove = handleMouseMove();
map.addEventListener('mouseup', () => {
handleMouseUp();
map.onmousemove = null;
});
}
})
}
catch(err) {
}
Although I'm not 100% sure why setting onmousemove to null doesn't work, I can say that you can use removeEventListener in order to detach an event handler from the event. For this to work, you have to pass a reference to the function you're trying to remove to both addEventListener and removeEventListener. Also, the way you've written the code, you're not clearing your mouseUp event handler, which means it may end up getting invoked more times than you want.
Inside the try/catch block take this for a spin:
map.addEventListener('mousedown', (event) => {
if (detectLeftButton(event) === true) {
handleMouseDown();
map.addEventListener('mousemove', handleMouseMove);
}
})
map.addEventListener('mouseup', (event) => {
handleMouseUp();
map.removeEventListener('mousemove', handleMouseMove);
})
Another option would be to have some kind of state variable that you set in mousedown/mouseup that allows a mouse move handler to determine whether or not to take action. Then you may not need to worry about detaching the event (although I don't know enough about your solution to say for sure). You can find an example of this type of solution on MDN: https://developer.mozilla.org/en-US/docs/Web/API/Element/mousemove_event

How to know if keypress was a real user action [duplicate]

I have a handler attached to an event and I would like it to execute only if it is triggered by a human, and not by a trigger() method. How do I tell the difference?
For example,
$('.checkbox').change(function(e){
if (e.isHuman())
{
alert ('human');
}
});
$('.checkbox').trigger('change'); //doesn't alert
You can check e.originalEvent: if it's defined the click is human:
Look at the fiddle http://jsfiddle.net/Uf8Wv/
$('.checkbox').change(function(e){
if (e.originalEvent !== undefined)
{
alert ('human');
}
});
my example in the fiddle:
<input type='checkbox' id='try' >try
<button id='click'>Click</button>
$("#try").click(function(event) {
if (event.originalEvent === undefined) {
alert('not human')
} else {
alert(' human');
}
});
$('#click').click(function(event) {
$("#try").click();
});
More straight forward than above would be:
$('.checkbox').change(function(e){
if (e.isTrigger)
{
alert ('not a human');
}
});
$('.checkbox').trigger('change'); //doesn't alert
Currently most of browsers support event.isTrusted:
if (e.isTrusted) {
/* The event is trusted: event was generated by a user action */
} else {
/* The event is not trusted */
}
From docs:
The isTrusted read-only property of the Event interface is a Boolean
that is true when the event was generated by a user action, and false
when the event was created or modified by a script or dispatched via
EventTarget.dispatchEvent().
I think that the only way to do this would be to pass in an additional parameter on the trigger call as per the documentation.
$('.checkbox').change(function(e, isTriggered){
if (!isTriggered)
{
alert ('human');
}
});
$('.checkbox').trigger('change', [true]); //doesn't alert
Example: http://jsfiddle.net/wG2KY/
Accepted answer didn't work for me. It's been 6 years and jQuery has changed a lot since then.
For example event.originalEvent returns always true with jQuery 1.9.x. I mean object always exists but content is different.
Those who use newer versions of jQuery can try this one. Works on Chrome, Edge, IE, Opera, FF
if ((event.originalEvent.isTrusted === true && event.originalEvent.isPrimary === undefined) || event.originalEvent.isPrimary === true) {
//Hey hooman it is you
}
Incase you have control of all your code, no alien calls $(input).focus() than setFocus().
Use a global variable is a correct way for me.
var globalIsHuman = true;
$('input').on('focus', function (){
if(globalIsHuman){
console.log('hello human, come and give me a hug');
}else{
console.log('alien, get away, i hate you..');
}
globalIsHuman = true;
});
// alien set focus
function setFocus(){
globalIsHuman = false;
$('input').focus();
}
// human use mouse, finger, foot... whatever to touch the input
If some alien still want to call $(input).focus() from another planet.
Good luck or check other answers
I needed to know if calls to the oninput handler came from the user or from undo/redo since undo/redo leads to input events when the input's value is restored.
valueInput.oninput = (e) => {
const value = +valueInput.value
update(value)
if (!e.inputType.startsWith("history")) {
console.log('came from human')
save(value)
}
else {
console.log('came from history stacks')
}
}
It turns out that e.inputType is "historyUndo" on undo and "historyRedo" on redo (see list of possible inputTypes).
You can use onmousedown to detect mouse click vs trigger() call.
I would think about a possibility where you check the mouse position, like:
Click
Get mouse position
Overlaps the coords of the button
...

how to add dbclick() on right click in jquery

Hi I want to have a dblclick() on the right click as the google maps have to zoom in and zoom out. Is there any way to do that. I have written the dblclick but now its working with only left click. Any pointers on how to do this. Here is my code
$("div#demo1").dblclick(function(e) {
//alert(e.getElementById());
if( (!$.browser.msie && e.button == 0) || ($.browser.msie && e.button == 1) ) {
alert("Left Mouse Button was clicked on demo1 div!");
$("div.window").animate({
'height':'+=20', 'width':'+=20'
},0,function(){
jsPlumb.repaintEverything();
jsPlumb.repaintEverything();
});
// Left mouse button was clicked (all browsers)
}
else if( (!$.browser.msie && e.button == 2) || ($.browser.msie && e.button == 3) ) {
alert("right click double");
}
});
There is another way you could detect a double right-click that does not involve fiddling with timers or keeping track of click counts manually. Using the .detail property of the event object in a mouseup or mousedown event. .detail holds the click count which will tell you how many clicks have happened recently. If .detail === 2 it was a double-click.
// suppress the right-click menu
$('#target').on('contextmenu', function (evt) {
evt.preventDefault();
});
$('#target').mouseup(function (evt) {
if (evt.which === 3) { // right-click
/* if you wanted to be less strict about what
counts as a double click you could use
evt.originalEvent.detail > 1 instead */
if (evt.originalEvent.detail === 2) {
$(this).text('Double right-click');
} else if (evt.originalEvent.detail === 1) {
$(this).text('Single right-click');
}
}
});
You might notice that I am using evt.originalEvent.detail to access the property instead of just .detail. This is because jQuery provides it's own version of the event object which does not include .detail, but you can access the original event object that the browser returned via .originalEvent. If you were using pure JavaScript instead of jQuery you would just use evt.detail.
Here's a working example.
There is no real way to do it, you can emulate it by taking the default timer for double clicks which IIRC is 300ms:
function makeDoubleRightClickHandler( handler ) {
var timeout = 0, clicked = false;
return function(e) {
e.preventDefault();
if( clicked ) {
clearTimeout(timeout);
clicked = false;
return handler.apply( this, arguments );
}
else {
clicked = true;
timeout = setTimeout( function() {
clicked = false;
}, 300 );
}
};
}
$(document).contextmenu( makeDoubleRightClickHandler( function(e) {
console.log("double right click" );
}));
http://jsfiddle.net/5kvFG/2/
Because the right-click has meaning to the user agent that is outside the purview of javascript (the context menu), you're going to have to do some dancing around.
First, you should disable the context menu on the target element:
document.getElementById('demo1').oncontextmenu = function() {
return false;
};
Now, when we right click, there won't be the context menu messing up the second click.
Next, understand that "double-click right" does not, generally speaking, exist. Even though you can bind the dblclick event, that isn't a generic event. "Double-click" is, by definition, double-clicking with the left mouse button.
So, we'll have to use the mousedown event, check to see how many times the right has been clicked, and react after two. I created a small helper function that keeps track of the click count and resets the state after a short time-frame.
var RightClick = {
'sensitivity':350,
'count':0,
'timer':false,
'active':function () {
this.count++;
this.timer = setTimeout(
this.endCountdown.bind(this),
this.sensitivity
);
},
'endCountdown': function () {
this.count = 0;
this.timer = false;
}
};
$("div#demo1").mousedown(function(e) {
if(e.which == 3) {
RightClick.active();
if (RightClick.count == 2)
alert("right click double");
}
});
Try it here: http://jsfiddle.net/94L7z/
You can adjust the sensitivity rate, allowing for shorter or longer double-clicks, depending on your preference.
Documentation
element.onContextMenu on MDN - https://developer.mozilla.org/en-US/docs/DOM/window.oncontextmenu
element.onMouseDown on MDN - https://developer.mozilla.org/en-US/docs/DOM/element.onmousedown
window.setTimeout on MDN - https://developer.mozilla.org/en-US/docs/DOM/window.setTimeout
jQuery event.which - http://api.jquery.com/event.which/
"Javascript Madness: Mouse Events" on UnixPapa.com, an article showing some tests related to mouse events and the left/right buttons - http://unixpapa.com/js/mouse.html
The problem is the concept of double clicking is only relevant to the left mouse button as far as JS is concerned. So no matter how many time, and how fast you click the right mouse button, it just registers as a bunch of single clicks. So what to do?
Create a global variable to track click count
detect a single right-click, you already know how to do this it seems
set the global variable that the right-click was fired once
set a timeout, so if another right click doesn't come through in a
reasonable time to be considered a dblclick the global variable
resets to 0. I recommend 300 ms, it seems to be the most natural
each time a right-click registers check that variable, if it's more
than one, fire your double-right-click handler.
you may want to make that global variable an object so you can track which element
registered the right click and expire specific element right clicks
accordingly. This will allow you to ignore if they double click
while moving the mouse over various objects. I consider this
optional as the chain of events are unlikely for a user to follow,
but depending on your app may result in unexpected functionality.
It might be better to define a jQuery function with this (try it):
var precision = 400;
var lastClickTime = 0;
$(document).ready(function()
{
var div = $('#div');
$(div).bind("contextmenu", function(e)
{
return false;
});
$(div).mousedown(function(event)
{
if (event.which == 3)
{
var time = new Date().getTime();
if(time - lastClickTime <= precision)
{
// DOUBLE RIGHT CLICK
alert('double click');
}
lastClickTime = time;
}
});
});

only writing "return false" once to handle clicking on many links

Instead of writing return false; many times is there a way to set a collection of links such that if any of them are clicked the click function would return false;? I'd still like to have most links return true so showing code that would return true vs. return false would be particularly appreciated.
The goal is writing less code. I'd also like to know if this is a bad idea for reason I can't understand.
The simpliest method is binding one event listener to the document, and checking for the target: http://jsfiddle.net/gKZ7q/
document.addEventListener('click', function(e) {
if (e.target.nodeName.toUpperCase() === 'A') e.preventDefault();
}, false);
For anchors with nested elements, you have to add an additional loop:
var targ = e.target;
do {
if (targ.nodeName.toUpperCase() === 'A') {
e.preventDefault();
break;
}
} while ((targ = targ.parentNode) !== document.documentElement);
// document.body should be fine. Using document.documentElement in case
// that a fool places an anchor outside the <body>
Links can also be triggered through a key event.

calling javascript method on onclick and onkeypress events

I have a search box and search button. I want to call a javascript method in case somebody types in search box and hits enter or clicks on search button.
So far with keypress event it's working fine:
function Search(e) {
if(e.keyCode==13) {
//DO operation
}
}
If I want to call same function on onclick event of search button, how can I use same method shown above. Only purpose here is not to duplicate same code by writing two different methods which at the end do same thing.
Add listeners to both events (onclick and onkeypress) and use event's type:
function Search(e) {
if( e.type == 'click' ||
(e.type=='keypress' && e.keyCode==13) ){
//DO operation
}
}
Demo here.
function Search(e) {
var doOper = function() {
//DO operation
}
if(e.keyCode==13) {
doOper();
}
if(buttonClicked) {
doOper();
}
}

Categories