JavaScript遍历SVG元素将Path转为Polygon时遇错误求助
解决SVG Path转Polygon的常见问题
我来帮你一步步搞定这些错误,让你的代码正常运行:
1. 修复ReferenceError: $ is not defined
你代码里用了jQuery的$(this)语法,但根本没引入jQuery库,浏览器自然找不到$函数。其实这个需求完全可以用原生JavaScript实现,不需要额外依赖,我们把所有jQuery相关的写法换成原生DOM API:
- 替换
$(this).is(path)为element.tagName === 'PATH'(注意tagName是大写) - 替换
$(this).getAttribute("id")为element.getAttribute("id") - 替换
$(this).getTotalLength()为element.getTotalLength(),以此类推
2. 修复XML解析语法错误
FileReader.readAsText是异步操作,你在fr.onload回调外面就调用了解析逻辑,这时候文件内容还没加载完成,相当于解析了空数据,导致语法错误。所有依赖文件内容的代码必须放在fr.onload函数内部。
3. 优化SVG元素遍历与操作
- 直接用
doc.querySelectorAll('path')获取所有path元素,比遍历所有*元素更高效 - 确保创建polygon时使用正确的SVG命名空间(你这部分是对的,不用改)
- 替换元素用原生的
replaceWith方法即可
修正后的完整代码
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Reader</title> </head> <body> <input type="file" id="fileReader" /> <br> <p id="Content"></p> <script> document.getElementById("fileReader").addEventListener('change', function() { var fr = new FileReader(); fr.onload = function() { console.log("File Loaded!"); // 所有解析和转换逻辑都放在onload里面 const parser = new DOMParser(); const doc = parser.parseFromString(fr.result, "text/xml"); console.log(doc); // 直接获取所有path元素 doc.querySelectorAll('path').forEach(function(pathElement) { const polygon = doc.createElementNS("http://www.w3.org/2000/svg", "polygon"); const pathId = pathElement.getAttribute("id"); if (pathId) { polygon.setAttribute("id", pathId); } console.log("Converting " + pathId); // 原生调用SVGPathElement的方法 const len = pathElement.getTotalLength(); let p = pathElement.getPointAtLength(0); let seg = pathElement.getPathSegAtLength(0); let stp = `${p.x},${p.y}`; for (let i = 1; i < len; i++) { p = pathElement.getPointAtLength(i); const currentSeg = pathElement.getPathSegAtLength(i); if (currentSeg > seg) { stp += ` ${p.x},${p.y}`; seg = currentSeg; } } polygon.setAttribute("points", stp); pathElement.replaceWith(polygon); }); // 如果需要把转换后的SVG显示出来,可以这样做 const serializer = new XMLSerializer(); const svgString = serializer.serializeToString(doc.documentElement); document.getElementById("Content").textContent = svgString; }; // 触发文件读取 fr.readAsText(this.files[0]); }); </script> </body> </html>
额外说明
- 我加了把转换后的SVG字符串显示到页面的逻辑,你可以根据需求调整
- 注意
getPathSegAtLength方法在一些旧浏览器中可能有兼容性问题,如果遇到问题,可以考虑用轻量的第三方库来处理路径点,但原生方法在现代浏览器中基本都支持 - 解析SVG时,也可以用
image/svg+xml作为第二个参数,但text/xml也能正常工作
内容的提问来源于stack exchange,提问作者the_ritz
相关产品推荐
相关产品推荐

