【问题标题】:Mousemove event won't fire on canvas even if z-index is max即使 z-index 为最大值,Mousemove 事件也不会在画布上触发
【发布时间】:2018-01-21 04:17:54
【问题描述】:

几周以来我有点不知所措,试图让mousemove 事件在一组分层画布上工作。 按照之前post 中的建议,我确认事件仅在目标层的z-index 位于顶部时才会正确触发(如这个简单的fiddle 所示):

但是,在我正在使用的扩展代码 (d3 parcoords) 中,尽管 HTML 结构与上述相同,但我无法在顶部的平行坐标图中为画布触发事件。

bl.ocks 显示了扩展版本,以及即使目标分层画布具有最大的z-index,该事件也无法正常工作(尽管该事件在图表下方的简单画布中运行良好)。 我尝试从 parcoords 文件中创建一个最小示例,但考虑到互连功能的数量,我无法获得一个有用且有效的版本。

我希望知道原始 parcoords 代码的人能够澄清图表的画布是如何组织的,以及是否有特定的东西可能导致 mousemove 事件不起作用。或者,也许一些有经验的眼睛可能会发现我在我发布的示例中遗漏的东西。 非常感谢任何提示!

从 d3.parcoords.js 中提取生成画布的代码:

var pc = function(selection) {
  selection = pc.selection = d3.select(selection);

  __.width = selection[0][0].clientWidth;
  __.height = selection[0][0].clientHeight;

  // canvas data layers
  ["marks", "foreground", "brushed", "highlight", "clickable_colors"].forEach(function(layer, i) {
    canvas[layer] = selection
      .append("canvas")
      .attr({
      id: layer, //added an id for easier selecting for mouse event 
      class: layer,
      style: "position:absolute;z-index: " + i
      })[0][0];
    ctx[layer] = canvas[layer].getContext("2d");
  });


  // svg tick and brush layers
  pc.svg = selection
    .append("svg")
      .attr("width", __.width)
      .attr("height", __.height)
      .style("font", "14px sans-serif")
      .style("position", "absolute")

    .append("svg:g")
      .attr("transform", "translate(" + __.margin.left + "," + __.margin.top + ")");

  return pc;
};

用于绘制方块并设置 mousemove 事件的函数:

//This custom function returns polyline ID on click, based on its HEX color in the hidden canvas "clickable_colors"
//Loosely based on http://jsfiddle.net/DV9Bw/1/ and https://stackoverflow.com/questions/6735470/get-pixel-color-from-canvas-on-mouseover
function getPolylineID() {

    function findPos(obj) {
        var curleft = 0, curtop = 0;
        if (obj.offsetParent) {
            do {
                curleft += obj.offsetLeft;
                curtop += obj.offsetTop;
            } while (obj = obj.offsetParent);
            return { x: curleft, y: curtop };
        }
        return undefined;
    }

    function rgbToHex(r, g, b) {
        if (r > 255 || g > 255 || b > 255)
            throw "Invalid color component";
        return ((r << 16) | (g << 8) | b).toString(16);
    }


    // set up some squares
    var my_clickable_canvas = document.getElementById('clickable_colors');
    var context = my_clickable_canvas.getContext('2d');
    context.fillStyle = "rgb(255,0,0)";
    context.fillRect(0, 0, 50, 50);
    context.fillStyle = "rgb(0,0,255)";
    context.fillRect(55, 0, 50, 50);

    $("#clickable_colors").mousemove(function(e) {
    //$(document).mousemove(function(e) {
    //debugger;
        var pos = findPos(this);
        var x = e.pageX - pos.x;
        //console.log(x)
        var y = e.pageY - pos.y;
        var coord = "x=" + x + ", y=" + y;
        var c = this.getContext('2d');
        var p = c.getImageData(x, y, 1, 1).data; 
        var hex = "#" + ("000000" + rgbToHex(p[0], p[1], p[2])).slice(-6);
        $('#status').html(coord + "<br>" + hex);
        console.log("Polyline's hex:" + hex)
    });
}

【问题讨论】:

    标签: javascript html d3.js canvas parallel-coordinates


    【解决方案1】:

    svg 覆盖了您的画布。 画布和 svg 都在同一级别,但您没有在 svg 上设置 z-index,因为它是在所有画布之后渲染的。
    只需将z-index: 0; 放在您链接的页面中的 svg 上即可在 Chrome 中为我修复它。 这似乎只是 z-indexes 的问题。
    您应该在所有画布上设置 css positionz-index 并在同一级别上设置 sgv。

    编辑
    抱歉,我错了它只是 z-index。
    我可以通过删除以下 css 来使其工作。

    .parcoords > canvas {
        pointer-events: none;
    }
    

    但这似乎在您正在使用的库中,所以只需覆盖它。

    .parcoords > canvas {
        pointer-events: auto;
    }
    

    【讨论】:

    • 感谢您对此进行调查!不过有点惊讶,因为我已经尝试在 SVG 上设置较低的z-index,但在 Firefox 中没有成功。我刚刚在 bl.ocks 示例中的 Chrome 中再次尝试,但也无法重现您在那里取得的成果。我将 SVG 和所有画布的 position:absolute;z-index:0; 设置为 z-index:5;,但仍然不会触发事件。这正是您的建议,还是我仍然遗漏了什么?我有最新的 Chrome 版本(60.0.3112.90 64 位),所以真的不知道为什么它不起作用..
    • 对不起,我错了,因为是 svg。我将编辑我的答案。
    • 太棒了,我不知道这可以用纯 CSS 来控制,我可能过了一段时间才发现这一点。真心感谢!现在唯一的问题是用auto 覆盖none 属性会阻止单击较低层(即现在悬停在顶层上可以正常工作,但不能再单击较低层上的轴和“刷过” “ 垂直)。我希望可以在每个画布上单独应用适当的 css 以获得整体所需的结果,我明天会尝试..再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-08
    相关资源
    最近更新 更多