将多个SVG加载到没有DOM追加的javascript数组中

时间:2013-11-19 18:26:31

标签: javascript d3.js

我想做以下事情:

function loadSvg(path) {
  d3.xml(path, 'image/svg+xml', function(xml) {
    return xml.documentElement;
  });
}

d3.json(jsonOfSvgFileNames, function(paths) {
  // paths = ['pathName','pathName2',...]
  var svgList = [];

  for(var p in paths) {
    var path = paths[p],
        svg = loadSvg(path);
    svgList.push(svg);
  }
});

xml.document调用完成后,我遇到d3.xml个对象消失的问题。我知道这个永久性问题可能是其他类型的服务器调用的问题,但我不确定我需要使用哪些关键字来找到答案。

虽然一个答案是按需发出服务器请求,然后在d3.xml调用中将SVG附加到DOM,但这不是我的应用程序的选项。时间在我的应用程序中很重要,甚至300毫秒的等待也是太多了,这就是为什么我更喜欢批量加载。

Ninja-edit:我发现这是因为异步调用,并且对象在加载之前被推入数组。承诺是否可以接受(例如load().then(push))?我没有过多地承诺过承诺。是否有可接受的承诺标准库?

1 个答案:

答案 0 :(得分:1)

承诺确实是要走的路:

var svgs = [];

$.when( loadData('gridList.json') ).then(function(status){
  console.log( status )
  for (var i = 0; i < svgs.length; i ++){
    $("body").append(svgs[i]);
  }
})


function loadSVG(path){
  var dfd = new jQuery.Deferred();
  d3.xml(path, 'image/svg+xml', function(xml) {
    svgs.push( xml.documentElement );
    dfd.resolve("loaded " + path);
  });
  return dfd.promise();
}


function loadData(jsonFile){
  var dfd = new jQuery.Deferred();
  d3.json(jsonFile, function(paths) {
      for( var i = 0; i < paths.length; i++ )
      $.when( loadSVG(paths[i]) ).then( function(status){
        console.log( status );
        if (svgs.length == paths.length)
          dfd.resolve( "All SVGs loaded!" )
      });
  });
  return dfd.promise();
}