jQuery doesn't find dynamically added DOM objects?
Question
I am very new at jQuery ... I've used Javascript many times and am quite familiar with DOM manipulation but simply not the API or gears of jQuery.
I am dynamically adding DOM elements via a JSON call like so:
$(document).ready(function() {
var url = "jsonMenuItems.js";
$.getJSON(url, null, function(data) {
var html = "";
//alert(data.items);
data = data.items;
for (var key in data) {
html += "<td class=\"menuItem\"><span>" + data[key].name + "</span></td>";
};
$("#menuTR").html(html);
});
var lZeroArray = $("#menu td");
lZeroArray.click(function() {
$("#submenu").slideDown("fast");
});
});
If the TD items are on the page manually the click function slideDown works perfectly ... if I use the above code to dynamically add the TD items then the click function slideDown does not fire.
jQuery cannot find it's own added items or am I doing something wrong?
Solution
Take a look at jQuery live. This will let you bind events to dynamically added items.
$("#menu td").live("click", function(){
$("#submenu").slideDown("fast");
});
OTHER TIPS
the problem is: your event handler is bound to $('#menu td')
, but at the time that this is done, there are no td
s in the #menu
!
using live()
makes sure that jquery adds event handlers to objects added later on to the DOM.
Alternatively, a solution used in older jquery versions would be:
var url = "jsonMenuItems.js";
$.getJSON(url, null, function(data) {
var html = "";
//alert(data.items);
data = data.items;
for (var key in data) {
html += "<td class=\"menuItem\"><span>" + data[key].name + "</span></td>";
};
$("#menuTR").html(html);
$("#menu td").click(function() {
$("#submenu").slideDown("fast");
});
});
var lZeroArray = $("#menu td");
lZeroArray.click(function() {
$("#submenu").slideDown("fast");
});
It looks like you're adding the click event to the wrong elements. You're adding the dynamically added TDs to an element with id="menuTR", but you're setting the click event on TD elements that are descendants of id="menu"
To test, try changing $("#menu td") to $("#menuTR td"), or vice versa. Alternately, you could try selecting the elements with $("td.menuItem"), which selects all TD elements with a class of menuItem.
That is because you have to reapply the click functionality to them after they are created:
$.getJSON(url, null, function(data) {
var html = "";
//alert(data.items);
data = data.items;
for (var key in data) {
html += "<td class=\"menuItem\"><span>" + data[key].name + "</span></td>";
};
$("#menuTR").html(html);
$("#menu td").click(function() {
$("#submenu").slideDown("fast");
});
});