2015-11-06 20 views
1
JSON文件之前加载

所以我有以下问题: 我有,我用了不同的操作循环来填充数据的另一个JSON这种方法的getJSON。在该循环中,我尝试获取所有图像文件的尺寸(存储在第一个json中,并使用它们的src),并将它们添加为第二个json中的另一个属性。 为此我使用下面的代码:有道等待所有图像填充数据

$.getJSON("json.txt", function(myJsonData) { 
     var elemID, elemType, elemURL, thumb, date, menuItem, imgH, imgW; 

     for (key in myJsonData) { 

      /*---Some operations for giving values all the variables---*/ 

      //Getting image dimensions 
      var tempImg = new Image(); 
      tempImg.onload = function() { 
       imgW = this.width; 
       imgH = this.height; 
       console.log(imgW + 'x' + imgH); 
       loaded += 1; 
      } 
      tempImg.src = elemURL; 

      //Filling the new json 
      var newJsonData = { 
       "elemID": 'elemID_' + elemID, 
       "type": elemType, 
       "url": elemURL, 
       "thumbnail": thumb, 
       "menuItem": menuItem, 
       "date": date, 
       "W": imgW, 
       "H": imgH 
      } 
     } 
    } 

之后,我有一个函数生成html代码创建我的页面的DOM。 问题是 - 新JSON没有等待的onload功能,我无法通过图像的尺寸。我正在考虑使用超时或其他方式,但我不确定这是一种好的做法。 :/希望你们能帮忙。

+0

凡'data'定义? – guest271314

+0

您在'for..in'循环中加载**相同的图像**。这是你的意图吗? – hindmost

+0

的数据,而不是尝试使用myJsonData像(在myJsonData键) –

回答

1

尝试制作含有newJsonData,其中newJsonData定义和推迟对象内imgonload处理程序解决的jQuery推迟对象的数组;从$.getJSON()返回包含延迟对象数组的新承诺对象。

注意,不是某些地方

var elemID, elemType, elemURL, thumb, date, menuItem, imgH, imgW; 

被设置为undefined其他值?

$.getJSON("json.txt", function(myJsonData) { 
     var elemID, elemType, elemURL, thumb, date, menuItem, imgH, imgW 
     , arr = []; 

     for (key in myJsonData) { 

      /*---Some operations for giving values all the variables---*/ 

      //Getting image dimensions 
      var tempImg = new Image(); 
      tempImg.onload = function() { 
       imgW = this.width; 
       imgH = this.height; 
       console.log(imgW + 'x' + imgH); 
       loaded += 1; 
       var dfd = new $.Deferred(); 
       //Filling the new json 
       var newJsonData = { 
        "elemID": 'elemID_' + elemID, 
        "type": elemType, 
        "url": elemURL, 
        "thumbnail": thumb, 
        "menuItem": menuItem, 
        "date": date, 
        "W": imgW, 
        "H": imgH 
       }; 
       arr.push(dfd.resolve(newJsonData)) 
      } 
      tempImg.src = elemURL; 

     }; 
     // $.when.apply($, arr).then(function() { 
     // do stuff with `newJsonData` objects 
     // console.log(arguments) 
     // }) 
     return $.when.apply($, arr) 
    }) 
1

这里有一些伪代码可能会帮助你 - 我强烈建议使用库来实现这一点。在我的示例中,我使用async,特别是parallel函数。

var elems = document.querySelectorAll("img"); 
var fns = Array.prototype.map.call(elems, function(current){ 

/* 
    get image dimensions here, using the "current" argument 
    make sure to return a function that takes a callback (async expects this) 
    the callback itself takes two args, first is the error object, 
    the second will be the dimension data 
*/ 
    current.onload = function() { 
     var dimensionData = { w: current.width, h: current.height }; 
     return function(callback){ 
      callback(null, dimensionData); 
     } 
    } 
}); 

/* 
    fns will now be an array of functions that take a single callback 
    async will process all of these functions in parallel and, 
    once they're all complete, will call its own callback. in your case, 
    results will be an array of dimensional data for each of your images and, 
    now that you know they've all loaded, can safely write it to the JSON 
*/ 

async.parallel(fns, function(err, results){ 
    writeToJson(JSONData); 
}); 

将尽快用完整的例子来更新这个例子。现在有点忙。

+0

您是否曾经找到解决方案OP? –

1

你可以使用一个jQuery promise()做到这一点:

$('<img/>', { src : elemURL }).promise().done(function(img) { 
    //give some time to populate attributes to img 
    setTimeout(function() { 
     console.log(img[0].width, img[0].width); 
    }, 200);  
}) 

演示 - >http://jsfiddle.net/udfs8e24/

超时是给浏览器一段时间来填充属性的虚拟图像。没有这个,img[0].width,img[0].width有时将返回0,0即使您可以看到img实际上如果安慰它有一个宽度和高度。所以,而不是你的代码可能是这样的:

$('<img/>', { src : elemURL }).promise().done(function(img) { 
    setTimeout(function() { 
     var newJsonData = { 
      "elemID": 'elemID_' + elemID, 
      "type": elemType, 
      "url": elemURL, 
      "thumbnail": thumb, 
      "menuItem": menuItem, 
      "date": date, 
      "W": img[0].width, 
      "H": img[0].height 
     } 
    }, 200) 
}) 
1

我不是100%确定你的问题,但也许这可能有所帮助。 进程JSON文字,然后用一个推迟到处理结果...可能需要一些定制,但应该给你一个例子来立足。

// makeClass - By Hubert Kauker (MIT Licensed) 
// original by John Resig (MIT Licensed). 
function makeClass() { 
    var isInternal; 
    return function (args) { 
     if (this instanceof arguments.callee) { 
      if (typeof this.init == "function") { 
       this.init.apply(this, isInternal ? args : arguments); 
      } 
     } else { 
      isInternal = true; 
      var instance = new arguments.callee(arguments); 
      isInternal = false; 
      return instance; 
     } 
    }; 
} 
var ImagesClass = makeClass(); 
ImagesClass.prototype.init = function (elemID, elemType, elemURL, thumb, menuItem, adate, imgW, imgH) { 
    this.elemID = 'elemID_' + elemID; 
    this.type = elemType; 
    this.url = elemURL; 
    this.thumbnail = thumb; 
    this.menuItem = menuItem; 
    this.date = adate; 
    this.W = imgW; 
    this.H = imgH; 
    this.newJsonData = { 
     "elemID": this.elemID, 
      "type": this.type, 
      "url": this.url, 
      "thumbnail": this.thumbnail, 
      "menuItem": this.menuItem, 
      "date": this.date, 
      "W": this.W, 
      "H": this.H 
    }; 
}; 

var myimages = []; 
var dfd = new $.Deferred(); 
dfd.done(function (imagearray) { 
    //do something to process the array of images here - they are loaded in imagearray 
}); 

var jqxhr = $.getJSON("json.txt"); 
jqxhr.done(function (myJsonData) { 
    // HUGE assumption on my part that each myJsonData in json.txt contains each of these with these name: 
    // elemID, elemType, elemURL, thumb, date, menuItem, imgH, imgW 
    var obj = jQuery.parseJSON(myJsonData); 

    jQuery.map(obj, function (n, i) { 
     var myImageObj = ImagesClass(n.elemID, n.elemType, n.elemURL, n.thumb, n.date, n.menuItem, n.imgH, n.imgW); 
     myimages.push(myImageObj.newJsonData); 
     dfd.resolve(myimages); 
    }); 

}); 
jqxhr.fail(function() { 
    console.log("error"); 
}); 
jqxhr.always(function() { 
    console.log("complete"); 
});