【问题标题】:Manipulate external XML files after they have been loaded加载外部 XML 文件后对其进行操作
【发布时间】:2014-10-28 12:20:03
【问题描述】:

我已经使用 d3.xml() 和 queue.js 库加载了几个外部 SVG 文件。我可以使用以下代码 (JSFiddle) 在加载每个文件时对其进行操作(更改其位置和颜色):

var width = 300, height = 300;
var sampleSVG = d3.select("body")
    .append("svg")
    .attr( {width: width, height: height} );

var shapes = [
  { url: "https://dl.dropboxusercontent.com/u/2467665/shapes-24.svg", color: 'purple' },
  { url: "https://dl.dropboxusercontent.com/u/2467665/shapes-23.svg", color: 'red' }
];

var q = queue();
shapes.forEach(function(shape) { 
  q.defer(d3.xml, shape.url, "image/svg+xml"); 
});

q.awaitAll(function(error, results) { 
  sampleSVG.selectAll('g.shape').data(shapes)
    .enter().append('g').attr('class', 'shape')  
    .attr('transform', function() {
      return 'translate(' + Math.random()*(width-50) + ',' + Math.random()*(height-50) + ')'
    })
    .each(function(d,i) {
      this.appendChild(results[i].documentElement);
      d3.select(this).select('svg').select("*")
        .attr("transform", "scale(0.2)")
        .attr("stroke", function() { return d.color; });
    })
});

我想在它们全部加载后访问这些形状,就像普通的 d3 对象一样。比如上图读进去之后,我想执行一个简单的过渡让它们全黑:

sampleSVG.select(".shape svg *").transition().delay(1000).attr("stroke", "black");

但这不起作用。

如何读取这些外部 SVG 文件,以便像平常一样进行操作?

【问题讨论】:

  • 您正在尝试更新 q.awaitAll 函数之外的颜色。这意味着 sampleSVG.select(...) 行将在 DOM 中存在形状之前运行。尝试在 q.awaitAll 函数中移动它,就像在 jsfiddle.net/hk367c5q 中一样,你应该没问题。
  • @BenLyall 是的,这行得通,但问题是我还有很多其他不涉及这些形状的动态事情正在发生。我想让所有东西都“在引擎盖下”加载,然后启动动态链,就好像这些是正常的 d3 生成的形状一样。
  • 当然...这很有意义,您只需要延迟调用 sampleSVG.select(...) 行,直到您完成对 DOM 的操作。就目前而言,在 SVG 元素出现之前,您调用它还为时过早。
  • 有没有办法确定我何时完成了对 DOM 的操作,以便只有在返回 true 时才能启动 sampleSVG.select(...) 行等?
  • 这在很大程度上取决于您的设置。如果它像在您的 jsfiddle 中那样简单,只需将 sampleSVG.select(...) 行包装在一个函数中,然后从 q.awaitAll 的末尾调用该函数。如果您有一组复杂的函数都在操纵 DOM,那么您将需要某种方式来跟踪一切何时完成。提示:您已经在使用的队列库绝对可以帮助您解决这个问题。

标签: javascript jquery svg d3.js


【解决方案1】:

您正在尝试在创建 SVG 形状之前更新它们的颜色。如果你移动了

sampleSVG.select(".shape svg *").transition().delay(1000).attr("stroke", "black");

在q.awaitAll(...) 函数中,它会在 DOM 中创建形状后运行,并且选择将起作用。

任何延迟调用的方法

sampleSVG.select(".shape svg *").transition().delay(1000).attr("stroke", "black");

直到您的 DOM 操作完成后才能正常工作。您可以将其包装在一个函数调用中,并在 q.awaitAll(...) 的末尾调用该函数,或者您可以额外使用 queue 库,以与您当前使用它类似的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多