SVG中重叠foreignObject的点击事件失效问题求助
解决SVG重叠foreignObject的点击事件穿透问题
这个问题其实是SVG里foreignObject的渲染层级和pointer-events属性共同导致的——SVG元素是按照代码顺序堆叠的,后面的foreignObject会处于顶层,而你给两个foreignObject都设置了pointer-events="all",这意味着整个顶层foreignObject的区域(哪怕里面的div只占20px高度)都会拦截点击事件,底层的元素自然接收不到,哪怕它没被顶层的div视觉上覆盖。
这里有两个直接的解决方案:
方案1:让顶层foreignObject仅在子元素区域拦截点击
把顶层foreignObject的pointer-events设为none,然后给它内部的子元素单独设置pointer-events="all",这样只有子元素实际占据的区域会拦截点击,空白区域的点击会穿透到底层:
<svg class="makeStyles-timeline-17" width="100%" height="1920" overflow="auto"> <!-- 底层foreignObject,保持原有设置 --> <foreignObject position="absolute" width="100%" height="1920" pointer-events="all"> <div> <div id="timelineRow_0" data-index="0" data-time="Wed Dec 09 2020 00:00:00 GMT+0600 (Bangladesh Standard Time)" style="height: 20px;"></div> </div> </foreignObject> <!-- 顶层foreignObject修改pointer-events --> <foreignObject position="absolute" width="100%" height="1920" pointer-events="none"> <div style="height: 20px; pointer-events: all"> Test</div> </foreignObject> </svg>
方案2:缩小顶层foreignObject的区域(如果可行)
如果顶层foreignObject不需要占满整个1920高度,直接把它的height设为子元素的实际高度(比如20px),同时调整位置到对应区域,这样它就不会覆盖整个底层foreignObject的区域,底层未被覆盖的部分就能正常响应点击:
<svg class="makeStyles-timeline-17" width="100%" height="1920" overflow="auto"> <foreignObject position="absolute" width="100%" height="1920" pointer-events="all"> <div> <div id="timelineRow_0" data-index="0" data-time="Wed Dec 09 2020 00:00:00 GMT+0600 (Bangladesh Standard Time)" style="height: 20px;"></div> </div> </foreignObject> <!-- 缩小顶层foreignObject的尺寸 --> <foreignObject position="absolute" width="100%" height="20px" pointer-events="all"> <div style="height: 20px"> Test</div> </foreignObject> </svg>
原理补充
pointer-events="all"意味着元素会响应所有点击相关事件,包括它的空白区域。而pointer-events="none"会让元素完全不参与事件传递,点击会直接穿透到它下面的元素。给子元素单独设置pointer-events="all"可以实现“只有子元素区域拦截点击,其余区域穿透”的效果,这是解决重叠元素点击穿透的常用技巧。
内容的提问来源于stack exchange,提问作者Md Sabbir Alam
相关产品推荐
相关产品推荐

