我有一个特殊的问题。 我正在加载一个JSON文件,其中包含许多图像的src,宽度和高度。
我正在尝试将它们加载到平滑的脚本jquery插件中,并让图像自动滚动。
“观看区域”div可以并排放置三个图像。
首次加载页面时,仅显示第一张图像。如果我重新加载它,显示前三个图像,其他(总共有11个)被加载,但插件不滚动,所以你看不到它们。
当我在$(window).one函数中插入一个警告(“what”)行时,一切正常。
我怀疑它会在加载图像和触发.load事件时与之有关。
以下是解析JSON文件并创建附加到可滚动div的HTML字符串的代码:
var aSectionImages = new Array;
var aImagesCount = new Array();
var aImagesLoaded = new Array();
var htmlString;
var jsonStyleImages = "images.json"
var jsonNavImages = "imagesNav.json";
var scrollableArea = $("#scrollableArea");
$.getJSON(jsonNavImages, getNavIcons);
$.getJSON(jsonStyleImages, makeScroller);
function imageLoaded(imgSrc){
var locId = (imageInSection(imgSrc)).replace(/\s|'/g, "_");
if (aImagesLoaded[locId]===undefined){
aImagesLoaded[locId] = 0;
};
aImagesLoaded[locId] = aImagesLoaded[locId]+1;
if (aImagesLoaded[locId]==aImagesCount[locId]){
//alert("section" + locId);
//$("#loaded").html(locId);
//aSectionLoaded = {locId:"loaded"};
//in theory, wait until all images in a section are loaded before
//appending the HTML to the div:
scrollableArea.append(htmlString);
}
}
function imageInSection(src){
var resultId=false;
var locSrc = src.split("/");
var locFileName = (locSrc[locSrc.length-1]);
for (i = 0; i < aSectionImages.length; i++){
for(j=0; j < aSectionImages[i].images.length; j++){
tempSrc = aSectionImages[i].images[j].src.split("/");
tempFileName = tempSrc[tempSrc.length-1];
if (tempFileName == locFileName) {
resultId = aSectionImages[i].id;
}
}
}
return resultId;
}
function makeScroller(data){
aSectionImages = data;
for (i=0; i<aSectionImages.length;i++){
locData = aSectionImages[i];
locId = locData.id.replace(/\s|'/g, "_");
aImagesCount[locId] = locData.images.length;
htmlString = "<div id=\"" + locId + "\">";
for (j=0; j<locData.images.length; j++){
oImage = new Image();
$(oImage)
.load(function(){
imageLoaded(this.src);
})
.attr("src", locData.images[j].src);
if (oImage.complete && oImage.naturalWidth !== 0){
$(this).trigger("load");
//$("#trigger").html(locData.images[j].src);
//return false;
}
locImage = locData.images[j];
locImage.id ? locImage.id = " id=\""+locImage.id+"\" " : locImage.id = "";
htmlString += "<img height=\"" + locImage.height + "\"" + " width=\"" + locImage.width + "\"" + locImage.id + " src=\"" + locImage.src + "\" />";
}
}
}
这是插件的一部分,用于在加载时显示图像:
//加载时做一次 $(窗口)。一( “负载”,函数(){ // alert(“如果我在这里包含警报,为什么会有效?”);
// If the content of the scrolling area is not loaded through ajax,
// we assume it's already there and can run the code to calculate
// the width of the scrolling area, resize it to that width
if(options.ajaxContentURL.length === 0) {
$mom.scrollableAreaWidth = 0;
$mom.tempStartingPosition = 0;
$mom.find(options.scrollableArea).children().find("img").each(function() {
// Check to see if the current element in the loop is the one where the scrolling should start
if( (options.startAtElementId.length !== 0) && (($(this).attr("id")) == options.startAtElementId) ) {
$mom.tempStartingPosition = $mom.scrollableAreaWidth;
}
// Add the width of the current element in the loop to the total width
$mom.scrollableAreaWidth = $mom.scrollableAreaWidth + $(this).outerWidth(true);
});
// Set the width of the scrollableArea to the accumulated width
$mom.find(options.scrollableArea).css("width", $mom.scrollableAreaWidth + "px");
// Check to see if the whole thing should be hidden at start
if(options.hiddenOnStart) {
$mom.hide();
}
}
// Set the starting position of the scrollable area. If no startAtElementId is set, the starting position
// will be the default value (zero)
$mom.find(options.scrollWrapper).scrollLeft($mom.tempStartingPosition);
// If the user has set the option autoScroll, the scollable area will
// start scrolling automatically
if(options.autoScroll !== "") {
$mom.autoScrollInterval = setInterval(autoScroll, $mom.autoScrollDelay);
}
// If autoScroll is set to always, the hot spots should be disabled
if(options.autoScroll == "always")
{
hideLeftHotSpot();
hideRightHotSpot();
}
// If the user wants to have visible hot spots, here is where it's taken care of
switch(options.visibleHotSpots)
{
case "always":
makeHotSpotBackgroundsVisible();
break;
case "onstart":
makeHotSpotBackgroundsVisible();
$mom.hideHotSpotBackgroundsInterval = setInterval(hideHotSpotBackgrounds, (options.hotSpotsVisibleTime * 1000));
break;
default:
break;
}
});
完整的代码是 http://chereecheree.com/dagworthy/style.html
您会注意到,如果您重新加载页面,它会按预期工作,但如果您按照链接进行操作 一级(dagwothy /),只加载第一个图像,除非在加载时抛出alert语句。
感谢您抽出宝贵时间来研究这个问题! --Daniel。
答案 0 :(得分:3)
我认为你的问题在这里,或者至少是我看到的第一个问题:
oImage = new Image();
$(oImage).load(function(){
imageLoaded(this.src);
}).attr("src", locData.images[j].src);
if (oImage.complete && oImage.naturalWidth !== 0){
$(this).trigger("load");
}
在这种情况下this
不是oImage
(就像在.each()
中一样),它是文档,所以你要解雇{ {1}}在错误的元素上,您需要改为$(oImage).trigger("load")
或$(oImage).load()
。
您尝试处理的情况,手动触发load
因为并非所有浏览器在从缓存加载图像时触发它都是正确的想法...您只需要在正确的元素上触发事件,否则这种情况永远不会成立,因为所有这些图像都没有load
事件来增加计数:
load
if (aImagesLoaded[locId]==aImagesCount[locId]){
给图像加载时间,所以一切都准备就绪,然后其他任何东西继续......这本身就会抛出你窗外的任何竞争条件,所以当发生这种情况时,通常要么a)一些依赖得到之前没有时间的加载,或者b)抛出一些事件顺序,给第一次加载...这通常也是一部分。