I have a button that clears a list, the click on this button shows a dialog that asks for validation (Yes/No). What I want is to disable the "Clear" button after clearing the list (Click on Yes). Here's my code :
$('#clearBtn').click(function() {
$('#alert5').show();
$('#bg').show();
$('#Yes').click(function(){
$('.list1').empty();
$('#clearBtn').disable(true);
$('#clearBtn').click(function(e){
e.preventDefault();
});
$(".alert").fadeOut(250);
$(".alertbg").fadeOut(250);
});
});
the preventDefault() function doesn't seem to work.
First never nest event handlers.
$('#cleatBtn').click(function () {
$('#alert5').show();
$('#bg').show();
});
$('#Yes').click(function () {
$('.list1').empty();
$('#cleatBtn').attr('disabled', true);
$(".alert").fadeOut(250);
$(".alertbg").fadeOut(250);
});
If you just want to disable then use the following syntax
$('#cleatBtn').attr('disabled', true);
Remove the innermost event completely.. That is not required.
Use on to bind the events, if you want the button to be enabled but turn off the event handler using off
One more option you have is to apply a class to the button when you press yes and execute the code only when the class is not present.
$('#cleatBtn').click(function () {
if( !$(this).hasClass('active')) {
$('#alert5').show();
$('#bg').show();
}
});
$('#Yes').click(function () {
$('.list1').empty();
$('#cleatBtn').attr('disabled', true);
$('#cleatBtn').addClass('active');
$(".alert").fadeOut(250);
$(".alertbg").fadeOut(250);
});
To disable a button, call the prop function with the argument true on it:
$('#cleatBtn').prop("disabled", true);
e.preventDefault(); is the correct way of cancelling events. Some older browsers also expect a return type of false. Which I think will cause jQuery to call preventDefault()?
Here's a good answer: What's the effect of adding 'return false' to a click event listener?
I think your structure looks a bit odd. you don't need to attach click events within a click event.
Just attach them all separately on document.ready events. At the moment they are nested, then go back to trying to cancel your event. The dom tree might be confused by the way the events are nested.
Hope that helps.
I'm trying to make an extension with 'pick' functionality: letting the user click on any element on the page and see the xpath for it.
However, to make it usable I have to prevent the element from reacting on clicking: I don't want clicking on hyperlinks to forward me to another page, buttons to submit forms, etc., etc.
How would I do that?
UPD: I need it only for Chrome
The cleanest way in my opinion would be to bind one event handler to body in the capturing phase and prevent the event from propagating/the default behavior.
You can get a reference to the clicked element with event.target:
document.body.addEventListener('click', function(event) {
event.preventDefault();
event.stopPropagation();
console.log(event.target);
}, true);
The advantage is that this event handler will be the very first that is triggered, no matter which other event handlers are bound to elements in the page (unless of course the page binds a similar event handler to body, but usually event handlers are bound in the bubbling phase).
For more information see quirksmode.org - Event order and MDN - addEventListener.
DEMO
For a CSS only solution:
* {
pointer-events: none;
}
Try this
$('body *').on('click',function(e){
return false;
});
In your click event handler make sure you either call preventDefault() in the event object, or return false from your function. For example:
function myClickHandler(e) {
e.preventDefault() // e is the event object
// Do your click stuff here
.
.
.
return false; // not required if you've called e.preventDefault()
}
I'm implementing an interactive tutorial for a js-heavy web application. I highlight some container and expect the user to click on some element inside it. At the same time, I want to prevent the user from doing anything else, e.g. clicking on a different link.
The main problem is that I don't want to unbind any events - when the tutorial's closed, the application must work like it did before.
I started with registering a handler on all the containter's descendant elements:
element.on("click.tutorialLock", function(e){
e.stopPropagation();
e.stopImmediatePropagation();
e.preventDefault();
}
Then I set its "priority", so that it executes before any other events:
handlers = element.data("events").click;
our = handlers.pop();
handlers.splice(0, 0, our);
Finally, when I want to unlock some element, I just disable the event on it:
elementToEnable.off(".tutorialLock")
That works, but is very heavy. I tried registering the event only on elements which have some custom event handlers defined, but it omits anchors and other basic elements. Maybe you could come up with some good idea?
I would get the active parent element and pass it into a function which would disable every event other than the events in parent
$('.className').live ('click', function (e)
{
if (!$(this).parents('#targetParent').length))
return false; // same as e.preventDefault() & e.stopPropogation()
});
Hope this is similar to what you want
We are working on a JavaScript tool that has older code in it,
so we cannot re-write the whole tool.
Now, a menu was added position fixed to the bottom and the client would very much like it to have a toggle button to open and close the menu,
except closing needs to happen automatically when a user starts doing things out side of the menu, for example, when a user goes back into the page, and selects something or clicks on a form field.
This could technically work with a click event on the body, triggering on any click,
however there are numerous items in the older code, where a click event was handled on an internal link, and return false was added to the click function, in order for the site not to continue to the link's href tag.
So clearly, a general function like this does work, but not when clicked on an internal link where the return false stops the propagation.
$('body').click(function(){
console.log('clicked');
});
Is there a way I can force the body click event anyway,
or is there another way I can let the menu dissappear, using some global click event or anything similar?
Without having to rewrite all other clicks in the application that were created years ago.
That would be a monster task, especially since I have no clue how I would rewrite them, without the return false, but still don't let them go to their href.
Events in modern DOM implementations have two phases, capturing and bubbling. The capturing phase is the first phase, flowing from the defaultView of the document to the event target, followed by the bubbling phase, flowing from the event target back to the defaultView. For more information, see http://www.w3.org/TR/DOM-Level-3-Events/#event-flow.
To handle the capturing phase of an event, you need to set the third argument for addEventListener to true:
document.body.addEventListener('click', fn, true);
Sadly, as Wesley mentioned, the capturing phase of an event cannot be handled reliably, or at all, in older browsers.
One possible solution is to handle the mouseup event instead, since event order for clicks is:
mousedown
mouseup
click
If you can be sure you have no handlers cancelling the mouseup event, then this is one way (and, arguably, a better way) to go. Another thing to note is that many, if not most (if not all), UI menus disappear on mouse down.
In cooperation with Andy E, this is the dark side of the force:
var _old = jQuery.Event.prototype.stopPropagation;
jQuery.Event.prototype.stopPropagation = function() {
this.target.nodeName !== 'SPAN' && _old.apply( this, arguments );
};
Example: http://jsfiddle.net/M4teA/2/
Remember, if all the events were bound via jQuery, you can handle those cases just here. In this example, we just call the original .stopPropagation() if we are not dealing with a <span>.
You cannot prevent the prevent, no.
What you could do is, to rewrite those event handlers manually in-code. This is tricky business, but if you know how to access the stored handler methods, you could work around it. I played around with it a little, and this is my result:
$( document.body ).click(function() {
alert('Hi I am bound to the body!');
});
$( '#bar' ).click(function(e) {
alert('I am the span and I do prevent propagation');
e.stopPropagation();
});
$( '#yay' ).click(function() {
$('span').each(function(i, elem) {
var events = jQuery._data(elem).events,
oldHandler = [ ],
$elem = $( elem );
if( 'click' in events ) {
[].forEach.call( events.click, function( click ) {
oldHandler.push( click.handler );
});
$elem.off( 'click' );
}
if( oldHandler.length ) {
oldHandler.forEach(function( handler ) {
$elem.bind( 'click', (function( h ) {
return function() {
h.apply( this, [{stopPropagation: $.noop}] );
};
}( handler )));
});
}
});
this.disabled = 1;
return false;
});
Example: http://jsfiddle.net/M4teA/
Notice, the above code will only work with jQuery 1.7. If those click events were bound with an earlier jQuery version or "inline", you still can use the code but you would need to access the "old handler" differently.
I know I'm assuming a lot of "perfect world" scenario things here, for instance, that those handles explicitly call .stopPropagation() instead of returning false. So it still might be a useless academic example, but I felt to come out with it :-)
edit: hey, return false; will work just fine, the event objects is accessed in the same way.
this is the key (vs evt.target). See example.
document.body.addEventListener("click", function (evt) {
console.dir(this);
//note evt.target can be a nested element, not the body element, resulting in misfires
console.log(evt.target);
alert("body clicked");
});
<h4>This is a heading.</h4>
<p>this is a paragraph.</p>
If you make sure that this is the first event handler work, something like this might do the trick:
$('*').click(function(event) {
if (this === event.target) { // only fire this handler on the original element
alert('clicked');
}
});
Note that, if you have lots of elements in your page, this will be Really Very Slow, and it won't work for anything added dynamically.
What you really want to do is bind the event handler for the capture phase of the event. However, that isn't supported in IE as far as I know, so that might not be all that useful.
http://www.quirksmode.org/js/events_order.html
Related questions:
jQuery equivalent of JavaScript's addEventListener method
Emulate W3C event capturing model in IE
I know this is an old question, but to add to #lonesomeday's answer, you can do the same in vanilla JavaScript with:
document.querySelectorAll('*')
.forEach(element => element.addEventListener('click', e => {
console.log('clicked: ', e.target)
}))
This will add the listener to each element instead of to the body, and from experience this will let you execute the click event even if the page is navigating away or if there's already an onclick with stopPropagation in it.
I think this is what you need:
$("body").trigger("click");
This will allow you to trigger the body click event from anywhere.
You could use jQuery to add an event listener on the document DOM.
$(document).on("click", function () {
console.log('clicked');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
document.body.addEventListener("keyup", function(event) {
if (event.keyCode === 13) {
event.preventDefault();
console.log('clicked ;)');
}
});
DEMO
https://jsfiddle.net/muratkezli/51rnc9ug/6/
My fix in Feb 2023:
To trigger a function anywhere on the page/document:
JS code:
document.onmouseup = closeMenus
'closeMenus' would be a function that turns each menu's display value to none.
Any 'mouseup' event anywhere on the document, calls the function.
I have an onclick event attached to a region in my page that causes a certain action to fire when the user clicks in it (naturally). I recently added an image to that region. When the user clicks on that image, I want another action to occur, and I do NOT want the action associated with the entire region to occur. However, I find that both events are, in fact fired when one clicks the image. How do I suppress the region-wide action when the image is clicked?
The issue you are running into is known as event bubbling. The click event of the image bubbles up to all parent elements of that node. You want to cancel bubbling.
The best way to do this that works across all browsers is by using a JavaScript framework. jQuery has a very simple way to do this. Other frameworks have similar mechanisms to cancel bubbling, I just happen to be most familiar with jQuery.
For example, you could do something like this in jQuery:
$('img').click(function () {
// Do some stuff
return false;// <- Cancels bubbling to parent elements.
});
Darit is correct, you need to stop the event from bubbling (propagating):
function imgEventHandler(e) {
// ^notice: pass 'e' (W3C event)
// W3C:
e.stopPropagation();
// IE:
if (window.event) {
window.event.cancelBubble = true;
}
}
In the event handler for the image do
event.cancelBubble = true;
and then at the end do
return false;