I just got through figuring out that I need to watch out for duplicate event handlers in jquery if I'm dynamically assigning them multiple times as described here: http://www.parallaxinfotech.com/blog/preventing-duplicate-jquery-click-events
Do I need to watch out for this or handle it somehow if I'm declaring a function dynamically within another function multiple times? How does JavaScript really handle this? Does it only use the last function that was called or does it only instantiate a function once at load time? From what I can tell it's not running the function multiple times.
$(document).on("click",".button",function() {
function alertThem()
{
alert('Clicked!');
}
alertThem();
});
JavaScript will remember every function you're assigning it.
$('button').click(function(){
alert('hi')
})
$('button').click(function(){
alert('hi')
})
The code above will alert "hi" twice. If you're assign new function and you want to clear the old one, you can do unbind().click(). what it will do is it will unbind all events, or you can do unbind('click') which will unbind just the click. see https://jsfiddle.net/rznbtc1p/
$('button').click(function(){
alert('hi')
})
$('button').unbind().click(function(){
alert('hi')
})
The link you provided does not work (gives me timeout) so I hope I understood what you asked.
About what happens there:
In your script you created a closure and bound it to a click event. Each time you click on the element with class button, the anonymous function is triggered. Each time is triggered it defines function alertThem(), and calls it. Only once defines it, only once calls it. The scope of that function is its parent, the closure. That function is not defined outside that scope, so no need to worry about double definition.
Side note here: Personally as a rule of thumb don't think is a good idea to define functions like this, but if it suits your project... go for it.
Now about duplication. Since I cannot see the link, I think you are referring to double event binding.
In js can bind any number of events to the same element. You can for example bind on click something that says "Hi, you clicked me", then bind also on click something that says "Hi, you received a message before saying you clicked me". When you click that element, you will see both messages.
This can actually become a problem. You have 3 options:
Be really careful how you bind events
Keep tracking of what you bound
Check if events are already bound (although that is a bit unreliable). You can check how here: jQuery find events handlers registered with an object
In your code snippet, you aren't creating duplicate event handlers.
What is happening in your snippet is that you are creating a new function alertThem within the scope of your click handler function and then executing it in the line below.
Related
I call an external js file. This js file already has a (document).click function. I want to have an (document).click within the main js.
external js:
$(document).click(function() {
//do stuff
});
I do not use global variables. What's the best way to have $(document).click function in the external file and also to add an $(document).click function within the main js?
You can have both. As long as nobody stops propagation, both event handlers will run.
Do post the code if you still have any trouble.
Expanding the answer a bit:
There is in fact a way (the wrong way) to do click event handlers that supports only one at a time. If you do:
element.onclick = function () {alert('a')};
And then
element.onclick = function () {alert('b')};
You will get only one alert (saying 'b'). Which is why you should never use that. This is a remnant of a time when nobody knew what they were doing. It's 2015, the less we talk about it the better.
Now, when you use the proper way of registering event handlers:
element.addEventListener('click', function () {alert('a')});
element.addEventListener('click', function () {alert('b')});
You'll get both alerts.
To clear up any confusion, it's worth mentioning that jQuery uses the same old addEventListener internally when you do $(element).click(f) or $(element).on('click', f) or however it works today.
You can add 'click' event on both the file,but the problem is, when
you click on that particular element both the handlers will fire on
the same time If i am not wrong, both handler will work differently
and should not fire at same time.
Best way use Event trigger with different name spaces of events.
$(document).on('click.func1',function(){
func1();
});
$(document).bind('click.func2',function(){
doStuff2();
});
Then when you need to trigger you can choose order.
$(document).trigger('click.func1').trigger('click.func2');
Or you can trigger both event on same time:
$(document).trigger('click');
I am wondering if anyone can help with understanding this Javascript syntax.
Lets say I have the following:
<script>
$(function(){
$("#contactbutton").click(function(event){
$("#dialog").dialog({width:500});
});
});
</script>
I understand that the first line is testing if the DOM is ready and loaded. It then passes control to the inside function.
This inside function gets the element with an ID of contactbutton and for the click event, passes control to the next function.
This inner function, gets the elemnt with an ID of dialog and calls the .dialog method to display the dialog box. However, I am not sure about:
function(event)
What is the event parameter here, and why do we need it? Also, can this be renamed to anything we want?
Thanks,
This is actually an object that is accessible within that function. Usually it is called the event reference. The object holds details, functions, variables, etc., about the function and event, allowing you to handle the event and access properties of it. You are able to access it once you set a name to the first argument of the handler, that is function(event) { }
In a certain case, say you wanted to prevent the default event of an anchor link which would be to navigate the page to stackoverflow.com. preventDefault is a function that can do this, that is, prevent the default event. In this case that would be to prevent the navigation to stackoverflow.com. You are able to access the preventDefault function using the syntax event.preventDefault() if you have assigned the name event to the first argument of the handler.
For another example, in an onkeydown event you can access which key has been pressed with event.keyCode.
In $.ready() I have declared a click function as shown below
$(document).ready(function(){
$("#btnClk").click(function(clkevent){
//Doing Something Here
clkevent.preventDefault();
});
});
I want to remove this click() from $("#btnClk") in another javaScript function. How can I do this?
One of the problems with the proposed solutions is they remove all click event handlers registered, which may not be desired.
A solution to this is to separate the handler method out to a common scope shared by the both the participating methods then use that method reference along with .off() to resolve this
function btnclickHandler(clkevent){
//Doing Something Here
clkevent.preventDefault();
}
$(document).ready(function(){
$("#btnClk").click(btnclickHandler);
});
$("#btnClk").off('click', btnclickHandler);
Old School
$("#btnClk").unbind('click');
New School
$("#btnClk").off('click');
To register a click handler you should be using .on('click', ...) instead of .click - the latter can cause confusion because the same function is also used to trigger a click event.
To unregister the handler, use .off('click')
Please see the caveats at http://api.jquery.com/off/ regarding function handlers, name spaces, etc (my emphasis):
If a simple event name such as "click" is provided, all events of that type (both direct and delegated) are removed from the elements in the jQuery set.
and
A handler can also be removed by specifying the function name in the handler argument.
Note that in the latter case you can't specify the function name if the function never had a name in the first place, as in the code in the question where the handler is an anonymous function.
You can use unbind for this .
$('#btnClk).unbind('click');
almost same question
You can do this using off():
$('#btnClk').off('click');
This will remove all click event handlers from the btnClk.
Alright, so I'm making a Facebook-style chat. But that doesn't really matter.
See here:
http://jsfiddle.net/SkHme/7/
Nice and pretty, right? Well, there's a problem. Notice this line:
<div class="conversation EmperorCuzco" onclick="setActive('EmperorCuzco')">
See the onclick attribute? Well, it's not working. However, I have confirmed that the function itself DOES work. (if you run it just like that in the JavaScript, it runs like a dream) I have further confirmed that the function is not the problem by attempting to replace the onclick value with a simple alert('blah'), but that doesn't work either.
So, what's up? I'm guessing that something in my JavaScript is somehow disabling something, but I have absolutely no idea what it could be, nor how I could go about fixing it. I did some web searching, but couldn't find anything that helps.
What's going on?
Your setActive function is defined inside the scope of the $(document).ready handler. Move the function outside that function so that it is in the global scope.
Right now it looks like this:
$(document).ready(function()
{
// ...
function setActive(new_conversation)
{
// ...
}
});
Now change that to:
$(document).ready(function()
{
// ...
});
function setActive(new_conversation)
{
// ...
}
Really though, you should separate your content from your interactions and bind those event handlers in your script itself. Something like:
// Refers to the last clicked conversation *button*
// Initialize to empty jQuery object
var $active_conversation = $([]);
// Binding on #chat, targeting click events on .conversation_button children
$("#chat").on("click", ".conversation_button", function() {
// Hide currently active conversation
$active_conversation.hide();
$active_conversation.siblings('.conversation_button').removeClass("selected");
// Set as currently active conversation button
// Note: this refers to the clicked <div class="conversation_button">
var $this = $(this);
$active_conversation = $this.siblings('.conversation');
// Show this conversation
$active_conversation.show();
$this.removeClass("alert").addClass("selected");
});
Some advantages of this approach:
You don't need different classes for different conversations. By storing the actual conversation DOM element (as a jQuery object) in $active_conversation, the conversation can be identified without any extra processing.
You can add and remove whole list items with a conversation without assigning new event handlers. In the sample above, the event handler for all .conversation_button elements is defined at the level of #chat. For more about this binding mechanism, read up on .on (or .delegate for pre-1.7).
Here, have an updated fiddle! :-)
If all you say is really true (bad mistakes happen), the only thing that can make this is that an other event handler which takes your event before uses stopPropagation() or return false;
A quick check that can do is replace onclick with onmousedown or onmouseup, and see if you alert become visible.
Good morning peoples.
I have a bit of a slight jQuery question/problem that I am not sure how to tackle.
I have a click handler bound to varying classes on some anchor tags (which works great). I have now come to a page that needs an extra handler on the same anchor tags so I decided to use some namespacing to get the desired result. The trouble with the namespacing is that it is called before the original click handler and creates problems with the first handler. The error is raised due to the first handler requiring an element to exist to continue in the function but the namespaced click handler removes the element before so it errors out.
Does anyone know if one can tell namespaced handlers to execute After the original handler or would I have to completely re-write the script and perhaps extend it on this one (and only) page to have the funcitonality work as I would like.
Thanks in advance.
Alex
It's easier to add a classname to the anchors on the page that events are bound on and check that in my function..
Sorry for any time wasted
If you bring the handler out into a separate function, you can call the original handler from the other handler.
function handler() {
// original event handler code
};
$('#originalTarget').click(handler);
$('#otherTarget').click(function() {
// code to do anything specific to this handler
handler();
}
You can assign more than one handler:
// general handler
$('a.linkclass').click( function(){
doThis();
});
// specific handler on the page in question
$('#specificlink').click( function(){
doSomethingExtra();
});