D3.js v4:在 ES6 箭头函数事件监听器中访问当前 DOM 元素 [英] D3.js v4: Access current DOM element in ES6 arrow function event listener
问题描述
在D3.js v4中,通过传统的回调函数注册事件监听器时,this
引用了当前的DOM元素:
In D3.js v4, when registering an event listener through a traditional callback function, this
references the current DOM element:
d3.select("div").on('mouseenter', function() {
d3.select(this).text("Yay");
});
ES6 提供了箭头函数,恕我直言,这使 D3.js 代码更具可读性,因为它们非常简洁.然而,传统的回调不能一味地用箭头函数代替:
ES6 offers arrow functions, which IMHO make D3.js code a lot more readable because they are very concise. However, traditional callbacks cannot blindly be replaced with arrow functions:
d3.select("div").on('mouseenter', () => {
d3.select(this); // undefined
});
文章关于 D3 和箭头函数" 很好地解释了为什么 this
没有按预期绑定.本文建议对需要访问当前 DOM 元素的代码使用传统回调.
The article "On D3 and Arrow Functions" gives a very good explanation of why this
is not bound as expected. The article suggests using traditional callbacks for code that needs access to the current DOM element.
是否可以通过箭头函数访问当前 DOM 元素?
Is it possible to access the current DOM element from an arrow function?
推荐答案
在 D3 中有一种惯用的方法:只需使用不太出名的第三个参数:
There is an idiomatic way of doing this in D3: just use the less famous third argument:
selection.on("mouseenter", (d, i, nodes) => {
d3.select(nodes[i]);
});
这与以下内容相同:
selection.on("mouseenter", function() {
d3.select(this);
});
我在这里写了一个例子:d3 v4 在`this`不可用时从拖动回调中检索拖动DOM目标
I wrote an example here: d3 v4 retrieve drag DOM target from drag callback when `this` is not available
这是一个演示:
d3.selectAll("circle").on("mouseover", (d, i, p) => {
d3.select(p[i]).attr("fill", "maroon")
})
.on("mouseout", (d, i, p) => {
d3.select(p[i]).attr("fill", "seagreen")
});
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg>
<circle cx="50" cy="50" r="20" fill="seagreen"></circle>
<circle cx="125" cy="50" r="20" fill="seagreen"></circle>
<circle cx="200" cy="50" r="20" fill="seagreen"></circle>
</svg>
实际上,如果您查看链接的文章末尾,他会给出相同的解决方案.
Actually, if you look at the end of the article you linked, he gives the same solution.
您的建议的解决方案,d3.event.target
,尽管适用于事件侦听器,在几种情况下不起作用.例如:
Your proposed solution, d3.event.target
, despite working for event listeners, does not work in several situations. For instance:
d3.selectAll("circle").each(()=>d3.select(d3.event.target).attr("fill", "red"))
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg>
<circle cx="50" cy="50" r="20" fill="seagreen"></circle>
<circle cx="125" cy="50" r="20" fill="seagreen"></circle>
<circle cx="200" cy="50" r="20" fill="seagreen"></circle>
</svg>
但同样的代码使用第三个参数:
But the same code works using the third argument:
d3.selectAll("circle").each((d,i,p)=>d3.select(p[i]).attr("fill", "red"))
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg>
<circle cx="50" cy="50" r="20" fill="seagreen"></circle>
<circle cx="125" cy="50" r="20" fill="seagreen"></circle>
<circle cx="200" cy="50" r="20" fill="seagreen"></circle>
</svg>
这篇关于D3.js v4:在 ES6 箭头函数事件监听器中访问当前 DOM 元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!