使用 JavaScript 设置基本 SVG 元素的属性

Set attribute of basic SVG element with JavaScript

首先,下面是没有添加任何 JavaScript 的预期结果

* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body { display: flex; justify-content: center; align-items: center; }
svg { width: 12.5rem; height: 6rem; }
path { fill: none; stroke: #444; stroke-width: 5px; }
circle { opacity: 0.75; fill: #0dd; }
<svg>
  <path
    d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" 
  />

  <circle r='10'>
    <animateMotion 
      dur="5s" repeatCount="indefinite"
      path="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" 
     />
  </circle>
</svg>

注意 animateMotion 元素和 path 属性的值。在上面的代码片段中,一切都完美无缺。

但是,在下面的代码片段中,我们还没有在 animateMotion 元素上添加 path 属性,因此我们尝试使用 JavaScript 插入它。在完成的程序中,path 属性将填充动态值。

当 DOM 结构相同时,为什么 animateMotion 元素不能像第一个片段中那样工作?

let animateMotion = document.querySelector( `animateMotion` );

animateMotion.setAttributeNS(
  `http://www.w3.org/2000/svg`, `path`, 
  `M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z`
);
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body { display: flex; justify-content: center; align-items: center; }
svg { width: 12.5rem; height: 6rem; }
path { fill: none; stroke: #444; stroke-width: 5px; }
circle { opacity: 0.75; fill: #0dd; }
<svg>
  <path
    d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" 
  />

  <circle r='10'>
    <animateMotion 
      dur="5s" repeatCount="indefinite"
     />
  </circle>
</svg>

经过检查,我们可以看到浏览器似乎已正确添加 path 属性,与第一个代码段的 HTML 中显示的完全一样:

尝试将 null 作为 setAttributeNS

中的 namespace

let animateMotion = document.querySelector( `animateMotion` );

animateMotion.setAttributeNS(
  null, `path`, 
  `M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z`
);
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body { height: 100%; }
body { display: flex; justify-content: center; align-items: center; }
svg { width: 12.5rem; height: 6rem; }
path { fill: none; stroke: #444; stroke-width: 5px; }
circle { opacity: 0.75; fill: #0dd; }
<svg>
  <path
    d="M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z" 
  />

  <circle r='10'>
    <animateMotion 
      dur="5s" repeatCount="indefinite"
     />
  </circle>
</svg>