当 `this` 不可用时,从拖动回调中检索 DOM 目标
Posted
技术标签:
【中文标题】当 `this` 不可用时,从拖动回调中检索 DOM 目标【英文标题】:Retrieve DOM target from drag callback when `this` is not available 【发布时间】:2017-12-28 22:51:25 【问题描述】:d3.drag 的文档指出,拖动事件的 DOM 元素目标将在 this
中提供给回调:
当指定事件被调度时,每个侦听器将被调用,其上下文和参数与 selection.on 侦听器相同:当前数据 d 和索引 i,其中 this 上下文作为当前 DOM 元素。
但我的回调是一个对象实例,this
指向该对象。所以我需要另一种方式来访问通常在this
中传递的当前DOM 元素。我该怎么做?
【问题讨论】:
【参考方案1】:当this
不可用时,将第二个和第三个参数一起使用得到this
:
d3.drag().on(typename, function(d, i, n)
//here, 'this' is simply n[i]
)
详细解释请看下面我写的在箭头函数中处理this
的文章。这个问题和你的不同,但解释是一样的。
这里是一个基本的demo,试着拖个圈看看控制台:
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 选择,堆栈 sn-ps 会冻结。
将“this”与箭头函数一起使用
D3.js 中的大多数函数都接受匿名函数作为参数。常见的例子有.attr
、.style
、.text
、.on
和.data
,但列表远不止这些。
在这种情况下,匿名函数会按顺序对每个选定的元素进行评估:
-
当前数据 (
d
)
当前索引 (i
)
当前组 (nodes
)
this
作为当前 DOM 元素。
数据、索引和当前组作为参数传递,即 D3.js 中著名的第一个、第二个和第三个参数(其参数在 D3 v3.3 中传统上命名为 d
、i
和 p
。 X)。但是,对于使用this
,不需要使用任何参数:
.on("mouseover", function()
d3.select(this);
);
当鼠标悬停在元素上时,上面的代码将选择this
。检查它在这个小提琴中的工作:https://jsfiddle.net/y5fwgopx/
箭头函数
作为一种新的 ES6 语法,与函数表达式相比,箭头函数的语法更短。但是,对于经常使用this
的 D3 程序员来说,存在一个陷阱:箭头函数不会创建自己的 this
上下文。这意味着,在箭头函数中,this
的原始含义来自封闭的上下文。
这在多种情况下可能很有用,但对于习惯于在 D3 中使用this
的程序员来说,这是一个问题。例如,使用上面小提琴中的相同示例,这将不起作用:
.on("mouseover", ()=>
d3.select(this);
);
如果你怀疑,这里是小提琴:https://jsfiddle.net/tfxLsv9u/
嗯,这不是什么大问题:可以在需要时简单地使用常规的老式函数表达式。但是,如果您想使用箭头函数编写所有代码怎么办?是否有可能有一个带有箭头函数的代码并且仍然可以在 D3 中正确使用this
?
第二个和第三个参数组合
答案是是的,因为this
与nodes[i]
相同。提示实际上存在于整个 D3 API 中,当它描述时:
...
this
作为当前 DOM 元素 (nodes[i]
)
解释很简单:因为nodes
是DOM中的当前元素组,i
是每个元素的索引,nodes[i]
指的是当前DOM元素本身。即this
。
因此,可以使用:
.on("mouseover", (d, i, nodes) =>
d3.select(nodes[i]);
);
这是对应的小提琴:https://jsfiddle.net/2p2ux38s/
【讨论】:
.on("mouseover", (d, i, nodes) => d3.select(nodes[i]); );这在 d3 V4 中可用我们如何在 d3 v3 中做到这一点 @AjinkyaDhote 这样做:.on("mouseover",()=>d3.select(d3.event.target);)
我尝试了 jsfiddle。它给出了我现在得到的相同错误。可能是因为版本变化什么的
@krishna 好吧,这不是投反对票的理由,因为我在这里的回答显然是正确的:你做错了其他事情。如果你有问题,我建议你发布一个问题来重现它。以上是关于当 `this` 不可用时,从拖动回调中检索 DOM 目标的主要内容,如果未能解决你的问题,请参考以下文章
当静态库不可用时,是不是可以从 linux 交叉编译 Windows?
Android WifiP2p - 当发现的设备不可用时收到通知
当锁定不可用时,调用Lock.lock()的线程何时从调用返回?