So i have the same piece of code that runs for both Ready and Click events, but when I try to combine them it doesn't work
$("input[name='reimburse']").on("ready click", function() {
//some code
});
I think it has to do it the Ready function because even this doesn't work
$("input[name='reimburse']").on("ready", function() {
//some code
});
Instead I have to do this for Ready functionality
$("input[name='reimburse']").ready(function() {
//some code
});
Other than creating another JS function and calling that method from 2 different declared events, how can I achieve my initial code? Why doesn't calling on("ready") work?
EDIT:
Its been brought to my attention that ready event is not applicable for individual DOM's and that load should be used instead. I have tried this but still doesn't work. Only the click event works. I have also tried replacing on with bind and same thing happens.
The ready event applies to the document, not to individual DOM elements. So, there is no specific ready event that applies to the "input[name='reimburse']" DOM elements.
If what you're trying to do is to have the same function fire both when the page is first loaded and when a specific click event is fired, then you can put your common event handling code into a named function and then refer to that function from two separate event handlers:
function myHandler(e) {
// code here
}
$(document).ready(myHandler);
$("input[name='reimburse']").on("click", myHandler);
Though, the last line of code above will only work IF those DOM elements are already loaded. As such, you may need to put that line of code inside a .ready() handler (depending upon where the code is being run from).
$(document).ready(function() {
$("input[name='reimburse']").on("click", myHandler);
myHandler();
});
Here's another related answer: jQuery.ready() equivalent event listener on elements?
Why doesn't calling on("ready") work?
Because jQuery decided not to support that structure. jQuery used to support $(document).on( "ready", handler ), but as of jQuery v1.8, that support has been deprecated (e.g. you shouldn't use it because it will be removed). Per the jQuery documentation, these three forms can be used for .ready().
$( document ).ready( handler )
$().ready( handler ) // works, but not recommended
$( handler )
If it is bothering you to have to both specify an event handler and call your function at initiatialization time, then you could create your own plug-in that would do that for you:
$.fn.initOn = function(events, handler) {
this.on(events, handler);
handler();
}
Then, instead of this:
$(document).ready(function() {
$("input[name='reimburse']").on("click", myHandler);
myHandler();
});
You could just do this:
$(document).ready(function() {
$("input[name='reimburse']").initOn("click", myHandler);
});
You can just imitate the click on ready:
jQuery(document).ready(function () {
$("input[name='reimburse']").click(function() {
//some code
});
$("input[name='reimburse']").click();
});
Try using bind()
$("input[name='reimburse']").bind("ready click", function() {
//some code
});
According to the documentation
Multiple event types can be bound at once by including each one
separated by a space
Note, ready is valid for document and shouldn't be used for elements. To get similar functionality, use load
$("input[name='reimburse']").bind("load click", function() {
//some code
});
From the jQuery docs here: https://api.jquery.com/ready/
There is also $(document).on( "ready", handler ), deprecated as of jQuery 1.8. This behaves similarly to the ready method but if the ready event has already fired and you try to .on( "ready" ) the bound handler will not be executed. Ready handlers bound this way are executed after any bound by the other three methods above.
While you shouldn't be using deprecated methods whenever possible, I'm curious, where are you setting your event listeners?
Related
This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 8 years ago.
Suppose I have some jQuery code that attaches an event handler to all elements with class .myclass.
For example:
$(function(){
$(".myclass").click( function() {
// do something
});
});
And my HTML might be as follows:
<a class="myclass" href="#">test1</a>
<a class="myclass" href="#">test2</a>
<a class="myclass" href="#">test3</a>
That works with no problem.
However, consider if the .myclass elements were written to the page at some future time.
For example:
<a id="anchor1" href="#">create link dynamically</a>
<script type="text/javascript">
$(function(){
$("#anchor1").click( function() {
$("#anchor1").append('<a class="myclass" href="#">test4</a>');
});
});
</script>
In this case, the test4 link is created when a user clicks on a#anchor1.
The test4 link does not have the click() handler associated with it, even though it has class="myclass".
Basically, I would like to write the click() handler once and have it apply to both content present at page load, and content brought in later via AJAX / DHTML. Any idea how I can fix this?
I am adding a new answer to reflect changes in later jQuery releases. The .live() method is deprecated as of jQuery 1.7.
From http://api.jquery.com/live/
As of jQuery 1.7, the .live() method is deprecated. Use .on() to attach event handlers. Users of older versions of jQuery should use .delegate() in preference to .live().
For jQuery 1.7+ you can attach an event handler to a parent element using .on(), and pass the a selector combined with 'myclass' as an argument.
See http://api.jquery.com/on/
So instead of...
$(".myclass").click( function() {
// do something
});
You can write...
$('body').on('click', 'a.myclass', function() {
// do something
});
This will work for all a tags with 'myclass' in the body, whether already present or dynamically added later.
The body tag is used here as the example had no closer static surrounding tag, but any parent tag that exists when the .on method call occurs will work. For instance a ul tag for a list which will have dynamic elements added would look like this:
$('ul').on('click', 'li', function() {
alert( $(this).text() );
});
As long as the ul tag exists this will work (no li elements need exist yet).
Sometimes doing this (the top-voted answer) is not always enough:
$('body').on('click', 'a.myclass', function() {
// do something
});
This can be an issue because of the order event handlers are fired. If you find yourself doing this, but it is causing issues because of the order in which it is handled.. You can always wrap that into a function, that when called "refreshes" the listener.
For example:
function RefreshSomeEventListener() {
// Remove handler from existing elements
$("#wrapper .specific-selector").off();
// Re-add event handler for all matching elements
$("#wrapper .specific-selector").on("click", function() {
// Handle event.
}
}
Because it is a function, whenever I set up my listener this way, I typically call it on document ready:
$(document).ready(function() {
// Other ready commands / code
// Call our function to setup initial listening
RefreshSomeEventListener();
});
Then, whenever you add some dynamically added element, call that method again:
function SomeMethodThatAddsElement() {
// Some code / AJAX / whatever.. Adding element dynamically
// Refresh our listener, so the new element is taken into account
RefreshSomeEventListener();
}
Hopefully this helps!
Regards,
After jQuery 1.7 the preferred methods are .on() and .off()
Sean's answer shows an example.
Now Deprecated:
Use the jQuery functions .live() and .die(). Available in
jQuery 1.3.x
From the docs:
To display each paragraph's text in an
alert box whenever it is clicked:
$("p").live("click", function(){
alert( $(this).text() );
});
Also, the livequery plugin does this and has support for more events.
If you're adding a pile of anchors to the DOM, look into event delegation instead.
Here's a simple example:
$('#somecontainer').click(function(e) {
var $target = $(e.target);
if ($target.hasClass("myclass")) {
// do something
}
});
You can bind a single click event to a page for all elements, no matter if they are already on that page or if they will arrive at some future time, like that:
$(document).bind('click', function (e) {
var target = $(e.target);
if (target.is('.myclass')) {
e.preventDefault(); // if you want to cancel the event flow
// do something
} else if (target.is('.myotherclass')) {
e.preventDefault();
// do something else
}
});
Been using it for a while. Works like a charm.
In jQuery 1.7 and later, it is recommended to use .on() in place of bind or any other event delegation method, but .bind() still works.
Binds a handler to an event (like click) for all current - and future - matched element. Can also bind custom events.
link text
$(function(){
$(".myclass").live("click", function() {
// do something
});
});
If your on jQuery 1.3+ then use .live()
Binds a handler to an event (like
click) for all current - and future -
matched element. Can also bind custom
events.
You want to use the live() function. See the docs.
For example:
$("#anchor1").live("click", function() {
$("#anchor1").append('<a class="myclass" href="#">test4</a>');
});
I have a jQuery plugin, and inside of it I have an init function. Inside of this init-function I attach some events:
(function ( $ ) {
$.fn.gallery = function(options) {
var init = function(self) {
var main += '<input id="gallery-search">';
//click event for the filter checkboxes
$("body").on('click', self.selector+" .gallery-filter-checkbox",function(event) {
self.data(filter( self ));
});
//capture input in the search box
$('#gallery-search').keyup(function(){
console.log('test');
});
self.html(output);
}
}( jQuery ));
}
The first one works just fine, but the second one doesn't work at all. I have tested it outside of the plugin scope and it works just fine so there is no syntax error, but probably an error in the way I try and attach the event?
Since #gallery-search is created dynamically, you can use delegated event handler:
$(document).on('keyup', '#gallery-search', function() { ... });
If self represents static HTML element at page, you can use a little better (for performance) version:
self.on('keyup', '#gallery-search', function() { ... });
Or you can place event handler in code after element's insertion, if HTML will not be modified later:
self.html(output);
$('#gallery-search').keyup(function()
{
console.log('test');
});
keyup() is a shortcut for bind('keyup',callback) which will register some event handler on the elements that are already present in the DOM (not necessarily rendered). It won't work if the element is not present in DOM when it's defined. To do that you need to use delegate() which will attach some handler on an element which is currently available or in might be available in future.
From jQuery 1.7 onwards, it's recommended to use on() as it combines the functionality of bind / delegate / live.
on() can be used in two ways
$(selector).on('event',callback);
$(parentSelector).on('event','someChildSelector', callback);
First one is direct handler and second one is called delegated handler.
If you're using first one to register event handlers, you've to make sure that element is present in the DOM at the time of registering just like bind(). So if you're adding new elements, you have to attach that handler again.
If you're using the second way, you don't have to worry about registering the handler again
$(document).on('click','.row',callback);
As document is always available, you callback will be registered as click handler for all the existing rows and any new row that you might add in the future.
I strongly recommend you read the Direct and delegated events section here. They even explain about the performance benefits.
Now that you know how it works, you can fix it using on() either as a direct handler or as a delegated handler.
EDIT : It's better to use closest static parent than document/body when using on() to register delegated handlers. Thanks to Regent for suggesting that :)
$('closestStaticParent').on('keyup','#gallery-search',function(){
console.log('test');
});
In this example someone shows a jQuery onclick event.
My shows this:
$(function() {
$('.post').on('click', function() {
SOME STUFF
});
});
But what are the first and last line doing?
if i remove the lines, it's not working:
$('.post').on('click', function() {
SOME STUFF
});
But why? In the linked example is a second commenter. He shows this way (without first/last line).
Can someone explain this?
It is a shortcut for $( document ).ready(...)
See http://api.jquery.com/ready/
Quoting the doc :
While JavaScript provides the load event for executing code when a page is rendered, this event does not get triggered until all assets such as images have been completely received. In most cases, the script can be run as soon as the DOM hierarchy has been fully constructed. The handler passed to .ready() is guaranteed to be executed after the DOM is ready, so this is usually the best place to attach all other event handlers and run other jQuery code. [...]
All three of the following syntaxes are equivalent:
* $( document ).ready( handler )
* $().ready( handler ) (this is not recommended)
* $( handler )
That is short for document.ready. It waits until the entire document is loaded and the element with class .post can be found and bound to.
If you omit that part, the jQuery function will not find the element and your event will not work.
The first and last lines create an anonymous function. In computer programming, an anonymous function is a function defined, and possibly called, without being bound to an identifier.
In the example here it is used to set the event listener that is loaded onload of the page.
$(function() {
$('.something').on('click', function() {
alert('hello');
$(this).addClass('classOne');
});
});
$(function(){});
is jQuery short hand for
$(document).ready(function() {});
which ensures your document is ready for manipulation before executing anything within it. In many ways its similar to the browser window.onready event. See jQuery docs..
The risk if you don't wrap your jQuery code in either of these forms of the functions is that you will try and manipulate elements before they have been created by the browser. Your code is not guaranteed to fail, but you could, at the very least, get inconsistent behaviour.
This works for running the same code on both ready and resize:
$(document).ready(function() {
$(window).resize(function() {
// Stuff in here happens on ready and resize.
}).resize(); // Trigger resize handlers.
});//ready
How would you accomplish the same result using jQuery.on() ?
on can be used to wire up the resize and ready events just like any other event.
So for your case, you could create a function that has the code you want to happen for resize and ready, and then pass it to both calls to on.
If you want to keep your enclosing scope clean, you could do all this in an immediately executing function:
(function() {
function stuffForResizeAndReady(){
// Stuff in here happens on ready and resize.
}
$(window).on("resize", stuffForResizeAndReady);
$(document).on("ready", stuffForResizeAndReady);
})();
2012-07-25: There are 2 differences to be aware of when using .on() to attach ready handlers:
Ready handlers added via $(fn) and $(document).ready(fn) are "retro-fired" while ones added by .on() are not. Using those, if you add a handler after the DOM is already loaded, the fn will be fired immediately. If you add a handler via .on('ready', fn) after the DOM is loaded, it will not be fired by jQuery, but you can manually .trigger('ready') it.
When you use $(fn) or $(document).ready(fn) to add a ready handler, the fn receives jQuery as its 1st arg, allowing the familar jQuery(function($){ }) usage. If you use $(document).on('ready', fn), the 1st arg that the fn receives is an event object. In both cases this inside the fn is the document. If you were to do something abnormal like $('#foo').on('ready', fn) for the purpose of triggering, this would be the #foo element.
.ready(), .resize(), and others like .mouseover() are all just short-cuts for using the .bind() function (or .on() in jQuery 1.7+). .resize(function () {}) maps to .bind('resize', function () {}). Here is how your code would look using .on() wherever possible:
$(document).on('ready', function() {
$(window).on('resize', function() {
// Stuff in here happens on ready and resize.
}).trigger('resize'); // Trigger resize handlers.
});//ready
Here is a demo: http://jsfiddle.net/qMBtP/
Bind it both the load and resize event as below:
$(window).on('load resize', function () {
// your code
});
Much simpler - hope this helps.
In one section of code I have this:
$("#searchbar").trigger("onOptionsApplied");
In another section of code, I have this:
$("#searchbar").bind("onOptionsApplied", function () {
alert("fdafds");
});
The bind() is executed before the trigger(), but when I view the page, I never get an alert().
Why not? What am I doing wrong with events?
Perhaps your #searchbar is not part of the DOM when you execute:
// This will not work if #searchbar is not part of the DOM
// or if the DOM is not ready yet.
$("#searchbar").bind("onOptionsApplied", function () {
alert("fdafds");
});
This type of stuff often happens if .bind() is outside the document ready or because #searchbar is added dynamically.
To make sure onOptionsApplied is bound correctly even under these conditions, use .live() or .delegate():
// This can be outside document ready.
// It binds all now and future #searchbars
$("#searchbar").live("onOptionsApplied", function () {
alert("fdafds");
});
// Document ready
$(function() {
// Whatever you do....
// Make sure #searchbar is now part of the DOM
// Trigger onOptionsApplied
$("#searchbar").trigger("onOptionsApplied");
});
});
jsFiddle example
I also tried it and works fine.
put the bind function in the ready handler and then trigger the event ...it should go smooth