Windows上的Chrome会在点击

时间:2016-01-01 22:19:55

标签: javascript d3.js javascript-events

我正在使用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行为添加到容器元素。我希望它能够做到以下几点:

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

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

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

2 个答案:

答案 0 :(得分:1)

我在旧版本的d3(3.3.3)中遇到了同样的问题。我不知道自那以后它是否已被修复。正如你所说,问题在于Chrome处于奇怪的状态,鼠标点击会触发鼠标移动事件。完全关闭Chrome并重新打开它似乎让它脱离了这种状态。

我能够通过检查d3的mousemove功能来解决这个问题。我在d3中的mousedowned()中向move()函数添加了两行:

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的情况下解决问题。

答案 1 :(得分:0)

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