2015-11-06 53 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"); 
});