【发布时间】: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