Reputation: 362
On site: http://jonirautiainen.net/code_edit/ there on left is a panel which has a filetree.
.load('scandDir.php') loads new <ul><li></li></ul>
elements from php-file.
The problem is that because this script is a loop it executes loadNew(); multiple times. Please check the problem live on page mentioned before. Click on those folders to open them and you will see those files showing up multiple times.
Script needs to be looped because .load is asynchronous. $(".file-tree a").on(
won't let me select those new elements created by executing .load.
Is there any other way to do this?
function loadNew()
{
$(".file-tree a").on("click",function ()
{
var path = $(this).attr("title");
var folder = $(this).text();
var name = $(this).attr("name");
var id = $(this).parent().attr("id");
$("#testi").html(path + folder + name + id);
var liHtml = $(this).parent().html();
if(liHtml.match(/<ul /))
{
}else
{
if(name=="dir")
{
$("#hiddenDiv1").load("scanDir.php?path=" + path + "/" + folder, function() {
var hiddenDiv = $("#hiddenDiv1").html();
$("#" + id).append(hiddenDiv);
loadNew();
});
}
}
});
}
loadNew();
Upvotes: 2
Views: 99
Reputation: 23250
It looks to me like every time a .file-tree
link is clicked it will be attaching a new click
handler to all of the .file-tree
elements. You just want to attach to the new elements. So perhaps change to something like this:
var expand = function() {
var path = $(this).attr("title");
var folder = $(this).text();
var name = $(this).attr("name");
var id = $(this).parent().attr("id");
$("#testi").html(path + folder + name + id);
var liHtml = $(this).parent().html();
if(liHtml.match(/<ul /)) {
}
else
{
if(name=="dir")
{
$("#hiddenDiv1").load("scanDir.php?path=" + path + "/" + folder, function() {
var hiddenDiv = $("#hiddenDiv1").html();
$("#" + id).append(hiddenDiv);
});
}
}
};
$('#fileNavi').on('click', '.file-tree a', expand);
EDIT:
on
will effect all elements added to the DOM as well as existing elements.
Upvotes: 1
Reputation: 171669
Your loadNew function is binding a new click handler to $(".file-tree a") every time you call it.
1 click, one load, 3 clicks.. 3 clcik handlers, 3 loads. Delegate the click handler to parent of the list.
$("#fileNavi ").on("click",'.file-tree a',function ()
loadNew();
})
EDIT: will require some reformatting of loadNew , you could pass "this"
into load new as an argument so you can get all the variables from the element clicked
Upvotes: 1
Reputation: 198324
You keep piling on new click handlers. I understand that you're loading new elements and they need to have their events handled too, but in the process you're adding more handlers to the existing elements. So after you expand several directories, the older elements will have a couple of handlers on them; and when you click those, all of those handlers will get invoked (which gets you additional elements).
One approach is to take care what you add your click handler to. Only add it to the newly loaded elements.
Another, easier approach is to take advantage of the power of jQuery's on() method. If you write it like this:
$('#fileNavi').on('click', '.file-tree a', function() {
...
});
and only once, the handler will work for current and any future elements that appear in your hierarchy. Then inside the handler just do the AJAX call and add the new data to the document, trusting jQuery to handle the events for you. Get rid of the loadNew
function altogether, especially the deviant recursion you have going there.
Upvotes: 1
Reputation: 33
you probably just need to add some parameters to "loadNew()" so it knows exactly what to do and not repeat itself.
Upvotes: 0