2014-10-24 11 views
0

디자인 포트폴리오 페이지입니다. 로드시 JSON 데이터가 ajax를 통해 검색되고 키 중 하나가 '.project-links'목록을 생성하는 데 사용됩니다 (로드시 프로젝트가 표시되지 않고 프로젝트가 선택 될 때만 프로젝트 이미지가로드됩니다 showProj 함수 참조)). 제 질문은 fadein/fadeout에 관한 것입니다. fadeOut 콜백 내에서 프로젝트 내용이 정의되거나로드되었지만 페이드 인이 완료된 후에도 이미지가 화면에 계속 페인트됩니다. 누군가가 projImages가로드 될 때까지 fadeIn이 실행되지 않도록 어떻게 조정할 수 있는지에 대해 나에게 알려줄 수 있습니까?아약스로드 된 json 데이터로 Fadein 콜백이 제대로 작동하지 않습니다.

감사합니다. 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() 개체 배열을 사용하여 완료된로드를 추적하기로했습니다. 모든 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. JQuery와 바닐라 자바 ​​스크립트의 이상한 조합을 사용하고 있습니다. document.getElementById()에 대한 전화는별로 신경 쓰지 않지만, XMLHttpRequestjQuery.ajax()으로 바꾸는 것이 좋습니다.

+0

감사합니다. Dave 님, 감사드립니다. 나는 훨씬 더 빨리 반응했을 것이다. 그러나 나는 2011 맥북 프로의 운이 좋지 않은 주인이다. 그래서 나는 재시작하는 데 많은 시간을 낭비한다. – user1613163

+0

귀하의 도움에 관해서는 먼저, 헤드 업에 감사드립니다. 그러나 나는 그것의 요지를 얻는다라고 생각한다. 그러나 나는 범위 혼란을 경험하고있다. fadeWhenReady 함수가 정확히 어디에 있어야합니까? 그리고 js와 jq의 혼합에 관해서는 js (나는 몇 가지 jQ를 알고 있습니다)를 배우면서 jQ의 사용을 최소화하려고합니다. 그러나 편의와 단순성을 위해 클래스 조작과 페이드 (fades)를 위해 jQ를 사용하고 있습니다. btw는 나중에 고려해야 할 사항이며 jQ를 적절하게 사용하는 것처럼 보입니다. 본질적으로 내 무지는 ajax/json을 통해로드되는 요소를 어떻게 페이드하는 것입니다. 추가 도움을 주셔서 다시 한 번 감사드립니다. – user1613163

+0

범위 지정 문제가있는 이유는 분명하지 않습니다. 새 함수를'ajaxReq','makeLinks','getJsonData' 함수와 같은 레벨에 넣으려고합니다. – dave