views:

279

answers:

3

I am trying to create a jQuery fadeIn fadeout effect for my page content using the code below.

$(document).ready(function (){
$("#main").click(function(){
    $("#content").fadeOut(800, function(){
        $("#content").load("main.html", function(){
            $("#content").fadeIn(800);
        });
    });
});

$("#gallery").click(function(){
    $("#content").fadeOut(800, function(){
        $("#content").load("gallery.html", function(){
            $("#content").fadeIn(800);
        });
    });
});

});

So whenever a user clicks on either the main link or gallery link, the old content fades out and new content fades in. The problem I am facing is that for every link I have to repeat the same code again and again. So I tried to use a loop to simplify this but it doesn't work. Here is my code:

var p = ["#main","#gallery", "#contact"];
var q = ["main.html", "gallery.html", "contact.html"];
for (i=0;i<=(p.length-1);i++){
    $(p[i]).click(function(){
    $("#content").fadeOut(500, function(){
        $("#content").load(q[i], function(){
            $("#content").fadeIn(500);
        });
    });
});
}

It works fine when I write repeat the scripts for each link but it doesn't work when I combine them in a loop. I only get the FadeOut effect and nothing happens after that.

This might be a very simple issue or may be something deep into jQuery. Any hint or help is greatly appreciated.

TK

A: 

your i variable is always evaluated at 3, which makes q[i] undefined. you'll have to find a way, like a class perhaps to persist the number associated through to the callback.

if it really is just the three links i'd suggest something simpler like a case statement.

switch $(this).attr('id') {
    case 'gallery' : ; break;
    case 'contact' : y; break;
    case 'main' : z; break;
}

and if you're worried about code duplication just write a function that accepts what page to load and call it in each .click()

nathan gonzalez
I would mark this as answer as well.. Thank you Nathan
Tarun
A: 

You have to capture the current value of i or q[i] in a separate closure, like:

function buildChangeOverTo(src)
{
    return function() {
        var content = $("#content");
        content.fadeOut(500, function(){
           content.load(src, function(){
               content.fadeIn(500);
        }});
    }
}

var p = ["#main","#gallery", "#contact"];
var q = ["main.html", "gallery.html", "contact.html"];
for (i=0;i<=(p.length-1);i++) {
    $(p[i]).click(buildChangeOverTo(q[i]));
}

There are tons of information about those strange javascript closures on the web.

Wikser
I understand now.. I guess my javaScript skills are not as good as I thought they were.. Thank you Wikser
Tarun
A: 

I would tackle that problem by adding a class to the links, say fadeLink and I would add a custom attribute to the link like fadeUrl. I would set the link destinations into the fadeUrl attribute on each link and then your document ready code could look like this:

$(document).ready(function (){
    $(".fadeLink").click(function(){
        var jqThis = $(this);
        $("#content").fadeOut(800, function(){
            $("#content").load(jqThis.attr("fadeUrl"), function(){
                $("#content").fadeIn(800);
            });
        });
    });
});

This would side-step the loop and to add or edit links in the future you only have to change the data on the links.

patrickmcgraw
Thanks Patrick..
Tarun