Crazywako
Crazywako

Reputation: 362

jQuery / JS: looping function load

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

Answers (4)

Jivings
Jivings

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

charlietfl
charlietfl

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

Amadan
Amadan

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

Josh Marthaller
Josh Marthaller

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

Related Questions