Javascript 在重叠的SVG层中处理鼠标事件
我正在用d3.js构建地图可视化。我正在为美国各州和县绘制填充多边形。县的SVG层位于州的SVG层之下。状态已填充,但填充不透明度设置为0;我认为需要填充来捕捉点击事件 我想在州一级捕捉点击事件,但我想在县一级捕捉鼠标悬停事件 但是,鼠标悬停事件由各州捕获,不会传递到各县Javascript 在重叠的SVG层中处理鼠标事件,javascript,jquery,html,svg,d3.js,Javascript,Jquery,Html,Svg,D3.js,我正在用d3.js构建地图可视化。我正在为美国各州和县绘制填充多边形。县的SVG层位于州的SVG层之下。状态已填充,但填充不透明度设置为0;我认为需要填充来捕捉点击事件 我想在州一级捕捉点击事件,但我想在县一级捕捉鼠标悬停事件 但是,鼠标悬停事件由各州捕获,不会传递到各县 有没有办法将事件向下传递一层或触发县上的鼠标悬停事件?如果您想在单击某个州时执行某些操作,例如更改边框样式或形状的不透明度,您可以使用每个县都属于某个州的事实,只需在州中对县进行分组,捕获县中的“单击”事件,选择相应的状态元素
有没有办法将事件向下传递一层或触发县上的鼠标悬停事件?如果您想在单击某个州时执行某些操作,例如更改边框样式或形状的不透明度,您可以使用每个县都属于某个州的事实,只需在州中对县进行分组,捕获县中的“单击”事件,选择相应的状态元素并更改其视觉属性。这一战略的模型:
// Setup the visualization, assuming that you have a div with id 'chart'
var width = 300,
height = 300,
div = d3.select('#chart'),
svg = div.append('svg')
.attr('width', width)
.attr('height', height);
// Array of states, each one containing one or more counties. In this example,
// the states are rectangles, but you get the idea
var states = [
{
width: 300,
height: 300,
name: 'Fake State',
counties: [
{x: 5, y: 5, width: 95, height: 290, fill: '#b4a0a0'},
{x: 100, y: 5, width: 150, height: 290, fill: '#b4c0a0'},
{x: 250, y: 5, width: 45, height: 290, fill: '#a4a0c0'}
]
}];
// Create a group for each state, with class state
var gstates = svg.selectAll('g.state')
.data(states)
.enter()
.append('g')
.classed('state', true);
// Add the state background, in this case, a transparent rectangle
gstates
.append('rect')
.classed('state', true)
.attr('width', function(d) { return d.width; })
.attr('height', function(d) { return d.height; })
.attr('fill', '#444')
.attr('fill-opacity', 0.0);
// For each group, add rectangles for each county, binding them to the
// county array of each state.
gstates.selectAll('rect.county')
.data(function(d) { return d.counties; })
.enter()
.append('rect')
.classed('county', true)
.attr('x', function(d) { return d.x; })
.attr('y', function(d) { return d.y; })
.attr('width', function(d) { return d.width; })
.attr('height', function(d) { return d.height; })
.attr('fill', function(d) { return d.fill; })
.on('mouseover', function() {
d3.select(this).attr('fill-opacity', 0.5);
})
.on('mouseout', function() {
d3.select(this).attr('fill-opacity', 0.9);
})
.on('click', function() {
// Retrive the parent group of each county, and then select
// the shape corresponding to the state and alter its properties
// you can also access the state data
var parent = d3.select(d3.select(this).node().parentNode),
state = parent.select('rect.state');
// Output 'Fake State'
console.log(parent[0][0].__data__.name);
state.attr('fill-opacity', 1.0);
});
这里有一把小提琴。关于,这里有一个d3函数,它可以满足您的需要 它通过临时禁用顶层上的指针事件,并手动触发下一层上的鼠标事件,将事件传递到下层
function passThruEvents(g) {
g .on('mousemove.passThru', passThru)
.on('mousedown.passThru', passThru)
;
function passThru(d) {
var e = d3.event;
var prev = this.style.pointerEvents;
this.style.pointerEvents = 'none';
var el = document.elementFromPoint(d3.event.x, d3.event.y);
var e2 = document.createEvent('MouseEvent');
e2.initMouseEvent(e.type,e.bubbles,e.cancelable,e.view, e.detail,e.screenX,e.screenY,e.clientX,e.clientY,e.ctrlKey,e.altKey,e.shiftKey,e.metaKey,e.button,e.relatedTarget);
el.dispatchEvent(e2);
this.style.pointerEvents = prev;
}
}
您是否有指向您正在使用的示例的链接?此解决方案非常棒,很容易适应其他情况,但是,被最上面的元素“遮挡”的元素将无法通过
:hover
进行样式设置,我也很想解决此问题。