2014-10-24 1 views
0

Это страница портфолио дизайна. При загрузке данные JSON извлекаются через ajax, а один из ключей используется для создания списка «.project-links» (ни один проект не отображается при загрузке, а изображения проекта загружаются только при выборе проекта (см. функцию showProj)). Мой вопрос касается fadein/fadeout: изображения по-прежнему окрашиваются на экран после завершения затухания, несмотря на то, что содержание проекта определяется/загружается в обратном вызове fadeOut; может кто-нибудь, пожалуйста, просветит меня о том, как я могу настроить это, чтобы fadeIn не запускался до загрузки projImages?Обратный вызов Fadein не работает должным образом с данными json, загруженными ajax

Спасибо, 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); 

ответ

0

Вы можете добавить событие загрузки к изображениям и запустить fadeOut при загрузке всех изображений.

Поскольку для полной загрузки вам понадобится несколько изображений, я решил отслеживать, какие нагрузки завершены, используя массив из jQuery.Deferred() объектов. Как только все Отложенные решения будут разрешены, вы можете запустить анимацию fade.

Вот функция, которая должна работать:

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() не против меня так сильно, но я бы рекомендовал заменить XMLHttpRequest с помощью jQuery.ajax().

+0

Спасибо Дэйв, очень ценится. Я бы ответил гораздо раньше, но я не такой счастливый обладатель MacBook Pro 2011 года, поэтому я теряю много часов, перезагружаясь. – user1613163

+0

Что касается вашей помощи: во-первых, спасибо за хедз-ап re: .Deferred; Я думаю, что я понимаю суть этого, но я испытываю путаницу в сфере; где именно должна существовать функция fadeWhenReady? И что касается моего сочетания js & jq: я изучаю js (я знаю некоторый jQ), пытаясь свести к минимуму использование jQ. Но в интересах целесообразности и простоты я использую jQ для манипуляций классов и fades, которые, кстати, были запоздалой мыслью и казались подходящим использованием jQ. По сути, мое невежество заключается в том, как угасать элементы, которые загружаются через ajax/json. Еще раз спасибо за любую дальнейшую помощь. – user1613163

+0

Это не очевидно для меня, почему у вас проблемы с обзором. Я бы поставил новую функцию на том же уровне, что и функции 'ajaxReq',' makeLinks' и 'getJsonData'. – dave