d3开发SVG时如何让上层line元素点击事件穿透到下层元素
解决方案
你需要的是保留线条的hover响应能力,仅让点击事件穿透到下层元素,不能直接给线条设置pointer-events: none(会同时屏蔽hover事件,导致title和mouseover回调失效),可以通过线条点击回调临时隐藏自身获取下层元素的方式实现,全程无视觉感知:
实现步骤
- 给线条绑定click事件回调,回调中临时隐藏当前线条,获取点击坐标对应的下层元素后恢复线条显示
- 若下层元素是绑定了click事件的圆形,手动触发它的click事件即可
完整修改代码
svg = d3.select('svg') .style("cursor", "pointer") ; circles = svg.append('g'); lines = svg.append('g'); events = d3.select('#events'); var data = [ { id: 1, x: 25, y: 25 }, { id: 2, x: 75, y: 25 }, { id: 3, x: 25, y: 75 }, { id: 4, x: 75, y: 75 } ]; circles.selectAll('circle') .data(data, d => d.id) .join('circle') .attr('cx', d=> d.x) .attr('cy', d=> d.y) .attr('r', 20) .on('click', function(e) { events.text('circle');}) .append('title') .text(d=> 'circle ' + d.id) ; // 线条点击事件处理函数 function lineClickHandler(e) { // 临时隐藏当前线条,用于获取下层元素 this.style.display = 'none'; // 获取点击坐标下的元素 const targetEl = document.elementFromPoint(e.clientX, e.clientY); // 立刻恢复线条显示,同步执行无闪烁 this.style.display = 'revert'; // 匹配到圆形则触发其点击事件 if(targetEl.tagName.toLowerCase() === 'circle') { targetEl.dispatchEvent(new Event('click')); } } lines.selectAll('line') .data(data, d => d.id) .join('line') .attr('x1', d=> d.x - 25) .attr('y1', d=> d.y - 25) .attr('x2', d=> d.x + 25) .attr('y2', d=> d.y + 25) .on('mouseover', function(e) { events.text('line');}) .on('mouseout', function(e) { events.html(' ');}) // 新增点击事件绑定 .on('click', lineClickHandler) .append('title') .text(d=> 'line ' + d.id) ;
这个方案完全不影响原有hover逻辑:线条的mouseover回调、自带title提示都可以正常触发,仅点击事件会穿透到下层对应元素。
内容的提问来源于stack exchange,提问作者Nikki Locke
相关产品推荐
相关产品推荐

