这是一个设计组合页面。在加载时,通过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);
答案 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
。