使用ajax加载的json数据,Fadein回调无法正常工作

时间:2014-10-24 19:15:05

标签: javascript ajax json fadein fadeout

这是一个设计组合页面。在加载时,通过ajax检索JSON数据,其中一个密钥用于生成一个' .project-links' (加载时不显示任何项目,仅在选择项目时加载项目图像(请参阅showProj函数))。我的问题是关于fadein / fadeout:尽管在fadeOut回调中定义/加载了项目内容,但在淡入完成后仍然会在屏幕上绘制图像;有人可以请教我如何调整这个,以便fadeIn不会运行直到projImages加载?

谢谢你,svs。

function ajaxReq() {
    var request = new XMLHttpRequest();
    return request;
}


function makeLinks(projects) { // result = getJsonData > request.responseText
    var projectList = document.getElementById("project-list");

    for (var project in projects) {
        if (projects[project].status !== "DNU") {
            var projectId = projects[project].id;
            var listItem = "<li><a class=\"project-link\" id=\""+projects[project].project+"\" href=\"#\">" + projects[project].project + "</a></li>";
            projectList.innerHTML += listItem;
        } // if !DNU
    }

    // ADD EVENT LISTENERS
    var projLink = document.getElementsByClassName("project-link");
    for (var i = 0; i < projLink.length; i++) {
        var projId = projLink[i].id;
        //projLink[i].dataset.projIx = [i];
        projLink[i].addEventListener("click", showProject, false);
    }


    var showNext = document.getElementById("show-next");
    var showPrev = document.getElementById("show-previous");
    showNext.addEventListener("click", showProject, false);
    showPrev.addEventListener("click", showProject, false);

    // ARROW KEYS [not invoking the showProject function]
    $(document).keydown(function(e) {
        if(e.which==37) { // LEFT arrow
            $(showPrev).click(showProject);
            console.log("previous");
        } else
        if(e.which==39) { // RIGHT arrow
            $(showNext).click(showProject);
            console.log("next");
        }
    })


    function showProject(projId) {

        var intro = document.getElementById("intro");
        if (intro) {
            intro.parentNode.removeChild(intro);
        }
        projId.preventDefault();

        var projLinks = document.getElementsByClassName("project-link"); // array

        var selIx = $(".selected").index();


        // ###### CLICK PREVIOUS/NEXT ######
        if (this.id === "show-previous" || this.id === "show-next") {

            // 1a. if nothing is .selected
            if (selIx < 0) {
                if (this.id === "show-previous") {
                    var selIx = projLinks.length-1;
                }
                else if (this.id === "show-next") {
                    var selIx = 0;
                }
            }

            // 1b. if .selected:
            else if (selIx > -1) {
                if (this.id === "show-previous") {
                    if (selIx === 0) { // if @ first slide
                        selIx = projLinks.length-1;
                    }
                    else {
                        selIx --;
                    }
                }
                else if (this.id === "show-next") {
                    if (selIx === projLinks.length-1) { // if @ last slide
                        selIx = 0;
                    }
                    else {
                        selIx ++;
                    }
                }
            }
            var selProjLi = projLinks[selIx]; // => li
        } // click previous/next


        // ###### CLICK .project-link ######
        else if (this.id !== "show-previous" && this.id !== "show-next") {
            var selIx = $(this).closest("li").index();
        }


        // FADE OUT, CALLBACK: LOAD NEW PROJECT
        $("#project-display").fadeTo(450, 0.0, function() {

            // ###### ALL ######
            $(".selected").removeClass("selected");


            var projId = projLink[selIx].id;
            var selProjLi = projLink[selIx].parentElement;
            selProjLi.className = "selected";

            var projectDisplay = document.getElementById("project-display");

            // set vars for the project display elements:
            var projName = document.getElementById("project-name"); // h3
            var projTools = document.getElementById("project-tools");
            var projNotes = document.getElementById("project-notes");
            var projImages = document.getElementById("project-images");

            // disappear the metadata elements 'cause sometimes they'll be empty
            projTools.style.display = "none";
            projNotes.style.display = "none";
            testimonial.style.display = "none";

            for (var project in projects) { // 'Projects array' -> project
                if (projects[project].project === projId) {

                    var activeProj = projects[project];

                    projName.innerHTML = activeProj.project;

                    // maintain centered display of project-metadata: check for a value, else the element remains hidden
                    if(activeProj["tools used"]) {
                        projTools.style.display = "inline-block";
                        projTools.innerHTML = activeProj["tools used"];
                    }
                    if(activeProj.notes) {
                        projNotes.style.display = "inline-block";
                        projNotes.innerHTML = activeProj.notes;
                    }
                    if(activeProj.testimonial) {
                        testimonial.style.display = "inline-block";
                        testimonial.innerHTML = activeProj.testimonial;
                    }

                    // HOW TO ENSURE THESE ARE ALREADY LOADED ***BEFORE #project-display FADES IN***
                    projImages.innerHTML = "";
                    for (var i = 0; i < activeProj.images.length; i++ ) {
                        projImages.innerHTML += "<img src=\"" + activeProj.images[i].url + "\" />";
                    }
                } // if project id ...
            } // for (var obj in data)
        }) // fade out

        $("#project-display").fadeTo(600, 1.0);

    } // showProject
} // makeLinks

function getJsonData() {
    var request = ajaxReq();
    request.open("GET", "/json/projects.json", true);
    request.setRequestHeader("content-type", "application/json");
    request.send(null);
    request.onreadystatechange = function() {
        if (request.readyState === 4) {
            if (request.status === 200) {
                //makeLinks(request.responseText);
                var projects = JSON.parse(request.responseText);
                var projects = projects["Projects"];
                makeLinks(projects); // makeLinks = callback
                return projects;
            }
        }
    } // onreadystatechange
} // getJsonData

getJsonData(makeLinks);

1 个答案:

答案 0 :(得分:0)

您可以向图像添加加载事件,并在加载所有图像时运行fadeOut。

由于您需要多个图像才能完成加载,因此我选择使用jQuery.Deferred()个对象来跟踪哪些加载完成。一旦解决了所有延迟,您就可以运行淡入淡出动画。

这是一个应该有效的功能:

function fadeWhenReady(projImages, images) {
    projImages.innerHTML = "";
    var loads = []; //create holding bin for deferred calls

    //create images and attach load events
    for (var i = 0; i < activeProj.images.length; i++ ) {
        var deferred = $.Deferred();
        var img = $("<img src=\"" + activeProj.images[i].url + "\" />");
        img.on("load", function() { deferred.resolve() }); //after image load, resolve deferred
        loads.push(deferred.promise()); //add the deferred event to the array
        img.appendTo(projImages); //append image to the page
    }

    //when all deferreds are resolved, then apply the fade
    $.when.apply($, loads).done(function() {
        $("#project-display").fadeTo(600, 1.0); 
    });
}

function showProject移除对$("#project-display").fadeTo(600, 1.0);的来电,并通过调用fadeWhenReady功能替换以下行。

projImages.innerHTML = "";
for (var i = 0; i < activeProj.images.length; i++ ) {
    projImages.innerHTML += "<img src=\"" + activeProj.images[i].url + "\" />";
}

P.S。你正在使用jQuery和vanilla javascript的奇怪组合。拨打document.getElementById()的电话不要太在意我,但我当然建议您使用jQuery.ajax()替换XMLHttpRequest