Jquery/Javascript - javascript

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();
});

Related

Why are event handlers being removed in this function?

I'm trying to understand why event handlers need to be removed. I'm a beginner developer, and I searched all over for the answer but couldn't find the reason.
I came across the code below and I see that the event handler is removed as soon as it is bound. Is it a good practice?
bindSubmitEvent: function() {
var self = this;
$('#submitBtn').on('click', function() {
$(this).off('click', self.bindSubmitEvent);
self.validateForm();
if (self.options.valid_selection) {
self.submitForm();
} else {
$('#submitRegistrationBtn').on('click', self.bindSubmitEvent);
console.log("not valid");
}
});
}
The code you've shown does not work.
this inside the inner click handler is #submitButton, therefore trying to detach the self.bindSubmitEvent from it makes no sense, as that function was never attached to it.
Also $('#submitRegistrationBtn').on('click', self.bindSubmitEvent) will cause more trouble, as two events will be attached at the next click, and the second one will be called with this (and therefore self being the #submitRegistrationBtn. That will probably cause the whole code to fail (silently).
Is it a good practice?
Non working code is not a good practice, no. Removing an event listener sometimes makes sense (e.g. if the form was submitted, you want the registration button to be disabled), in most cases however, it is way easier to just remove the button itself (as it serves no functionality without a listener attached).

Do I need to delete duplicate dynamic functions in Javascript?

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.

Delegate onclick handler of one element from another using Jquery

My question is as follows:
I have a dynamically generated element that has onclick='removeMe()', a function that causes it to removes itself.
I used jQuery .on('click',selector,handler) delegation to bind a function to this element, to execute a specific block of code.
However, the element removes itself and in doing so deletes the handler that would execute that block of code.
To spice things up: the block of code must be run after the element is removed, and I cannot edit the function that removes the element to execute my code after.
I'm new to jQuery, so the first solution that popped into my head was to somehow bind the handler to another element that is never removed, which runs when the first element is clicked.
Is that possible?
Are there any other, better solutions I haven't thought of? Am I missing something obvious?
If my explanation is not clear I can provide clarification or provide the actual situation in which this takes place.
Thanks in advance!
Edit: Answered by Sivapriyan, and that solution is exactly what I needed. Thank you!
Why don't you just run everything in your onClick handler.
$( "#target" ).click(function() {
$(this).remove();
//Execute your block of code :)
});
$(document).on("click",".selector",function(){
alert("I will always live");
});
Declare in that way and you handler will always a live. Now the handler is on the document and no on the $element

jQuery event firing twice after .load()

I've come across an issue where jQuery events fire twice after $.load() is called. The event handler is placed in the load() callback function, and this seems to be the only place where events fire twice on the script.
I've tried adding event.stopPropogation() and event.preventDefault(), as these seem to be common suggestions with jQuery events firing more than one. I'm not sure if my code is bubbling improperly or what. Any feedback would be helpful.
Here's an extract of some of the code where you see the behavior.
$("div.questions").load("question_source.php #simplified_a", function(){
...
// Line 1
$("#some_id").change(function(){
cantBeNegative(this);
adjusted_gross_income = $(this).val();
console.log(adjusted_gross_income);
// event.stopPropagation();
// event.preventDefault();
});
You can clearly see the event firing twice with the console.log bit I've got in there. Any advice would be appreciated!
EDIT
OK, I checked through everything on the live page based on some of the suggestions, and there's definitely only one <div id="questions"> in existence when the problem is occurring. So, it doesn't appear to be an HTML problem.
I also checked to see if the event was actually being called twice, and as far as I can tell, the event is only being called once.
Now, I added a .on() event attached to the document which is called on the dynamically created elements, and that only fires once. .on() is not called within the .load() callback. Here's an example used on one of the other input boxes on the page which works without any problems:
$(document).on('change', "#SWA_mothers_income", function(){
console.log("mothers income changes from on()");
});
So, that works properly, but when tested on the same input within the .load() callback function, it fires twice, regardless of how it's called. So, it seems to me that it's almost certainly an issue with .load(). I wouldn't exactly call myself an expert in this, so if someone can figure out the issue, I'd love to know the answer. As it stands, I'm going to rewrite this code using .on().
SECOND EDIT
Adding $("#some_id").unbind('change');
before the 'change(function()) bit did the trick!
add this line
$("#some_id").unbind('change');
before
$("#some_id").change(function(){});
I'm not saying this will solve your problems but you need to pass in the event to reference it.
$("#some_id").change(function(event){
cantBeNegative(this);
adjusted_gross_income = $(this).val();
console.log(adjusted_gross_income);
event.stopPropagation();
event.preventDefault();
});
It's possible that you have two divs with a class of 'questions', so you could be binding the change function twice.
If you update your change function to the below, this will unbind the change event before re-adding it. This will make sure you only have the function bound once;
$("#some_id").unbind('change').change(function(event) {
event.preventDefault();
cantBeNegative(this);
adjusted_gross_income = $(this).val();
console.log(adjusted_gross_income);
});

Memory leak with unused event handler in javascript

I'm in a situation where I make a lot of ajax calls to change the same portion of html. This html represent a grid. After changing the html in the ajax call, I attach a event handler to an event of the grid. When the user click on a refresh button, I execute the same ajax call that set new html code and also add again an event handler to listen of event of the grid.
I want to know if each time I refresh my grid and add a new event handler if the previous event handler is still in memory and if yes, what are the bests practices in this situation? (e.g. unbind the event handler if exist before putting new html)
Here is an example of what I do:
$.get(this.config.actionLoggingUserListUrl, viewModel, function (data) {
MyNamespace.ui.hideGridAnimation($("#LoggingActionUsersList"));
if (data.success) {
$("#validationSummary").html("");
$("#usersList").html(data.result);
$("#LoggingActionUsersList").click(function() {
console.log("Here is my event handler attached multiple times!");
});
}
else {
$("#validationSummary").html(data.result);
$("#usersList").html("");
}
});
Note that the event handler I'm talking in this case is:
$("#LoggingActionUsersList").click(function() {
console.log("Here is my event handler attached multiple times!");
});
Event handlers stack, so yeah, this is a memork leak. Probably a fairly insignificant one, but its more the principle than the effect. Unless for some reason you really do need to have dynamic event handlers (something that is pretty rarely used as there aren't very many realistic uses for it), I'd strongly suggest pulling the event handler assignment out of the ajax call.
If you do need the event handler to change, the clever way to do it would be to make your event handler smart enough to know a little bit about the object to which it is assigned. That way, instead of adding a new event each time, you can just have logic in the event handler do different things based on the current identity of the object.
why are you binding it every time you make the call?
You are adding onto the stack every time. You are not replacing it. Best solution is to use on and do it once.
Other solution is to unbind the click event, before you add click event. The problem with this solution is if anything else added the click event, you just removed it.

Categories

Resources