Functions on JavaScript/jQuery selectors apply to elements that were on the page before the function is read. For example,
$('.foo').css('color', 'red');
applies to elements with class foo at the time this part of code was read, but do not apply to elements that were inserted later via JavaScript/jQuery functions such as append(), etc. Is there a way to define a hook that applies automatically at the time when an element is inserted?
Using $('.foo') as your selector will match all elements with the foo class whether they've been added after load or not.
For events:
.live() has been removed from newer versions of jQuery so you should use .on(). Here's an example:
$(document).on('click', '.foo', function(){
// click event code here
});
This event will match .foo elements when the page loads as well as any which are loaded via .append(), .html() etc.
UPDATE:
I think I understand what you mean now. There's a plugin called Live Query which should solve your problem. Just include it then use:
$('.foo').livequery(function() {
$(this).css('color', 'red');
});
Here's a working demo: http://jsfiddle.net/5jJAE/
I'm not sure I completely understand your question but let me try and answer.
Dynamic Elements do count!
When you call a method on a JQuery selector it applies to all objects in the DOM that match your selector criteria.
Just to be clear, this includes elements that were added dynamically. For example, take the method "hide" below, applying to a dynamically inserted element.
$('body').append('<h1 id="test" style="display:none;">HI!</h1>');
$('#test').show();
So, it's not that JQuery won't apply to dynamically inserted elements, BUT it just won't apply to elements that don't exist yet. In other words, it won't apply to any elements that are added AFTER your call.
The live() method
However, JQuery does have a clever little method called "live()" which might apply to your needs.
Description: Attach an event handler for all elements which match the current selector, now and in the future.
http://api.jquery.com/live/
Update - live() is deprecated but on() can be used
The replacement to live() is on(). However on() doesn't work quite like live() and to make it work for future elements you have to place an "on" event handler in the PARENT element of future elements.
See this answer for more detailed info: Turning live() into on() in jQuery
Related
I have the following set in my JS:
$('.selector').selectpicker();
When new DOM elements are added to the page, the above method doesn't work on the new DOM elements. I know that, in other cases, I can do the following such that newly added DOM elements work:
$(document).on("click", ".class-here", function() {
});
But how can a method like the first changed to work with new DOM elements (rather than calling that same method again)?
The answer will depend on the function you're calling (here selectpicker).
If you're talking about the bootstrap function, you would do:
$('.selector').selectpicker("refresh");
After having changed the DOM.
You might use the level 3 event for DOM node creation, like .on("DOMNodeInserted",(selector),(function)) to execute your function whenever an element fitting the selector is inserted. See How to catch creation of DOM elements and manipulate them with jQuery
Your problem is regarding binding new element in DOM, Prior version of jquery use bind and unbind method for new element in dom.
But If you use jQuery 1.3+ then you can write
$('selector').live('event',function (){ //do some action });
In above jquery, You didn't need to bind/unbind element on DOM.
But latest version of jQuery 1.7+, You can directly use .on() method which you mentioned above, It mean that you didn't care to bind, unbind on 'DOM change'.
On() is simple that you can write common callback for multiple events on particular selector.
I hope that this details is useful to you and you got your answer. If you use 'on()' then you not need to bind element in DOM.
I have two codes. This one works like a charm-
$("input:radio").on('change',showRatingSection);
But this one throws "Object has no method 'live'" error-
$("input:radio").live('change',showRatingSection);
Any ideas why?
If I assume that you can't call live method on radios, then how would I bind an event on the radios which will be added to my DOM in future? I know I can bind as soon as they get added but I am looking for an alternative to live() if it can't be used with radios.
Use the best method!
$("body").delegate('input:radio','change',function(){
//do code here
});
This work with AJAX, without ajax. I had the similar problem with "live" function too, but since I use this anywhere, I have no problem at all.
You can try this, it's called Event Delegation: elements that are generated dynamically in the DOM you can fire events using the syntax following
$(document.body).on('click', "input:radio", showRatingSection);
and .live() has been deprecated since 1.7 version of jQuery
document.body refers to the closest parent element in the DOM,
Delegate the event:
$(document).on('change', "input:radio", showRatingSection);
"Object has no method 'live'"
Yes because in the latest jQuery versions live has been removed.
I am looking for an alternative to live()
Yes you have an alertnative to this as suggested in this answer and others, with use of .on() it has a special syntax for it.
$(document).on('event', "selector", function);
Note:
Delegating to $(document) is very costly (in terms of performance) so you should always try to delegate to the closest static parent (Which was available at the doc ready).
Also there is a point if you are delegating to the closest static parent you should put that event inside doc ready block but if you are delegating to $(document) then there is no need to put it in doc ready block.
This question already has an answer here:
Difference between remove() and detach() in jQuery [closed]
(1 answer)
Closed 10 years ago.
I m not being able to distinguish between the jquery remove() and detach() method as both are acting same or working same ,plz consider the code:
<script>
$(document).ready(function(){
$("#btn1").click(function(){
$("body").append($("#p1").detach());
});
$("#btn2").click(function(){
$("body").append($("#p2").remove());
});
$("p").click(function(){
$(this).animate({fontSize:"+=1px"})
});
});
</script>
From the docs:
The .detach() method is the same as .remove(), except that .detach() keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.
remove() destroys the element completely. detach() removes the element, keeping its data intact.
The detach method doesn't remove interal jQuery data that are associated with the elements (e.g. event bindings), so it's only if there is any such data that you would see any difference.
To move an element from one place to another in the document, you don't have to remove it or detach it, just append it in the new place:
$("body").append($("#p1"));
You're not going to see a visible difference between the two. This excerpt is taken from the jQuery documentation:
The .detach() method is the same as .remove(), except that .detach() keeps all jQuery data associated with the removed elements. This method is useful when removed elements are to be reinserted into the DOM at a later time.
Please review the API documentation on each of these calls:
jQuery Remove
jQuery Detach
As explained by the documentation, $.detach() retains the associated jQuery data whereas $.remove() removes that data. This data contains things like the bound events, the animation queue and whatever you manually added with $.data().
In your original example, you should be able to notice the difference in the following scenario:
Click the paragraph.
Click the button.
Click the paragraph again.
For #p1 and #btn1, clicking the paragraph the second time will still trigger the click handler and bump the font size. This is because the event handler is stored in the data and is retained by detach(). Thus, when reattaching it to the DOM, the handler is still bound.
For #p2 and #btn2 however, the event handler is removed by remove() and clicking on the paragraph the second time won't do anything.
Side note: you don't need to call detach() when you're immediately appending it to the DOM again. detach() may be interesting if you want to store the element in a variable for a while until it needs to be re-appended (with the same data and behaviour). remove() is commonly used to just destroy an element, also cleaning up any associated data.
Is it better to attach the on() event to the document or a closer parent?
Note: Initially this question had another aspect and a different topic. It became obsolete really quickly (typo in the source code)
The best key for performance using jQuery is to use an id as the initial identifier. For example:
$('#my_id').on('click', 'tag.my_class', function () {
...
});
This allows jQuery to go straight to the container, and then begin trawling from there.
if you bind the "on" event to the closest parent will produce exactly what are you looking for, click function will works fine even if it is appended to document, but in future if you append any elements with class "clickable" will also get binded. so its always good practice to append the "on" event to closest parent rather than whole document.
if you want more specific you can use
$("ul.media-grid").on('click', 'li.clickable', function () {
alert("works")
});
as it will get the ul with the class "media-grid" and appends the event to the li's with class "clickable"
I am trying to hide/show a class of elements in a form depending on a drop-down menu choice made by the user. See: http://jsfiddle.net/3FmHK/2/
I am new to js and have two problems, so maybe they are obvious, bear with me.
1) I am modifying by the div id, so only the first element changes (and not in this fiddle for some reason, but it does in the project). However I want all the elements of a class to modify and I haven't been able to make that work. So how do I modify the style="display" for an entire class, rather than a single element?
2) The remove does not work for newly added element, when the form is returned with values in the project, they are removable. Using firebug, the code looks identical for the GET return generated elements vs the user added elements, as far as I can tell. Why does the remove function not work for newly added elements?
I recommend using jQuery for this if you can. You can use the .on() feature to bind actions ot newly created elements and use the class selector to .hide() all classes then .show() the currently selected on by id.
It would look something like this:
jQuery(document).ready( function() {
jQuery(document).on('click', '.classname', function() {
jQuery('.' + jQuery(this).attr('class') ).hide();
jQuery(this).show();
// Or you can use the following to show a specific ID element.
//jQuery('#idtoshow').show();
)};
});
This will hide all elements with the class name. You will need to include the jQuery library before your script. Although I am only using show and hide here, you can use .remove() as long as you bind your action with .on and not just .click. You need .on to bind to newly created elements.
http://api.jquery.com/on/
Hope this helps.
Try:
$(this).parent('div').first().remove();