如何在d3.xhr和异步队列中获取鼠标位置的元素?

时间:2016-05-31 13:53:27

标签: javascript d3.js lodash

有人可以告诉我这个问题。我需要在d3.xhr请求处理结束时获取鼠标指针所在的html元素。此d3.xhr应在队列中调用:async.queue

define([
    "d3",
    "lodash",
    "async",

], function (d3, _, async) {

var html = d3.select("html");
async.queue(function (cell, callback) {
   d3.xhr("/myurl", function (error, data) {

     var data = _.merge(JSON.parse(data.response), cellDetails);
     //processing data

     console.log(d3.mouse(html)); //this line fails
    }
}

控制台中出现的错误

Uncaught TypeError: Cannot read property 'sourceEvent' of null
k                    @ d3.v3.min.js:1
aa.mouse             @ d3.v3.min.js:3
(anonymous function) @ myJSfile.js:77
(anonymous function) @ d3.v3.min.js:1
t                    @ d3.v3.min.js:1
u                    @ d3.v3.min.js:1

通常任务是正确隐藏工具提示,因为现在它不会每次都消失。更多细节。 我们有一张桌子:

<table>
    <tr>
        <td class="fav">Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
    </tr>
    <tr>
        <td class="fav">Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
    </tr>
    <tr>
        <td class="fav">Data 1</td>
        <td>Data 2</td>
        <td>Data 3</td>
    </tr>
</table>
<div class="tooltip" style="visibility:hidden"></div>

我们应该能够导航到表格中的单元格,当mouseenter在单元格上然后js在异步队列中通过d3.xhr发送请求。因此,如果鼠标仍在同一个单元格上,我们必须在工具提示中显示响应。此验证需要,因为请求/响应需要一些时间,用户可能导航到另一个单元格甚至走出表格边框。在这种情况下,我们应该隐藏工具提示。

我尝试在页面上添加'mouseenter','mouseleave'等事件,html和其他元素,但它对我来说不起作用。更容易验证鼠标在哪里。 请帮忙。

3 个答案:

答案 0 :(得分:0)

您可以使用elementFromPoint解决问题。首先,为鼠标创建一个事件处理程序,然后使用x和y位置来确定鼠标是什么元素:

d3.select("body").on("mouseover", function() {
    var x = d3.event.pageX, y = d3.event.pageY,
    elementMouseIsOver = document.elementFromPoint(x, y);

    console.log(elementMouseIsOver);
});

在这个小提琴中,当您将鼠标悬停在控制台上时,可以看到控制台中的元素:http://jsfiddle.net/y9yj8kxq/。我希望这就是你想要的。

如果您在我的示例中编写console.log(elementMouseIsOver.id),它将记录鼠标所在的HTML元素的ID。我相信您可以在调用之前将此ID与ID进行比较,以检查鼠标是否仍在同一元素上。看到这个小提琴:http://jsfiddle.net/43c1h3a0/。将鼠标悬停在元素上时,可以在控制台中看到ID。

以下是API:https://developer.mozilla.org/en-US/docs/Web/API/Document/elementFromPoint

答案 1 :(得分:0)

事实上,你试图在没有mouse- *事件的情况下获得鼠标位置,它与这个问题有关(并且不可能): How to get the mouse position without events (without moving the mouse)?

您的第一个跟踪进入和离开每个单元格的解决方案更加可行。 使用此解决方案,您可以跟踪您是否在单元格上,以及哪一个。

然后在xhr回调中,检查你是否仍然相同,然后显示弹出窗口。

你也可以试试这个:https://stackoverflow.com/a/4517215/2372765。 这里的技巧是添加一个全局事件监听器并全局跟踪鼠标,并在每次移动时保存其位置。 (可能更耗费CPU)

答案 2 :(得分:0)

谢谢大家的回复。 我已经解决了这个问题。

方式如下。我添加了一个像'global'变量的标志,名为'isMouseOutOfTable',表示鼠标是在tbody还是out。我还在

上添加了活动
tbody.on('mouseleave', function(){tooltip.mouseOutOfTable(); tooltip.hideTooltip();})
cell.on('mouseenter', function(){tooltip.showTooltip(); tooltip.mouseWithinTable();})

因此,当鼠标不在tbody时,我们将标记设置为true并隐藏工具提示(如果鼠标位于单元格上,则设置false)。 如果我们有一个请求/响应队列,那么我们只检查标志

define([
    "d3",
    "lodash",
    "async",

], function (d3, _, async) {

var isMouseOutOfTable = true;

async.queue(function (cell, callback) {
   d3.xhr("/myurl", function (error, data) {

     var data = _.merge(JSON.parse(data.response), cellDetails);
     //processing data
     tooltip.setData(data);

    if(isMouseOutOfTable == false){
            toolTip.style("visibility", "visible");
     } else {
            toolTip.style("visibility", "hidden");
     }
  }
}

这段代码解决了当响应仍处理时鼠标不在桌面时的问题,你必须根据鼠标位置决定是否显示工具提示。