如何在SVG元素外获取父/子元素并为目标元素添加类?
问题原因
closest()是DOM调用方法,需要传入选择器作为参数,不能写成.closest.SVGGeometryElement的属性访问形式- 你的
.state-info元素和被点击的SVG path元素不在同一DOM父级链路中:path位于页面主内容<main>标签内,弹窗是独立挂载在<main>外的全局元素,用closest()向上查找永远无法匹配到目标元素,直接全局选择目标元素即可 - 原有逻辑针对每个州单独写if判断的写法冗余,后期维护成本高,可通过映射表批量处理
修正后的可用代码
针对你目前科罗拉多州的测试场景,修正后可直接运行的代码如下:
var stateWrap = document.querySelectorAll('.map-click path'); for (var i = 0; i < stateWrap.length; i++) { if (stateWrap[i].classList.contains('colorado')) { stateWrap[i].addEventListener('click', function() { console.log('hi'); // 直接全局选择.state-info元素添加类即可 document.querySelector('#map-popup .state-info').classList.add('co-popup'); }); } }
更高效的批量处理方案
你可以提前建立州类名和弹窗类名的映射表,不需要每个州单独写if判断,后续新增州只需要补充映射关系即可:
// 州类名和对应弹窗类名的映射表,后续新增州直接在这里补 const stateClassMap = { 'colorado': 'co-popup', // 示例:'california': 'ca-popup' } const statePaths = document.querySelectorAll('.map-click path'); statePaths.forEach(path => { // 匹配path上的州类名 const matchedState = Object.keys(stateClassMap).find(state => path.classList.contains(state)); if (matchedState) { path.addEventListener('click', () => { const stateInfoEl = document.querySelector('#map-popup .state-info'); // 先清除之前加的其他州的弹窗类,避免多个类叠加 Object.values(stateClassMap).forEach(cls => stateInfoEl.classList.remove(cls)); // 添加当前点击州的专属类 stateInfoEl.classList.add(stateClassMap[matchedState]); }) } })
内容的提问来源于stack exchange,提问作者Lauren Beecher
相关产品推荐
相关产品推荐

