D3.js v4:在 ES6 箭头函数事件监听器中访问当前 DOM 元素 [英] D3.js v4: Access current DOM element in ES6 arrow function event listener

查看:26
本文介绍了D3.js v4:在 ES6 箭头函数事件监听器中访问当前 DOM 元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆