I have added an onclick event, which opens a new tab/page, to a button which has an action already (I don't know which action cause it isn't displayed in source, or maybe it's a form submit action).
Button originally also opens a page in new tab, what I want to do is fire up some function after my onclick attribute executes which will stop execution and that default page opening will not happen, only my page will load.
Is there something that can be done?
It sounds like the event is bubbling up after you have handled it. To stop this happening, add event.cancelBubble = true at the end of your handler.
Using jQuery, you can do this:
$('button').click(function() {
//do something
return false; // stop the event from propagating
});
Try getting your function that your call on the onclick event to return false. This will cause any existing action by the button to be overridden
If the handler was set using 'onclick=' you can simply rewrite the onclick property.
If a handler was added to an element with addEventHandler or attachEvent, you can remove it with removeEventHandler or detachEvent, using the same parameters that were used to set it.
If you don't know the setter, or if it used an anonymous function, you can't remove it.
You could replace the element with a duplicate that has no events and set your own on the new element.
(cloneNode is not supposed to clone events, but it sometimes does in some browsers.)
Related
If I have an existing click event associated with a button, can I use code to simulate that button being pressed so the code in the click event will run? I'm asking because I want there to be certain times where the user does not have to press the button for code to be executed. I would like to press the button automatically for them in certain instances if that makes any sense.
As simple as this,
$(function() {
$('#button').trigger('click');
});
var button = document.getElementById('yourButtonIdHere');
button.click();
This will fire a click event in the button
You can trigger a click event on an element by calling the .click() function on the element. By passing no value to the function the click event will fire, as opposed to setting up a listener for the click event.
If the button has an id of "form-btn", here's what that would like:
<button id="form-btn">Submit</button>
<script type="text/javascript">
//Setup the click event
$('#form-btn').on('click', function (e) {
alert('clicked!');
});
//Call the click event
$('#form-btn').click();
</script>
This should work fine, although I usually try to use a named function when setting up my event handlers, instead of anonymous functions. By doing so, rather than triggering the event I can call the function directly.
Note that in my experience, older browsers (IE6, IE7) sometimes limit what code-triggered events can do as a safety precaution for the user.
Here's documentation on the .click() function: http://www.w3schools.com/jquery/event_click.asp
Edit 1
I forgot that jQuery also has the .trigger() function, as used in choz's answer. That will also the job quite nicely as an alternative to .click(). What's nice about .trigger() is that it can trigger standard events as well as custom events, and also allow you to pass more data in your event.
Just make a function and run the function from within the button.
Three Choices:
You can call the click event handling function directly when appropriate:
if(timeIsRightForClick){
yourClickHandler();
}
You can simulate a button click by calling the .click() method of the button.
$("#ButtonID").click()
https://api.jquery.com/click/
Same as #2, but using jQuery's trigger() function, which can be used on standard events and custom ones:
$("#ButtonID").trigger("click");
http://api.jquery.com/trigger/
Choices #2 and #3 are usually better because they will cause the event handling function to receive a reference to the click event in case it needs to use that object. Choice #1 doesn't cause an actual click event (just runs the code you tell it to) and so no event object is created or passed to the event handler.
Whenever I use preventDefault(), I typically place it at the top of the event handler, like so:
$('#foo').on('click', function(e){
e.preventDefault();
// do stuff
});
Is there any harm in placing it at the bottom of the event handler, and doing stuff before you invoke e.preventDefault()?
Another way of phrasing this question: can you be sure that, by including e.preventDefault() anywhere within the event handler, you will never follow through - say, to the target on a link or the submission of a form?
I've set up a fiddle that you can play with here: http://jsfiddle.net/tuanderful/SMdrN/
Yes.. where you place the statement is irrelevant.
As long as e.preventDefault() is called within the handler the default action will not be triggered
You can place it wherever you want, you can even call e.preventDefault(); inside some if block, it doesn't change the behavior
As long as nothing goes wrong in the code, it doesn't matter where you call preventDefault.
If you put it first in the code, it will prevent the default action even if the script crashes further on.
If you put it last in the code, it will only prevent the default action if the script didn't crash anywhere on the way.
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();
...
}
I'm using jquery and creating event handlers like this:
$('#some_selector a.add').live('click', function(){...});
However, I need to not execute handlers when an element has disabled class. Then I wrote the following to achieve this:
$('#some_selector a.add:not(.disabled)').live('click', function(){...});
But I'm tired of watching over all the places that I need to add :not(.disabled), sometimes I forget to add it and so on. Moreover, if I have an anchor element and my handler prevents default action on it, than adding :not(.disabled) will cause browser to open next page instead of doing nothing.
So is there a way to set up automatic disabling on handler execution when an element meets some condition (like having "disabled" class)?
Here is what you can do:
First, bind an event handler to the .disabled elements which prevents other handlers to be executed and prevents the default action:
$('#some_selector a.add.disabled').live('click', function(event){
event.stopImmediatePropagation();
event.preventDefault();
});
Then you can bind your other event handlers as you did before. As event handlers are executed in the order they have been bound, the event handler for disabled elements will always execute first and prevent other handlers from executing (through stopImmediatePropagation [docs]).
DEMO
You could use <button> instead of <a> for this. A <button> with the disabled attribute set will not respond to clicks at all:
A form control that is disabled must prevent any click events that are queued on the user interaction task source from being dispatched on the element.
For example: http://jsfiddle.net/ambiguous/sCv8n/
You can style a <button> to look pretty much any way you want too.
Is it possible to remove than add back click event to specific element? i.e
I have a $("#elem").click(function{//some behaviour});, $(".elem").click(function{//some behaviour});(there are more than 1 element) while my other function getJson is executing I'd like to remove the click event from the #elem, and add it again onsuccess from getJson function, but preserve both mouseenter and mouseleave events the whole time?
Or maybe create overlay to prevent clicking like in modal windows? is that better idea?
edit :
I've seen some really good answers, but there is one detail that I omitted not on purpose. There are more than one element, and I call the click function on the className not on elementId as I stated in the original question
Rather than using unbind(), which means you'll have to rebind the same event handler later, you can use jQuery's data() facility with the ajaxStart and ajaxStop events to have your elements ignore click events during all AJAX requests:
$(".elem").click(function() {
if (!$(this).data("ajaxRequestPending")) {
// some behaviour
}
}).ajaxStart(function() {
$(this).data("ajaxRequestPending", true);
}).ajaxStop(function() {
$(this).removeData("ajaxRequestPending");
});
EDIT: This answer is also id-to-class-proof (see questioner's edit), since everything matching the selector will handle the AJAX events the right way. That's the main selling point of jQuery, and it shows.
You are looking for .unbind(). Pass it 'click' and it will destroy the click event.
I would put it just before your getJSON and re-bind the click event inside the success handler of your ajax call.
You have to do some additional scripting. There is no callback for that. Take a look over here: jQuery - How can I temporarily disable the onclick event listener after the event has been fired?
Rather than unbinding/binding the click event, you could check the state of another variable to see if it should do the action.
var MyObject = {
requestActive = false;
};
function MyJsonFunction() {
// when requesting
MyObject.requestActive = true;
//...
// when request over
MyObject.requestActive = false;
}
$("#elem").click(function{
if (MyObject.requestActive == true) {
//do something
}
});