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

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

问题描述

在D3.js v4中,当通过传统的回调函数注册事件监听器时,这个引用当前的DOM元素:


$ b $($)$ {code> d3.select(div)。on('mouseenter',function(){
d3.select(this).text(Yay ;
});

ES6提供箭头功能,其中IMHO使D3.js代码更易读,因为它们非常简洁。但是,传统的回调不能盲目地用箭头函数替换:

  d3.select(div)。on('mouseenter' ,()=> {
d3.select(this); // undefined
});

文章在D3和箭头函数给出了一个很好的解释,为什么这个没有预期的约束。该文章建议对需要访问当前DOM元素的代码使用传统的回调。



可以从箭头函数访问当前的DOM元素吗?

解决方案

在D3中有一个惯用的方法:只使用不太着名的第三个参数:

  selection.on(mouseenter,(d,i,nodes)=> {
d3.select(nodes [i]) ;
});

这与以下相同:

  selection.on(mouseenter,function(){
d3.select(this);
});

我在S.O.写了一个例子。文件就是这样(不是双关语):使用这个使用箭头功能



这是一个演示:



  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 =50cy =50r =20fill =seagreen>< / circle> < circle cx =125cy =50r =20fill =seagreen>< / circle> < circle cx =200cy =50r =20fill =seagreen>< / circle>< / svg>  

/ div>



其实,如果你看看链接的文章的最后,他给出了相同的解决方案。



尽管为事件侦听器工作,您提出的解决方案 d3.event.target 在几种情况下不起作用。例如:



  d3.selectAll(circle )=> d3.select(d3.event.target).attr(fill,red)) 

 < script src =https://d3js.org/d3.v4.min.js>< / script>< svg> < circle cx =50cy =50r =20fill =seagreen>< / circle> < circle cx =125cy =50r =20fill =seagreen>< / circle> < circle cx =200cy =50r =20fill =seagreen>< / circle>< / svg>  

/ div>



但同样的代码使用第三个参数:



 

  SRC = https://d3js.org/d3.v4.min.js >< /脚本>< SVG> < circle cx =50cy =50r =20fill =seagreen>< / circle> < circle cx =125cy =50r =20fill =seagreen>< / circle> < circle cx =200cy =50r =20fill =seagreen>< / circle>< / svg>  

/ div>


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 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
});

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.

Is it possible to access the current DOM element from an arrow function?

解决方案

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]);
});

And that's the same of:

selection.on("mouseenter", function() {
    d3.select(this);
});

I wrote an example at S.O. Docs just about this (no pun intended): Using "this" with an arrow function

Here is a demo:

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.

Your proposed solution, d3.event.target, despite working for event listeners, doesn't 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元素arrow函数事件侦听器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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