【问题标题】:Chrome on Windows triggers d3.zoom behavior on clickWindows 上的 Chrome 在点击时触发 d3.zoom 行为
【发布时间】:2016-01-01 22:19:54
【问题描述】:

我正在使用 dc.js 和 d3.js 创建交互式地图。地图应该支持缩放和平移,所以我使用 d3.zoom 行为。当我单击地图上的区域时,我还希望运行一个函数。该代码在 Firefox(Linux 和 Windows)、IE 和 Chrome (Linux) 中按预期工作,但 Windows 上的 Chrome 版本 47 将点击解释为尝试缩放,从而抑制点击事件。有什么办法可以避免吗?

我创建了一个简化的jsfiddle 来演示这个问题。代码如下:

HTML

<div id="container"></div>

JS

var container = d3.select('#container');
var fmt = d3.format('.2f');

var svg = container.append('svg')
    .attr('width', 400)
    .attr('height', 400)
    .append('g');

var colors = ['#444488', '#448844', '#884444'];

svg.selectAll('circle')
    .data(colors)
    .enter()
    .append('circle')
    .attr('cx', function(d, i) { return 50 + 100*i; })
    .attr('cy', function(d, i) { return 50 + 100*i; })
    .attr('r', function(d, i) { return 10 + 10*i; })
    .style('fill', function(d) { return d; })
    .on('click', function(d, i) {
        // Skip the click handler if preventDefault was called. This prevents the click
        // handler from running at the end of a drag.
        if (!d3.event.defaultPrevented) {
            console.log('clicked circle #' + i);
        }
    });

var zoomBehavior = d3.behavior.zoom()
    .scale(1)
    .scaleExtent([1, 15])
    .translate([0, 0])
    .on('zoom', function() {
        console.log('got zoom: scale = ' + fmt(d3.event.scale) + ', translate = [' + fmt(d3.event.translate[0]) + ',' + fmt(d3.event.translate[1]) + ']');
        svg.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")");
    });

container.call(zoomBehavior);

该演示为 SVG 添加了三个圆圈,并为每个圆圈提供了一个点击处理程序。它还将 d3.zoom 行为添加到容器元素。我希望它执行以下操作:

  • 单击一个圆圈会运行该圆圈的单击处理程序。
  • 使用鼠标滚轮放大和缩小,无论鼠标是在圆圈还是背景上。
  • 单击和拖动平移该区域,无论单击/拖动是从一个圆圈开始还是从背景开始。如果它从一个圆圈开始,则不应运行该圆圈的点击处理程序。

Firefox 和 IE 中的演示满足所有这些要求。在 Chrome 中,当我单击一个圆圈时,将运行缩放处理程序而不是单击处理程序。有人对如何处理这个问题有建议吗?

作为另一种方法,我尝试在其余 SVG 元素的上方或下方放置一个矩形,并将缩放行为附加到矩形而不是容器,但我遇到了各种问题,即事件未到达正确的元素。如果人们认为这是可行的方法,我愿意进一步探索。

【问题讨论】:

  • 我无法使用您提供的 jsfiddle 复制该问题。在 Chrome 中,它只在双击时放大。
  • @ArcaneCraeda:这是 Windows 上的 Chrome 吗?
  • 我刚刚在 Linux 中检查了 Chrome,它在那里按预期工作。 (当我单击一个圆圈时,它会运行单击处理程序。)我将使用此信息更新问题。
  • 又改了,可以在Windows上运行。
  • 可能是你有时点击的时候稍微拖了一下?

标签: javascript d3.js dom-events


【解决方案1】:

我在使用旧版本的 d3 (3.3.3) 时遇到了同样的问题。我不确定它是否从那以后得到修复。正如您所说,问题在于 Chrome 处于一种奇怪的状态,即鼠标单击会触发 mousemove 事件。完全关闭 Chrome 并重新打开它似乎让它摆脱了这种状态。

我可以通过检查 d3 的 mousemove 函数来解决这个问题。我在 d3 的 mousedowned() 中的moved() 函数中添加了两行:

function moved() {
    if(d3.event.movementX === 0 && d3.event.movementY === 0) // new
        return false; // new
    dragged = 1;
    translateTo(d3.mouse(target), l);
    zoomed(event_);
}

这似乎无需重新启动 Chrome 即可解决问题。

【讨论】:

    【解决方案2】:

    在我进行开发和调试时,我的 Chrome 实例一定进入了某种奇怪的状态。我重新启动了 Chrome 并再次尝试,现在它工作正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      相关资源
      最近更新 更多