Stopping click event using mousedown only works when triggering an alert - javascript

I'm trying to prevent the defined onclick events of the children of an element being run by returning false from the mousedown event on the container like so:
submit_container.mousedown(function(event){
return false;
});
If I write my code like this, it doesn't work. However, if I add an alert first, the click events are in fact stopped:
submit_container.mousedown(function(event){
alert('Alert');
return false;
});
The same issue was alluded to here, but sadly none of the answers address this.
EDIT: JSfiddle example. I want the behaviour of the second link, but without having to trigger an alert

The mousedown is working for the container class . Your problem is that a href has a click event attached to it not mouse down. So you should be using onclick on the container or the href as event Propagation will occur and bubble up to the parent . You can still stop this from happening .
Example.
submit_container.click(function(event){
event.stopPropagation();
event.preventDefault();
return false;
});
Hope this helps

Are you using jQuery? Try with a "preventDefault" method:
submit_container.mousedown(function(event){
event.preventDefault();
return false;
});

Related

Stop propagation doesn't work

I have the below JQuery eventhandler. I want to stop all navigations on a web page.
$(document).click(function(event) {
event.stopPropagation();
event.preventDefault();
event.cancelBubble = true;
event.stopImmediatePropagation();
$(document).css('border-color','');
$(document).css('background-color','');
$(event.target).css('border-color','yellow');
$(event.target).css('background-color','#6BFF70');
return false;
});
When I use this on Facebook Login page, it stops all navigations. But in Google home page, "I'm Feeling Lucky" button still navigates to next page. How do I avoid it?
I'm using JavaFX browser by the way. It is similar to Safari browser.
If I load the Google search page, and execute this at the console:
document.body.addEventListener(
"click",
function (ev) { ev.stopPropagation(); ev.preventDefault(); },
true);
then I cannot click the "I'm Feeling Lucky" button anymore. The key is to use the third parameter and set it to true. Here is what MDN [says] about it:
useCapture Optional
If true, useCapture indicates that the user wishes to initiate capture. After initiating capture, all events of the specified type will be dispatched to the registered listener before being dispatched to any EventTarget beneath it in the DOM tree.
(Emphasis added.)
What you tried to do does not work because your event handler is on document, and thus will be called after any event handlers on the children of the document. So your handler cannot prevent anything.
With useCapture set to true, you can operate on the event before it gets a chance to be passed to the child element. I do not know of a way to have jQuery's event handlers work in the way you get with useCapture. Barmar's answer here says you can't use jQuery to set such handler. I'm inclined to believe him.
99.99% of webpages won't be able to have their navigation stopped by stopping event propagation for the reason I commented (you can't stop the event before it triggers all handlers for the initial target of the event). If preventing navigation is all you are interested in, I recommend using the window.onbeforeunload event, which is made for this exact situation.
Here is an example: http://jsfiddle.net/ejreseuu/
HTML:
google
JS:
window.onbeforeunload = function() {
return "Are you sure?"
}
There is no way to not have a confirmation box that I know of, as code that locks the user out of navigating away no matter what they do is generally malicious.
preventDefault() should not work in this case, cause Google relied on custom event listeners to handle click events on this button. While preventDefault()
prevents browser's default behavior.
For example, if this button was of type="submit", preventing default on click event would prevent browser's default behavior, which is submitting a form. But in this case click is handled by eventListeners added to the button itself. preventDefault() won't affect catching an event by them. Nor stopPropagation(), because it stops propagation of event to higher levels of DOM, while other eventListeners on the same level (button in our case) still get the event. stopImmediatePropagation() could work in theory, but only if your eventListener was added before google's.
So the easiest way to stop propagation is to stop an event before it reaches button node, and that's on capture phase, because button is the lowest element in the hierarchy. This can be done by passing true argument while adding eventListener
document.body.addEventListener("click", function (event) {
event.stopPropagation();
}, true);
This way event will be stopped before bubble phase, and so before it reaches eventListeners added to the button. More on capture and bubble phases here
Note that preventDefault() is not needed in this case. Actually, this button's event listeners are to prevent default themselves. Here are those eventListeners, for click and keyup respectively:
d = function(a) {
c.Xa.search(c.yc(), b);
return s_1vb(a)
}
function(a) {
13 != a.keyCode && 32 != a.keyCode || d(a)
}
note call to s_1vb, here is its sourse:
s_1vb.toString();
/*"function (a){
a&&(a.preventDefault&&a.preventDefault(),a.returnValue=!1);
return!1
}"*/
Basically its a function that take an event and do everything possible to prevent browser's default behavior
By the way, default behavior can be canceled on any stage of event flow (se Events Specification), including the very last stage, when it reached document. Only after it passed "through" all eventListeners uncanceled, browser should execute its default behavior. So attaching your listener to document was not the reason preventDefault() didn't work, it was because it was the wrong guy for the job :)
Try this:
$('body').click(function(event) {
event.stopPropagation();
event.preventDefault();
event.cancelBubble = true;
event.stopImmediatePropagation();
$(document).css('border-color','');
$(document).css('background-color','');
$(event.target).css('border-color','yellow');
$(event.target).css('background-color','#6BFF70');
return false;
});
Try to bind not only to click event, but as well on mousedown event.
Try this css:
body * {
pointer-events: none;
}
or in jQuery:
$("body *").css("pointer-events", "none");
Try declaring a new window event and then stopping the propagation from there:
var e = window.event;
e.cancelBubble = true;
if (e.stopPropagation)
{
e.stopPropagation();
}
Note that Google uses jsaction="..." instead of onclick="...". Try to use it's unbind method on the specified button.
Also you can use dynamic attachment, like:
$(document).on('click', '*', function
Or throw new Error()(just as a dirty hack)

How to prevent redirection when drag an anchor bound ‘mousedowd, mousemove, mouseup’?

I'm trying to implement a draggable image.
BUT <img> is wrapped by <a>
<a href="http://somewhere.com">
<img src="someone.png"/>
</a>
I bind 'mousedown, mousemove, mouseup' on the anchor to implement draggale.
But when 'mouseup', it will redirect.
How to prevent redirection if it was dragged?
P.S. I tried to add event.preventDefault() into mouseup handler, but it doesn't work.
CODE IN DETAIL:
$('.item').on('mousedown', function (e) {
// if not using preventDefault(), image won't move when 'mousemove'
e.preventDefault();
$('.item').on('mousedown', function (e) {
// update 'left' and 'top'
});
});
$('.item').on('mouseup', function () {
// still redirect !?!?
return false
});
preventDefault prevents the default event for a mouseup on the dragable image, but the event is then propagated to the enclosing <a> tag which has its own default behavior. You'll need to stop event propagation so that the event isn't sent to the link in case of a drag/drop. EDIT: as mentioned by TrueBlueAussie in the comments, it's the click event that triggers the link. That's the event which must be blocked from reaching the link.
event.stopPropagation();
https://developer.mozilla.org/en-US/docs/Web/API/Event/stopPropagation
Interesting question as I've never seen this in the MouseUp Event. What I'd do is just
return false;
from your mouseup handler, like this:
$("#anchor").on("click",function(){
//do some mouseup stuff
console.log("Doing mouseup stuff");
return false;
});
Here is a Fiddle:
https://jsfiddle.net/59ddut6s/3/
I think the event.stopPropagation(); mentioned by Jacque could be a better solution, but it's definitely not what I would typically think to do myself.
UPDATE: Minor change based on comments. Some useful info down there worth reading. I didn't consider that this method would case both event.stopPropogation() and event.preventDefault() but it makes sense that it would.
What still confuses me is WHY would on("click") prevent the link from navigating, but not on("mouseup")?

Prevent child's onclick after mouseup on parent?

I have a parent element with mouse up and mouse down events attached on it, and a child element with a click event attached.
Is there any way to prevent the click event from happening in the child, after the mouseup event has been triggered in the parent?
An example, on the JSfiddle here, the goal is to make the inner square not turn to green if I click on it.
Ideally I would like to do it without modifying the $('#inner').on('click', function(){}). I already know that I can set a boolean on mouseup and check it on click but i'm trying to find a way to do it without modifying the click event.
Using jquery(or any other library) is option and I don't really have any restrictions other than not modifying the click method.
EDIT
Thanks #adeneo for the suggestion, that looks promising but it made me realize I missed a big part of the problem. Inside mouseup there will be a conditional check to see if the click should be prevented or not. If I remove the event can I somehow add it back after the click has been avoided? In a setTimeout for example. I'm not sure how(or if it's possible) to get the reference to the removed click function and then re-add the handler.
Hopefully this new fiddle here helps me to explain it a little bit better!
$('#inner').on('mouseup', function(e) {
$(this).unbind("click");
$(this).css({'background': 'black'});
});
Did you try like this?
Try e.stopImmediatePropagation(); in your inner code.
Just replace your code with the below code and check. To stop the click event of the inner div you can use preventDefault() or stopPropagation(). Please check below
$('#inner').on('click', function(e) {
$(this).stopPropagation();
// or
// $(this).preventDefault();
alert('inner click');
});
$('#outer').on('mousedown', function(e) {
$(this).css({'background': 'green'});
});
$('#outer').on('mouseup', function(e) {
$(this).css({'background': 'yellow'});
});
I'm pretty sure that this is the answer you're looking for :
$($(this)).children().click(function (event) { // Preveu la propagació del click als fills
// event.stopPropagation();
});

preventDefault() doesn't prevent the action

When I use event.preventDefault() on a link it works, however when I use it on a button doesn't!
DEMO
My code:
<a id="link" href="http://www.google.com">link</a>
<button id="button" onclick="alert('an alert')">button</button>​
$('#link').click(function(event){
event.preventDefault();
});
$('#button').click(function(event){
event.preventDefault();
});
​
Link action is cancelled, but when I click on the button, still executes the onClick action.
Any help? what I want to do is to prevent the button onClick action without changing the button html (I know how to do
$('#button').removeAttr('onclick');
You want event.stopImmediatePropagation(); if there are multiple event handlers on an element and you want to prevent the others to execute. preventDefault() just blocks the default action (such as submitting a form or navigating to another URL) while stopImmediatePropagation() prevents the event from bubbling up the DOM tree and prevents any other event handlers on the same element from being executed.
Here are some useful links explaining the various methods:
http://api.jquery.com/event.preventDefault/
http://api.jquery.com/event.stopPropagation/
http://api.jquery.com/event.stopImmediatePropagation/
However, since it still doesn't work it means that the onclick="" handler executes before the attached event handler. There's nothing you can do since when your code runs the onclick code has already been executed.
The easiest solution is completely removing that handler:
$('#button').removeAttr('onclick');
Even adding an event listener via plain javascript (addEventListener()) with useCapture=true doesn't help - apparently inline events trigger even before the event starts descending the DOM tree.
If you just do not want to remove the handler because you need it, simply convert it to a properly attached event:
var onclickFunc = new Function($('#button').attr('onclick'));
$('#button').click(function(event){
if(confirm('prevent onclick event?')) {
event.stopImmediatePropagation();
}
}).click(onclickFunc).removeAttr('onclick');
you need stopImmediatePropagation not preventDefault. preventDefault prevents default browser behavior, not method bubbling.
http://api.jquery.com/event.stopImmediatePropagation/
http://api.jquery.com/event.preventDefault/
The preventDefault function does not stop event handlers from being triggered, but rather stops the default action taking place. For links, it stops the navigation, for buttons, it stops the form from being submitted, etc.
What you are looking for is stopImmediatePropagation.
you can try this:
$('#button').show(function() {
var clickEvent = new Function($(this).attr('click')); // store it for future use
this.onclick = undefined;
});
DEMO
It have helped me
function goToAccessoriesPage(targert) {
targert.onclick.arguments[0].preventDefault();
...
}

can someone explain how this stopPropagation works?

I was trying to setup this "when you click outside of the element, close it" type of thing using some code I found on Stackoverflow:
$(document).click(function() {
$('.list-to-hide').hide();
});
$('.show-list-button').click(function(event) {
event.stopPropagation();
});
Could someone explain the later part with stopPropagation? I don't understand why it's needed.
Thanks!
Matt
Imagine this:
<div>
DIV
<span>
Span
</span>
<div>
and:
$('div').click(function() { alert('div clicked'); });
$('span').click(function() { alert('span clicked'); });
Check out what happens when you click each one
When you click the span, it happens to also trigger the div because your also clicking the div.
Now if we wanted to alert the span only we need to stop the div click from triggering when we click on the span so we do this:
$('div').click(function() { alert('div clicked'); });
$('span').click(function(e) { alert('span clicked'); e.stopPropagation(); });
See what happens now
Your example code is missing a vital part:
$(document).click(function() {
$('.list-to-hide').hide();
});
$('.show-list-button').click(function(event) {
event.stopPropagation();
$('.list-to-hide').show();
});
Without the event.stopPropagation(), it would show the list, and then hide it because the .show-list-button is inside the $(document) so both click handlers would fire. event.stopPropagation() basically says only apply this click event to THIS CHILD NODE and don't tell the parent containers anything because I don't want them to react.
Think about it this way - you rent a taxi for $100. The driver gives his company $80. event.stopPropagation() is like telling him to keep all $100 because the company doesn't need to know anything about the ride.
event.stopPropagation(); prevents the event from bubbling up the DOM. Without this line, clicking on .show-list-button the click handler for document will fire also. With it, the document click will not fire.
Have you read this ?
http://api.jquery.com/event.stopPropagation/
It prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
Example
Kill the bubbling on the click event.
$("p").click(function(event){
event.stopPropagation();
// do something
});

Categories