svg 文件中的 JavaScript 上下文



我计划直接在 svg 文件中包含一些交互性(而不是引用所述 svg 文件的 html 文件(。

这是我的 svg 测试文件:

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="210" height="297" viewbox="0 0 210 297" xmlns="http://www.w3.org/2000/svg">
  <script type="text/javascript"><![CDATA[
      function test() {alert("Test");}
      ]]>
  </script>
  <rect x="10" y="20" width="100" height="200" style="fill:red" onclick="test()"></rect>
  
</svg>

我不完全确定执行JavaScript的上下文是什么。svg 标准有点独立于 html。

例如,如果我使用 document ,它会始终引用 self 吗(而不是 html 文档,如果在那里引用了这个 svg(?也许不行 使用window.alert() ,因为它保证只存在于网络浏览器上下文中?svg 查看器应用程序是否期望一些要求,这些应用程序指定在"裸"打开文件时向其 JavaScript 公开哪些全局对象?或者也许没有上下文是保证的,它由 svg 文件查看器的开发者来决定向文件内 JavaScript 公开什么(如果有的话(全局对象。

如果你使用 <img> 标签引用你的 svg 文件,JavaScript 将被完全忽略。

如果您使用 <object> 标签,如下所示,JavaScript 将起作用,但document仅引用您的 SVG 文件,并且无法从包含 <object> 标签的 HTML 文件中访问document变量。您可以通过在 SVG 文件中使用 console.log(document) 来查看这一点。

<object data="circle.svg" type="image/svg+xml">

如果您希望 JavaScript 能够访问您的 HTML document,您需要将 SVG 代码的内容直接嵌入到 HTML 中,而不是将其放在单独的文件中。

下面的工作代码显示了上述所有三个示例。

<!-- This won't log anything, JavaScript disabled -->
<img src="https://tchaffee.github.io/so-svg/square.svg"/>
<!-- "document" here will reference the XML SVG document -->
<object data="https://tchaffee.github.io/so-svg/square.svg" type="image/svg+xml"></object>
<!-- "document" here will reference the HTML document -->
<svg width="210" height="297" viewBox="0 0 210 297"
     xmlns="http://www.w3.org/2000/svg">
  <script type="text/javascript"><![CDATA[
    function test(evt) {
      console.log('Internal HTML document:');
      console.log(document);
    }
  ]]></script>
  <rect x="10" y="20" width="100" height="200" style="fill:blue" onclick="test()"></rect>
</svg>

以防万一链接断开,这是 https://tchaffee.github.io/so-svg/square.svg 的代码

<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="210" height="297" viewbox="0 0 210 297" xmlns="http://www.w3.org/2000/svg">
  <script type="text/javascript"><![CDATA[
    function test(evt) {
      console.log('External SVG document:');
      console.log(document);
    }
  ]]></script>
  <rect x="10" y="20" width="100" height="200" style="fill:red" onclick="test()"></rect>
</svg>

对于包含在 html 中的 svg 文件,上下文与 html DOM 元素相同 - 但是当您将 svg 引用用作单独的文档时,您只能访问此文档的上下文。要访问元素和事件,请使用onclick="test(this,event)"(在包含或单独的文件中(。

function short() {
  document.querySelector('rect').setAttribute('height',100);
}
button {display: block}
<button id="msg" onclick="short()">Click on box and/or on this button</button>
<svg width="210" height="297" viewbox="0 0 210 297" xmlns="http://www.w3.org/2000/svg">
  <script type="text/javascript"><![CDATA[
    function test(rect,event) {
      let w= +rect.getAttribute("width")
      rect.setAttribute("width", w+10)
      msg.innerText+=' #'
      console.log({rect,event,document,window})
    }
  ]]></script>
  <rect x="10" y="20" width="100" height="200" style="fill:red" onclick="test(this,event)"></rect>
</svg>

在上面的代码片段中 - 嵌入的 svg js 可以访问 svg 之外(更改<div id="msg">内容( - 其他 html 脚本(在 svg 之外(可以访问 svg。如果 svg 包含在<img src="test.svg">则嵌入的 js 将永远不会被执行。如果 svg 包含在<object data="circle.svg" type="image/svg+xml">则 JS 将被执行,但作为单独的文档执行,因此它无法访问<div id="msg">并且外部 html 脚本只能访问对象,但无法访问 svg 元素。

最新更新