当“this"不可用时,从拖动回调中检索 DOM 目标 [英] Retrieve DOM target from drag callback when `this` is not available

查看:23
本文介绍了当“this"不可用时,从拖动回调中检索 DOM 目标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

d3.drag 的文档说明拖动事件的 DOM 元素目标将在 this 中提供给回调:

The documentation for d3.drag states the DOM element target of the drag event will be available in this to the callback:

当一个指定的事件被调度时,每个监听器都会被调用,使用与 selection.on 监听器相同的上下文和参数:当前数据 d 和索引 i,以 this 上下文作为当前 DOM 元素.

When a specified event is dispatched, each listener will be invoked with the same context and arguments as selection.on listeners: the current datum d and index i, with the this context as the current DOM element.

但是我的回调是一个对象实例并且 this 指向那个对象.所以我需要另一种方法来访问通常在 this 中传递的当前 DOM 元素.我该怎么做?

But my call back is an object instance and this points to that object. So I need another way of accessing the current DOM element that is normally passed in this. How can I do it?

推荐答案

this不可用时,将第二个和第三个参数一起使用得到this:>

Use the second and the third arguments together to get this when this is not available:

d3.drag().on(typename, function(d, i, n) {
  //here, 'this' is simply n[i]
})

详细解释请看下面我写的关于箭头函数中this的文章.问题和你的不一样,但是解释是一样的.

For a detailed explanation, have a look at the article below that I wrote to deal with this in arrow functions. The issue is different from yours, but the explanation is the same.

这里是一个基本的demo,试着拖一个圆圈看控制台:

Here is a basic demo, try to drag a circle and look at the console:

var data = d3.range(5)
var svg = d3.select("body")
  .append("svg")
  .attr("width", 400)
  .attr("height", 100);
var circle = svg.selectAll(null)
  .data(data)
  .enter()
  .append("circle")
  .attr("cy", 50)
  .attr("cx", function(d) {
    return 50 + 50 * d
  })
  .attr("r", 10)
  .attr("fill", "tan")
  .attr("stroke", "black")
  .call(d3.drag()
    .on("start", function(d, i, n) {
      console.log(JSON.stringify(n[i]))
    }))

<script src="https://d3js.org/d3.v4.min.js"></script>

PS:我在 D3 选择上使用 JSON.stringify 因为如果您尝试控制台记录 D3 选择,堆栈片段会冻结.

PS: I'm using JSON.stringify on the D3 selection because Stack snippets freeze if you try to console.log a D3 selection.

使用带有箭头函数的this"

D3.js 中的大多数函数都接受匿名函数作为参数.常见的例子有 .attr.style.text.on.data,但列表比那大得多.

Most of functions in D3.js accept an anonymous function as an argument. The common examples are .attr, .style, .text, .on and .data, but the list is way bigger than that.

在这种情况下,匿名函数会按顺序为每个选定的元素求值,并被传递:

In such cases, the anonymous function is evaluated for each selected element, in order, being passed:

  1. 当前数据(d)
  2. 当前索引(i)
  3. 当前组(nodes)
  4. this 作为当前的 DOM 元素.
  1. The current datum (d)
  2. The current index (i)
  3. The current group (nodes)
  4. this as the current DOM element.

数据、索引和当前组作为参数传递,D3.js 中著名的第一个、第二个和第三个参数(其参数传统上命名为 d, ip 在 D3 v3.x 中).然而,对于使用this,不需要使用任何参数:

The datum, the index and the current group are passed as arguments, the famous first, second and third argument in D3.js (whose parameters are traditionally named d, i and p in D3 v3.x). For using this, however, one doesn’t need to use any argument:

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

上面的代码会在鼠标悬停在元素上时选择this.检查它是否在这个小提琴中工作:https://jsfiddle.net/y5fwgopx/

The above code will select this when the mouse is over the element. Check it working in this fiddle: https://jsfiddle.net/y5fwgopx/

作为新的 ES6 语法,与函数表达式相比,箭头函数的语法更短.但是,对于经常使用 this 的 D3 程序员来说,有一个陷阱:箭头函数不会创建自己的 this 上下文.这意味着,在箭头函数中,this 具有来自封闭上下文的原始含义.

As a new ES6 syntax, an arrow function has a shorter syntax when compared to function expression. However, for a D3 programmer who uses this constantly, there is a pitfall: an arrow function doesn’t create its own this context. That means that, in an arrow function, this has its original meaning from the enclosing context.

这在多种情况下很有用,但对于习惯于在 D3 中使用 this 的编码员来说,这是一个问题.例如,使用上面小提琴中的相同示例,这将不起作用:

This can be useful in several circumstances, but it is a problem for a coder accustomed to use this in D3. For instance, using the same example in the fiddle above, this will not work:

.on("mouseover", ()=>{
    d3.select(this);
});

如果你怀疑,这里是小提琴:https://jsfiddle.net/tfxLsv9u/

If you doubt it, here is the fiddle: https://jsfiddle.net/tfxLsv9u/

嗯,这不是什么大问题:可以在需要时简单地使用常规的老式函数表达式.但是如果您想使用箭头函数编写所有代码怎么办?是否可以在 D3 中使用带有箭头函数的代码并且仍然正确使用 this?

Well, that’s not a big problem: one can simply use a regular, old fashioned function expression when needed. But what if you want to write all your code using arrow functions? Is it possible to have a code with arrow functions and still properly use this in D3?

答案是,因为thisnodes[i]是一样的.该提示实际上存在于整个 D3 API 中,当它描述此内容时:

The answer is yes, because this is the same of nodes[i]. The hint is actually present all over the D3 API, when it describes this:

...以 this 作为当前 DOM 元素 (nodes[i])

...with this as the current DOM element (nodes[i])

解释很简单:因为nodes是DOM中的当前元素组,i是每个元素的索引,nodes[i] 指的是当前的 DOM 元素本身.也就是说,this.

The explanation is simple: since nodes is the current group of elements in the DOM and i is the index of each element, nodes[i] refer to the current DOM element itself. That is, this.

因此,可以使用:

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

这是相应的小提琴:https://jsfiddle.net/2p2ux38s/

这篇关于当“this"不可用时,从拖动回调中检索 DOM 目标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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