views:

40

answers:

2

I'm having a problem with elements added with appendTo() not being immediately available in the DOM.

First, I'm reading some data from a JSON file and then appending some html to a div. Then I'm calling a random shuffler plugin to show one of the added divs at a time.

    jsonUrl = "js/performers.json";

    $.getJSON(jsonUrl, function(json) {
        $.each(json.performers, function(i, performer) {
            var html = '<div class="performer_mini">';
            html += '<img src="' + performer.thumbnail + '" alt="' + performer.name + '" /><br />';
            html += performer.name + '<br /></div>';
            $(html).appendTo("div#performer_spotlight");
        });
    });

    $("#performer_spotlight").randomShuffler(".performer_mini", 3000, 3000, 9000);

The random shuffler does the following:

(function($) {
    $.fn.randomShuffler = function(shuffledElements, fadeInTime, fadeOutTime, timeout) {
        fadeInTime = fadeInTime || 3000;
        fadeOutTime = fadeOutTime || 3000;
        timeout = timeout || 9000;

        $(shuffledElements).hide();

        var $old_element;
        var $new_element;
        var old_index = 0;
        var new_index = 0;

        function shuffleElement() {
            $old_element = $new_element;
            old_index = new_index;
            while ($(shuffledElements).length > 0 && old_index == new_index) { // don't display the same element twice in a row
                new_index = Math.floor(Math.random()*$(shuffledElements).length);
            }
            $new_element = $(shuffledElements + ":eq(" + new_index + ")");
            if ($old_element != undefined) {
                $old_element.fadeOut(fadeOutTime, function() {
                    $new_element.fadeIn(fadeInTime);
                });
            } else {
                $new_element.fadeIn(fadeInTime);
            }
            setTimeout(shuffleElement, timeout);
        }

        $(this).show();
        shuffleElement();
    }
})(jQuery);

The first time the shuffleElement() function is called $(shuffledElements).length equals 0, so no element is displayed. On the next call to shuffleElement(), the elements added with appendTo() are available and one is selected at random as expected. Everything works correctly after that.

Is there some way to refresh the DOM or make these elements available to jQuery immediately after I add them with appendTo()? Any other suggestions for how to accomplish this?

+2  A: 

When exactly do you call randomShuffler? You call this function after the AJAX-request succeeds? I have always believed that the element added by appendTo available immediately after the addition.

This code works very well for me:

<script language="javascript">
    var test = "<div class=\"test\">1</div>";
    $(test).appendTo("div#performer_spotlight");
    $("div.test").html("<b>Hello</b>");
</script>
MeF Corvi
Yes. I'm calling it after. I edited the code block above to show what it looks like in my js file.
Craig M
+1  A: 

Yes, like @MeF Convi says you need to call the plugin only after the getJSON finishes:

$.getJSON(jsonUrl, function(json) {
    $.each(json.performers, function(i, performer) {
        var html = '<div class="performer_mini">';
        html += '<img src="' + performer.thumbnail + '" alt="' + performer.name + '" /><br />';
        html += performer.name + '<br /></div>';
        $(html).appendTo("div#performer_spotlight");
    });
    $("#performer_spotlight").randomShuffler(".performer_mini", 3000, 3000, 9000);
});
Pointy