如何切换选中元素的类?D3.js中classed函数报错问题求助
解决D3中切换元素类的问题
嘿,我明白你遇到的问题了!咱们先拆解下错误原因,再给你修正后的代码:
为什么你的代码会报错?
你在.classed()的回调里写了l.classed("non-active"),这里的l是绑定到元素上的原始数据对象,不是D3的选择集元素,所以它根本没有.classed()这个方法,自然会抛出.classed is not a function的错误。
你后来尝试的!d3.select(l).classed("non-active")也不对,因为d3.select()需要传入DOM元素或者选择器字符串,而你传的是数据对象l,根本选不到对应的DOM元素,所以逻辑不生效。
正确的写法
我们需要在.classed()的回调里拿到当前的DOM元素,然后判断它的类状态。有两种常用方式:
方法1:使用普通函数(利用this指向DOM元素)
function toggleLinksActivity(d) { d3.selectAll(".link") .filter(l => l.target == d) .classed("non-active", function() { // this指向当前遍历到的DOM元素,转成D3选择集后判断类状态 return !d3.select(this).classed("non-active"); }); }
注意这里不能用箭头函数,因为箭头函数会绑定外层的this,而不是当前的DOM元素。
方法2:使用回调的第三个参数(节点数组)
如果你偏好ES6箭头函数,可以用回调的第三个参数(所有节点的数组),结合索引拿到当前元素:
function toggleLinksActivity(d) { d3.selectAll(".link") .filter(l => l.target == d) .classed("non-active", (data, index, nodes) => { // 通过索引从节点数组中拿到当前DOM元素 return !d3.select(nodes[index]).classed("non-active"); }); }
核心要点
在D3的方法回调中:
- 第一个参数是绑定到元素的数据
- 第二个参数是元素的索引
- 第三个参数是当前选择集的所有DOM节点数组
- 普通函数里的
this指向当前DOM元素,箭头函数则不会
一定要区分「数据对象」和「DOM元素/选择集」,这是你这次踩坑的关键~
内容的提问来源于stack exchange,提问作者Jeroen
相关产品推荐
相关产品推荐

