I have a simple click handler that will alert its link's href as in:
<a id="link" href="http://www.google.com">Google</a>
$('a#link').on('click', function() {
alert($(this).attr('href'));
});
How can I separate the function (and how to call it) so that it can be called by another click handler?
function showHref() {
/* What to do here because $(this) won't resolve to <a> anymore. */
}
// I'd like a#another-link to be able to call that same function above.
<a id="another-link" href="http://www.microsoft.com">Microsoft</a>
$('a#another-link').on('click', /* How to call showHref? */);
Thanks.
You could do something like this:
function showHref() {
alert($(this).attr('href'));
}
$('a#link').on('click', showHref);
$('a#another-link').on('click', showHref);
In this code, this inside the showHref will refer to the link being clicked, since jQuery makes sure that the link being clicked is the calling context (using .call() which you may want to read up on). If, however, you were to manually call showHref, this would not refer to your link.
If you want a definition of showHref that you could both call manually, and bind through jQuery, it would probably be neatest to pass the reference as a parameter:
function showHref(link) {
alert($(link).attr('href'));
}
In that case, you'd have to adjust your listeners as follows:
$('a#link').on('click', function() {
showHref(this);
});
But it is also possible to combine selectors:
$('a#link, a#another-link').on('click', function() {
alert($(this).attr('href'));
});
You can put the function logic into a reference like this:
var handler = function () {
alert($(this).attr('href'));
};
Then you can use that reference to initialize event listeners:
$('#link').on('click', handler);
Of course, you can reuse that.
$('#some_other_link').on('click', handler);
Or call that yourself outside of an event handler context (which normally wouldn't make sense if you're fashioning an event handler function --- but it can be done with lambdas in general).
handler();
But if you want to just trigger the event on an element, you should call the corresponding event trigger function.
$('#link').click();
// or
$('#link').trigger('click');
You wrote:
function showHref() {
/* What to do here because $(this) won't resolve to <a> anymore. */
}
Umm, actually, yes it will. That's exactly the promise made by DOM events and also event handlers registered with jQuery.
FWIW, the content should just be:
alert(this.href)
There's really no need to invoke jQuery just to get the element's href attribute.
Related
so I'll be short: jquery .off() doesn't disable a listen I've set with .on.
html:
<span id="myspan">lol</span>
<button id="b1">jquery On</button>
<button id="b2">jquery Off</button>
js:
$("#b1").on("click", add);
$("#b2").on("click", del);
function add() {
$("#myspan").on("click", function(e) {
var a = 1;
testfunc(a, e);
});
}
function del() {
$("#myspan").off("click", testfunc);
}
function testfunc(num, event) {
alert(num);
}
So first we add to myspan the testfunc() by clicking the jquery On button. After we do that, if we click on the span, we get an alert. Next, we click the jquery off button. That is supposed to remove the listener but it doesn't. Even after that, when we click on myspan testfunc is still attached.
Why? And how can I remove it ?
Your parameters don't match
It doesn't because you bound to a different function (anonymous one). And then you're trying to unbind from testfunc... In order for your event (un)binding to work both parameters between on and off must match.
Possible workaround
If this is the only click event listener on the element, then it's be easiest way to unbind from your anonymous function by calling:
$("#myspan").off("click");
If you're binding several event handlers to click event on the same element then you can also distinguish them by providing namespaces and then use proper namespacing in off call.
$("#myspan").on("click.test", function(e) { ... });
...
$("#myspan").off("click.test");
Or use just namespace if you'd like to unbind several different event handlers that were bound using the same namespace:
$("#myspan").off(".test");
You're not binding the event handler to testfunc, you're binding it to an anonymous function, and whitin that function you're just calling testfunc, so you can't automatically unbind that.
It's either
$("#myspan").on("click", testfunc); // bind function
and then
$("#myspan").off("click", testfunc); // unbind function
or to unbind the anonymous function, just
$("#myspan").off("click"); // remove all handlers
or you can also namespace the handler
$("#myspan").on("click.test", function(e) {
var a = 1;
testfunc(a, e);
});
and to remove only that handler
$("#myspan").off("click.test");
In this simple case, replace your off call with this:
function del() {
$("#myspan").off("click");
}
You don't need to pass the handler function to the off call, and if you do, it will only remove that particular handler. However, you did not attach testfunc, but an anonymous function that just calls testfunc(). Therefore, your off call does nothing.
Also, you never assigned the variable testfunc.
I have a button on which i am attaching a click event. I have to unbind it after i click on it, and later on in my code i need to bind that click event on it again. I tried binding it again but that does not works. I can't use jquery 'live'. Is there any way to create a custom bind function on click event and then again call it ?
$(".submitButton").click(function(e){
//some functionality on click
$(".submitButton").unbind('click');
});
//somewhere ahead in my code
$(".submitButton").bind('click');
Apparently this isn't working. Is there any way to tackle this ?
Your .bind call doesn't seem correct. You haven't specified a callback.
So start by writing a function:
function handleButtonClick() {
//some functionality on click
$(this).unbind('click');
}
Notice that inside the handler I am unbinding $(this) which is the element being clicked and not all elements with class="submitButton".
and then:
$('.submitButton').bind('click', handleButtonClick);
and then later when you want to rebind:
$('.submitButton').bind('click', handleButtonClick);
and so on.
define your listener somewhere else:
function clickHandler() {
//some functionality on click
$(".submitButton").unbind('click', clickHandler);
}
$(".submitButton").bind('click', clickHandler);
//somewhere ahead in my code
$(".submitButton").bind('click', clickHandler);
When you use .bind() to bind an event handler it expects a function to be passed as well, since that's what will be executed when the event fires. Don't use an anonymous function, instead declare a named function and pass a reference to that when binding.
function handleClick(e){
//some functionality on click
$(".submitButton").unbind('click');
}
$(".submitButton").click(handleClick);
// somewhere else in your code (in reaction to some other event)
$(".submitButton").click(handleClick);
You can use jQuery.one(). Please refer below code.
$(".submitButton").one('click', clickHandler);
The first form of this method is identical to .bind(), except that the handler is unbound after its first invocation.
you can call it or bind it whenever it necessary.
So, there are two important details to this question:
its inside the scope of document ready's callback function
the element that the event is attached to does not actually exist in the DOM
Here's a visual representation of the scenario
$(document).ready(function() {
$('#myNonExistentElement').on('click', function() {
//do something
});
});
Is it possible to programatically trigger that click event (via console or something else) under those circumstances?
I think the simple answer is no.
There are two cases which might, however, fit with your question:
1) If you just want to execute the event handler code, use a named function (instead of an anonymous function) and call it whenever you need to.
2) If you want to bind a click handler to an object that does not yet exist in the DOM but you know will in the future, you can use code like:
$(document).ready(function() {
$('body').on('click', '#myNonExistentElement', function() {
//do something
});
});
See the section about delegated events at http://api.jquery.com/on/
If you try to bind an event to an element that doesn't exist via jQuery (or at the very least, .on) no new event will be bound.
Sample case here.
*event code stolen from here because I'm lazy.
I have a page with boxes and I want a function to run on each box click. Additionally, I want the function to run ONCE on page load.
(The idea is that the function "updates the state", and I want to update on each click, but also on page load - to initialize the state, so to speak.)
Normally, I do this like so:
$('.box').click(function() {
// do something
}).first().click();
So I attach the handler to each .box click event, and then I get the first .box element and trigger the click event on it.
This approach works, but it feels kind-of clumsy. How do you tackle this problem?
jQuery has triggerHandler()(docs), which offers a number of advantages that may be desired for your code.
$('.box').click(function() {
// do something
}).triggerHandler('click');
From the docs:
The .triggerHandler() method does not cause the default behavior of an event to occur (such as a form submission).
While .trigger() will operate on all elements matched by the jQuery object, .triggerHandler() only affects the first matched element.
Events created with .triggerHandler() do not bubble up the DOM hierarchy; if they are not handled by the target element directly, they do nothing.
Instead of returning the jQuery object (to allow chaining), .triggerHandler() returns whatever value was returned by the last handler it caused to be executed. If no handlers are triggered, it returns undefined
function hello() {
//Here goes your update function
alert('world');
}
$('.box').click(hello);
hello();
This is how I would probably do it.
(function(){
var foo = function(){
// stuff
}
$('.box').click(foo);
foo();
})();
Calls foo when it initializes and adds it to the click.
Something like this could also work :
$(document).ready(function($) {
$('.box').click(function() {
$(this).val("Value"); //Your function here
});
$('.box').each(function() {
$(this).val("Ready"); //Your function here
});
});
Demo
There's this piece in the codebase I'm working on:
this.element.addEvent('click', this.clickEvent.bindWithEvent(this));
I want to change it so that the click event makes sure the window is loaded first. So I tried:
var t = this;
this.element.addEvent('click', function() {
window.addEvent('load', function() {
t.clickEvent.bindWithEvent(t));
});
});
That doesn't seem to get it to work though. What am I missing?
You're adding a handler to the load event when the user clicks something, _aftertheload` event has already fired. Therefore, nothing happens.
You should probably add the click handler inside of an event handler for the load event. (swap the two addEvent lines)
in mootools you tend to use domready and not load but essentially, doing it as suggested will not work as it lacks the context here:
this.element.addEvent('click', this.clickEvent.bindWithEvent(this));
so you are working within a class here - therefore, make sure you instantiate it on the domready event instead, something like...
window.addEvent("domready", function() {
// whatever you need to do...
var foo = new myClass($("someElement"), {option: value}); // example instantiation
// if the binding is not in the .initialize, then call the right method...
// foo.bindMyEvents();
});
as long as the class instance is within domready, you're fine. if that's not an option, see which method binds the events and call that on the domready instead.