添加一个DOM/SVG元素与d3 javascript库改变变量引用/范围,为什么

Appending an DOM/SVG element with the d3 javascript library changes variable reference/scope, why?

本文关键字:改变 javascript 变量 引用 为什么 范围 d3 元素 一个 添加 SVG      更新时间:2023-09-26

我注意到当我将DOM/SVG元素添加到现有对象内联和使用D3 javascript库时的单独步骤时,我会得到混合结果。如果我查看引用原始SVG对象的变量,当在创建原始对象期间添加另一个对象时,它会发生变化。下面是一个例子:

var body = d3.select("body");
var svg = body.append("svg")
    .attr("width", '100%')
    .attr("height", '100%')
var html1 = svg.append("foreignObject")
    .attr("x", 50)
    .attr("y", 25)
    .attr("width", 200)
    .attr("height", 100)
    .attr('id', 'fo1')
    .append("xhtml:div")
    .html("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam.");
var html2 = svg.append("foreignObject")
    .attr("x", 250)
    .attr("y", 25)
    .attr("width", 200)
    .attr("height", 100)
    .attr('id', 'fo2');
html2.append("xhtml:div")
    .html("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec eu enim quam.");
console.log('first fo:', html1[0]);
console.log('first fo id:', d3.select('#fo1')[0]);
console.log('second fo:', html2[0]);

输出如下:

first fo: 
   Array[1]
        0: div
        length: 1
        parentNode: html
        __proto__: Array[0]
first fo id: 
  Array[1]
       0: foreignobject#fo1.[object SVGAnimatedString]
       length: 1
       parentNode: html
       __proto__: Array[0]

second fo: 
  Array[1]
     0: foreignobject#fo2.[object SVGAnimatedString]
     length: 1
     parentNode: html
     __proto__: Array[0]

在创建过程中将DIV元素内联地附加到foreignObject元素后,变量从foreignObject变为 DIV 。在额外的步骤中这样做不会改变引用。下面是相应的jsfield谁能给我解释一下,告诉我如何避免它?

D3中append()操作的结果是您刚刚附加的元素。这样你就可以将这些方法链接起来设置属性、内容等。如果不是这种情况,那么您就不能使用.html()函数来设置新附加的div的内容,因为当前对象仍然是父foreignObject

这个行为是故意的,你不能阻止它,除非你修改D3源代码。如果需要保存对所有元素的引用,只需在单独的调用中追加即可。这是

var html1 = svg.append("foreignObject")
    ...
    .attr('id', 'fo1')
    .append("xhtml:div")
    .html(...);

将成为

var html1 = svg.append("foreignObject")
    ...
    .attr('id', 'fo1');
var nested = html1.append("xhtml:div")
    .html(...);