示例 fiddle :https://jsfiddle.net/tomaskafka/w1acm8ox/
这是我的更新循环:
var output = d3.select('#output')
.selectAll('p')
.data(data)
;
output
.enter()
.append('p')
.call(function(parent) {
parent.append('a')
});
;
output
.exit()
.remove()
;
// PROBLEM: at this point, element addded right now isn't selected, and so it's attr and text isn't set.
output
.select('a')
.attr('href', function(d) { return 'http://www.google.com?q=' + d; })
.text(function(d) { return d; })
;
你能帮忙吗?我知道由于某些优化,d3 不会立即更新 DOM,那么添加嵌套元素并在更新时设置其属性的正确方法是什么?
谢谢!
最佳答案
您没有正确使用更新、进入、退出模式。
您输入的选择已附加:
output
.enter()
.append('p')
.call(function(parent) {
parent.append('a')
});
但是,你会在这里遇到问题:
output
.select('a')
.attr('href', function(d) { return 'http://www.google.com?q=' + d; })
.text(function(d) { return d; })
;
只有创建选择时存在的元素才会更新。因此,您新创建的元素(输入选择的一部分)不受影响。这是更新选择,与输入选择互斥 - 这与 v3 中不同,需要使用合并方法将更新选择与输入选择合并。
这就是为什么您必须使用超时 - 第一次运行更新函数时会附加功能,第二次则更新它们。
尝试:
output
.enter()
.append('p')
.call(function(parent) { parent.append('a') })
.merge(output).select('a')
.attr('href', function(d) { return 'http://www.google.com?q=' + d; })
.text(function(d) { return d; });
输入选择将导致附加 p
,然后我们合并输入和更新选择,以便使用特定文本更新所有元素。现在您可以删除超时功能,并且在移动 slider 时,更新应该正确显示。
以下是更新的片段:
var items = [1,2,3,4,5,6,7,8,9,10,11,12,13]
var slider = d3.select('#slider')
.attr('min', 0)
.attr('max', items.length)
.attr('value', items.length - 1)
.attr('step', 1)
.attr('disabled', null) // enable
;
function update(data) {
var output = d3.select('#output')
.selectAll('p')
.data(data)
;
output
.enter()
.append('p')
.call(function(parent) {
parent.append('a')
})
.merge(output).select('a')
.attr('href', function(d) { return 'http://www.google.com?q=' + d; })
.text(function(d) { return d; });
;
output
.exit()
.remove()
;
}
update(['a', 'b', 'c']);
slider.on('input', function() {
var val = +this.value;
var newData = items.slice(0, val);
update(newData);
});
body {
font-family: sans-serif;
}
p {
outline: 1px red solid;
}
a {
display: inline-block;
outline: 1px blue solid;
min-width: 1em;
min-height: 1em;
}
.small {
font-size: 66%;
}
#slider {
width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.5.0/d3.min.js"></script>
<div id="wrap">
<input type="range" id="slider" disabled="disabled" />
<div class="small" id="output">static content</div>
</div>
关于javascript - d3 : How to append nested elements on enter()? 我的元素被附加,但后续的选择看不到它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44637594/