【问题标题】:Can I embed JavaScript code within an SVG file?我可以在 SVG 文件中嵌入 JavaScript 代码吗?
【发布时间】:2019-09-16 22:33:20
【问题描述】:

请看下面的代码。我一生都无法弄清楚阻碍onclick 事件的JavaScript 出了什么问题。当然,CSS 样式运行良好,但即使 JS 在 codepen 上按原样运行,它也不会在这里运行。

<svg id="mySVG" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
  <style>
    #mySVG {
      cursor: pointer;
    }
    @keyframes circleGrow {
      to {r:50}
    }
    #myCircle {
      animation: circleGrow 1s 1s forwards;
    }
    @keyframes strokeDraw {
      to {stroke-dashoffset: 0}
    }
    @keyframes toFill {
      to {fill: white;}
    }
    #myText {
      animation: strokeDraw 2.5s 2s linear forwards,
        toFill 1s 4.5s linear forwards;
    }
  </style>
  <script>
    //<![CDATA[
      var mySVG = document.getElementById("mySVG"),
        myCircle = document.getElementById("myCircle"),
        myText = document.getElementById("myText");

    mySVG.onclick = function(){

      myCircle.style.animation = "null";
      myText.style.animation = "null";

      setTimeout(function(){

        myCircle.style.animation = "";
        myText.style.animation = "";

      },10);

    }
    //]]>

  </script>
  <circle id="myCircle" cx="50" cy="50" r="0" fill="maroon" />
  <text id="myText" x="50%" y="50%" text-anchor="middle" alignment-baseline="central" font-size="40" fill="transparent" stroke="white" stroke-dasharray="190" stroke-dashoffset="190">Hello</text>
</svg>

【问题讨论】:

    标签: javascript animation svg cdata embedding


    【解决方案1】:

    你必须把script部分放在svg元素之后,因为解释是从上到下进行的,JS代码不能考虑不存在的元素(因为它们只会在后面定义)。

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <title>Document</title>
      <style>
        body { background-color: cornflowerblue }
      </style>
    </head>
    <body>
      <svg id="mySVG" viewBox="0 10 160 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
        <style>
          #mySVG { cursor: pointer; }
          @keyframes circleGrow { to {r:50} }
          #myCircle { animation: circleGrow 1s 1s forwards; }
          @keyframes strokeDraw { to {stroke-dashoffset: 0} }
          @keyframes toFill { to {fill: white;} }
          #myText {
            animation: strokeDraw 2.5s 2s linear forwards,
              toFill 1s 4.5s linear forwards;
          }
        </style>
        <circle id="myCircle" cx="50" cy="50" r="0" fill="maroon" />
        <text id="myText" x="50%" y="50%" text-anchor="middle" alignment-baseline="central" font-size="40" fill="transparent" stroke="white" stroke-dasharray="190" stroke-dashoffset="190">Hello</text>
        <script>
          //<![CDATA[
            var mySVG    = document.getElementById("mySVG")
              , myCircle = document.getElementById("myCircle")
              , myText   = document.getElementById("myText")
              ;
            mySVG.onclick = function()
            {
              myCircle.style.animation = "null";
              myText.style.animation   = "null";
    
              setTimeout(function()
              {
                myCircle.style.animation = "";
                myText.style.animation   = "";
              },10);
            }
          //]]>
        </script>
      </svg>
    </body>
    </html>
    

    【讨论】:

    • 哈!完美的!!!呸!早该想到的。但这就是stackoverflow存在的原因!!!
    • @RobertoMatthews stackoverflow 的原理是验证答案,它会给出声誉积分,这让我有更好的机会找到工作
    【解决方案2】:

    我不知道您所说的“它不会在这里工作”是什么意思,但原因可能是 DOM 尚未准备好时的竞争条件。您可以尝试将代码包装在文档就绪处理程序中:

    <html>
    
    <body><svg id="mySVG" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
      <style>
        #mySVG {
          cursor: pointer;
        }
        @keyframes circleGrow {
          to {r:50}
        }
        #myCircle {
          animation: circleGrow 1s 1s forwards;
        }
        @keyframes strokeDraw {
          to {stroke-dashoffset: 0}
        }
        @keyframes toFill {
          to {fill: white;}
        }
        #myText {
          animation: strokeDraw 2.5s 2s linear forwards,
            toFill 1s 4.5s linear forwards;
        }
      </style>
      <script>
        //<![CDATA[
    
        // Equivalent of jQuery $(document).ready() in vanilla JavaScript
        // (taken from http://youmightnotneedjquery.com/#ready )
        function ready(fn) {
          if (document.readyState != 'loading'){
            fn();
          } else {
            document.addEventListener('DOMContentLoaded', fn);
          }
        }
    
        ready(function() {
          var mySVG = document.getElementById("mySVG"),
              myCircle = document.getElementById("myCircle"),
              myText = document.getElementById("myText");
    
          mySVG.onclick = function(){
    
            myCircle.style.animation = "null";
            myText.style.animation = "null";
    
            setTimeout(function(){
    
              myCircle.style.animation = "";
              myText.style.animation = "";
    
            },10);
          }
        })
        //]]>
    
      </script>
      <circle id="myCircle" cx="50" cy="50" r="0" fill="maroon" />
      <text id="myText" x="50%" y="50%" text-anchor="middle" alignment-baseline="central" font-size="40" fill="transparent" stroke="white" stroke-dasharray="190" stroke-dashoffset="190">Hello</text>
      </svg></body>
    
    </html>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-02
      • 1970-01-01
      • 2010-09-15
      • 2010-12-25
      • 2016-09-22
      • 2011-09-26
      • 1970-01-01
      • 2014-06-28
      相关资源
      最近更新 更多