0

I need some help. I am trying to iterate through some Json items, create some li's with some information from the items, but also attach click handlers for the li's, but with a value transmited as parameter.

The problem is that the last value of that parameter is set for or the li's in the list. From what i searched i understood that it has something to do with javascript closure, but can't seem to understand how to fix it.

I am using jQuery and here is the code:

for (var i = 0; i < items.length; i++)
{
    // information that will be displayed for each video
    var entry = items[i];

    var title = entry.title;
    var image = entry.thumbnail.hqDefault;
    var id = entry.id;

    var li = $("<li class='video-single'>");
    li.append("<img src='" + image + "' alt='" + title + "'>");
    li.append("<h4>" + title + "</h4>");

    $(li).click(function() {
        displayPopUp(id);
    });

    ul.append(li);
}

Could anyone please help me fix this code?

Best regards, Marius.

1
  • $(li) means nothing, perhaps you wanted $('li')? I mean.. you're doing it wrong, jQuery expects a class or an element, not an entire tag. var li = $("<li class='video-single'>"); should simply be $('.video-single') :) and, at this point $(li) can be replaced with li ;) Commented Aug 7, 2014 at 18:53

3 Answers 3

1

The issue is that JS is function scoped so the id within your closure is the last id from your for loop. To fix this use forEach so you run each iteration of your loop in a separate scope e.g.

items.forEach(function (el, i) {
    // information that will be displayed for each video
    var entry = items[i];

    var title = entry.title;
    var image = entry.thumbnail.hqDefault;
    var id = entry.id;

    var li = $("<li class='video-single'>");
    li.append("<img src='" + image + "' alt='" + title + "'>");
    li.append("<h4>" + title + "</h4>");

    $(li).click(function() {
        displayPopUp(id);
    });

    ul.append(li);
});
Sign up to request clarification or add additional context in comments.

1 Comment

No problem, if you want to learn more about js scope and the language itself. I'd recommend looking at a few videos by Douglas Crockford or reading his book JavaScript:The Good Parts.
1

you need delegated event as elements are created dynamically, you can use class that is being added on li which is video-single:

$(document).on('click','.video-single',function() {
                        displayPopUp(id);
                    });

you can read about Delegated Events HERE

Comments

0

in order to bind an event to a dynamically added element you need to delegate it as below:

for (var i = 0; i < items.length; i++)
            {
                // information that will be displayed for each video
                var entry = items[i];

                var title = entry.title;
                var image = entry.thumbnail.hqDefault;
                var id = entry.id;

                var li = $("<li class='video-single'>");
                li.append("<img src='" + image + "' alt='" + title + "'>");
                li.append("<h4>" + title + "</h4>");

                $(document).bind('click',li,function() {
                    displayPopUp(id);
                });

                ul.append(li);
            }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.