使用使用shadowDOM实例化时对路径的SVG访问vanilla javascript

如何解决使用使用shadowDOM实例化时对路径的SVG访问vanilla javascript

我想操作一个 SVG 的内部路径,它在一个单独的文件中并用“use”实例化

这是我的代码

<!DOCTYPE html><meta charset="utf8"/>
<script src="https://ipfs.blockringtm.ml/ipfs/QmZU12UqysToVJjNmWo3E31i4tmmMbWyxZ82Vyse9CQp49/path-data-polyfill.js"></script>

<svg data="logo.svg" type="image/svg+xml" id="logo"
 width="120px"
 preserveAspectRatio="xMidYMin slice" viewBox="0 0 512 512"
>
<!-- https://stackoverflow.com/questions/65526455/trying-to-access-svg-elements-generated-with-use-with-javascript -->
<!--
  SVG use elements are like shadow DOM elements in HTML. Only the attributes
  of the USE element itself is exposed via the SVG DOM - you cannot alter
  any properties on a single USE element instance that are being cloned
  from the original symbol. It's not like a macro.
-->

<use id="logo1" xlink:href="logo.svg#logo"></use>
</svg>

<script>
var svg = document.querySelector('#logo');
var use = svg.querySelector('#logo1');
console.log('use:',use);
var paths = use.querySelectorAll('path'); // FAILED HERE : empty NodeList: []
console.log('paths:',paths);
for (let path of paths) {
var pathdata = path.getPathData();
console.log(pathdata);
}
</script>

svg 文件是:

<svg id="logo" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 196.1 236.8">
  <defs>
    <linearGradient id="a">
      <stop offset="0" stop-color="#606"/>
      <stop offset="1"/>
    </linearGradient>
  </defs>
  <path id="pin" fill="#01a49b" d="M30.3 168a94.8 94.8 0 0063.2 27.2 95 95 0 0065.6-21.8c.8-.8 17.6-16 1.2.6l-28 28.2L98 236.8l-68.1-68c-6.5-6.5-12.6-15.5-12.6-15.5a88.1 88.1 0 0013 14.7z"/>
  <path if="wrench" fill="#660266" d="M13.5 47.8C36.2 8.5 97-15.8 145 11.9c41.1 23.7 69.1 81.4 37.6 135-17.6 30-49.3 44-65 46.7-4 .7-18.3 1.9-22.5 1.9-1.3-.1-1.8-1.2-1-2.6l17.5-30.8c14.7-4.5 32-11.3 44.2-32.4a66.7 66.7 0 00-26.5-90.8C93.8 18.7 55 37.9 40 63.7A64.5 64.5 0 0051 144l8.2-14.5c2.2-3.8 2.4-4.5-.2-9A46.6 46.6 0 0158 73.3a44.8 44.8 0 0134.5-21.7c5.4-.3 4.8 1 3.7 2.7L80 82.3l9.4 16.3c1.7 3 5 6 8.5 5.9l22-2 15.3-26c1.3-1.9 2.2 0 3 2.2.7 2.2 10.4 16.9-2.5 39.3a45.3 45.3 0 01-37.9 23.4c-4.8-.3-6.1 2.5-8.7 7L65 190A99.7 99.7 0 012.7 121c-6.4-25.7-.8-53.3 10.8-73.3z"/>
</svg>

如果我使用 <object> 标记而不是 <use> 我可以使用 path.pathSegList 访问内部路径 但是它不适用于 path.getPathData pollyfill,因为路径是一个普通对象而不是 SVGPathElement。

问题:

  1. 如何从 Object 标签内的路径获取 SVGPathElement ? 即如何将 DOMobject 转换为 SVGPathElement ?
  2. 或者,有没有办法使用 use 标记获取并“打开” shadow-root,我是否需要在脚本中创建标记以保持打开状态?

对象标记实例的代码(有效)是:

<!DOCTYPE html>

<meta name="viewport" content="width=device-width,initial-scale=1.0" charset="utf8">
<script src="http://ipfs.blockringtm.ml/ipfs/QmU3jKAewrHV8Wryx2WzT5v72PsgT7wt8FgnL8mqmWk259/path-data-polyfill.js"></script>

<style>
body { border:0; margin:0; padding: 0; height: 100vh; top: 0;  }
svg { border: 1px dashed #555 }
</style>

<object id="sotest1" style="width:100px" data="logo.svg" type="image/svg+xml"></object>

<script>
  let obj = document.querySelector('#sotest1');
  obj.addEventListener("load",function(){
     console.log('obj.loaded !');
     var svgDoc = obj.contentDocument;
     console.log('svgDoc:',svgDoc);
     let path1 = svgDoc.querySelector("#pin");
     console.log('typeof:',typeof(path1))
     console.log('#path.d:',path1.getAttribute('d'));
     let paths = svgDoc.getElementsByTagName('path');
     for (let p of paths) {
       let d = p.getAttribute('d'); // does work but can get p.getPathData() to work
       console.log('p.d:',d);
     }

  },false);
</script>

如果你想得到这个文件,我已经为它准备了一个要点: https://gist.github.com/DrI-T/145db3eed5905f83333d8127cbf2c6b8

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 &lt;select id=&quot;xxx&quot;&gt; SELECT di.id, di.name, di.work_type, di.updated... &lt;where&gt; &lt;if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 &lt;property name=&quot;dynamic.classpath&quot; value=&quot;tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams[&#39;font.sans-serif&#39;] = [&#39;SimHei&#39;] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -&gt; systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping(&quot;/hires&quot;) public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate&lt;String
使用vite构建项目报错 C:\Users\ychen\work&gt;npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-