You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 07:02:57