【问题标题】:Add click event on elements of an embedded SVG in javascript在 javascript 中的嵌入式 SVG 元素上添加点击事件
【发布时间】:2012-04-14 06:34:19
【问题描述】:

我得到this SVG image from Wikipedia 并使用此代码将其嵌入到网站中:

<embed src="circle1.svg" type="image/svg+xml"/>

如果你运行它,你可以检查元素并查看源代码。图像中的所有国家都是独立的元素。如果我点击一个国家,我想提醒那个国家的 id,因为每个国家在 SVG 中都有一个由两个字母组成的 id。有谁知道这样做的方法?如果我把它放在一个元素中会更容易吗?

【问题讨论】:

    标签: javascript html canvas svg


    【解决方案1】:

    这是一个example,它应该与您尝试执行的操作非常相似。它使用 而不是 ,但这只是一个小细节。关于如何从父文档获取嵌入文档的 DOM,请参见另一个 example,两者之间略有不同。

    还请注意,维基百科的 svg 地图非常大,因此您需要在实际使用网站之前优化 svg,例如 SVG CleanerSVG Scour

    【讨论】:

    • 是的,这几乎正是我想要做的。但它只是我还是第一个示例仅适用于 Internet Explorer?
    • 它在 Opera 中也能正常工作。但是 webkit 和 gecko 似乎不能在 display:none 子树中的元素上正确计算 bbox。我已经用可见性替换了那些:隐藏,现在悬停标签显示在所有浏览器中。
    • Safari 10 无法设置嵌入式 SVG 的颜色
    • @BrianStallter 好的,是的,在 Chrome Canary v61 中,导出按钮只是弹出一个空窗口,也许是 Chrome 中的一些新策略?它在 Chrome v59 中运行良好。
    【解决方案2】:

    如果您的 SVG 包含在 DOM 中,您可以使用与基本 HTML 相同的方式将事件侦听器附加到单独的元素。使用 jQuery 的一个例子是:http://jsfiddle.net/EzfwV/

    更新:大多数现代浏览器都支持内联 svg,因此要将源代码加载到 DOM 中,您所要做的就是从资源中加载它(使用类似 jQuery 的 load() 之类的东西)。

    编辑:更具体的例子http://jsfiddle.net/EzfwV/3/

    【讨论】:

    • 我尝试将 svg 加载到 id 为“map”的 div 中。但是我收到警报,我看不到 svg 图像 $('#map').svg(); var svg = $('#map').svg('get'); svg.load('images/world.svg',{onLoad: function(){ alert('ready'); }});
    • 你的问题是你试图将 world.svg 加载到现有的 svg 标签中? (我想)。尝试类似 $('#map').load('images/world.svg', function(){ alert('ready')});
    【解决方案3】:

    好的,使用您的 cmets 我找到了问题的答案。我在 svg 本身中添加了这段代码。

    <script type="text/javascript"> <![CDATA[
        function addClickEvents() {
            var countries = document.getElementById('svg1926').childNodes;
            var i;
            for (i=0;i<countries.length;i++){
                countries[i].addEventListener('click', showCountry);
            }
        }
    
        function showCountry(e) {
            var node = e.target;
            if (node.id != 'ocean') {
                node = getCorrectNode(node);
            }
            alert(node.id);
        }
    
        function getCorrectNode(node) {
            if (node.id.length == 2 || node.id == 'lakes') {
                return node;
            }
            return getCorrectNode(node.parentNode);
        }
    ]]> </script>
    

    函数 addClickEvents 在 svg 加载时触发。 但我还有另一个问题。我必须使用

    将此 svg(带有代码)嵌入到 HTML 文档中
    <embed src="circle1.svg" type="image/svg+xml" />
    

    我必须将它放入 HTML 文档中的 div 中,而不是提醒 id。 如何从 svg 中获取此 id?

    【讨论】:

      【解决方案4】:

      2016 年 7 月更新

      现在可以响应来自embed 元素的事件,条件是您嵌入了来自同一域的内容。我以 JSFiddle 的形式创建了一个快速演示。最重要的是可以通过embeddingElement.@987654322@访问嵌入的文档。从那里,可以访问 SVG 元素并安装点击事件处理程序。

      实现说明:在演示中,我将事件处理程序添加到所有path 元素。出于性能原因,您可能希望将单个事件处理程序添加到 SVG,然后在处理程序中使用事件目标。编辑:就像在这个 updated Fiddle.

      旧答案

      快速的谷歌搜索给我带来了here。我想这就是你问题的答案,对吧?

      在这里总结一下:不可能在embed 元素上捕获事件,不幸的是,唯一的解决方案是修改 SVG 文件。

      这是一个如何将 JavaScript 嵌入 SVG 文件的小示例 (JSFiddle)。它基于来自 IBM developerWorks 的 example

      <svg>
        <script type="text/javascript">
          <![CDATA[
          var redVal = 0;
          var greenVal = 0;
          var blueVal = 0;
      
          function changeCol(evt) {
             redVal = Math.round(Math.random() * 255);
             greenVal = Math.round(Math.random() * 255);
             blueVal = Math.round(Math.random() * 255);
             evt.target.setAttribute("fill",
                   "rgb(" + redVal + "," + greenVal + "," + blueVal + ")");
      
          }
          // ]]>
        </script>
        <circle cx="200" cy="200" r="100" fill="blue"
                onclick="changeCol(evt)" />
      </svg>
      

      【讨论】:

      • 没有。我不想在整个 svg 中添加点击事件,而是在其中的每一层上添加多个点击事件
      • 大安:你确定吗?根据答案,如果不将 javascript 嵌入到 SVG 文档中,您将无法处理点击事件。事实上,您甚至看不到 embed 元素上的事件,更不用说 SVG 元素上的事件了。我不知道该文件的许可等,但如果可以,我建议您编辑文档以添加点击处理程序。
      • 这正是我的想法。我已经编辑了我的答案,以包含另一个解释如何做到这一点的教程。
      • 所以我必须在 svg 中手动添加每个国家/地区的点击事件,然后将代码粘贴到 html 文档中?
      • 当我尝试这段代码时,我得到“evt.getTarget 不是一个函数”。我必须改用 evt.target。
      【解决方案5】:

      一个简单的方法是

      • 使用 javascript 在 SVG 中动态创建路径
      • 动态添加样式
      • 向路径添加事件
      • 附加到现有的 SVG。

      脚本

       <svg id="mySvg"></svg>
      

      var XMAX = 500;
      var YMAX = 500;
      var _xx=10;
      var _reg=100;
      var _l=10;
      // Create PATH element
      for(var x=1;x<20;x++)
      {
      var pathEl = document.createElementNS("http://www.w3.org/2000/svg", "path");
      pathEl.setAttribute('d','M'+_l+' 100 Q 100  300 '+_l+' 500' );
      pathEl.style.stroke = 'rgb('+(_reg)+',0,0)';
      pathEl.style.strokeWidth = '5';
      pathEl.style.fill = 'none';
          $(pathEl).mousemove(function(evt){$(this).css({"strokeWidth":"3","stroke":"#ff7200"}).hide(100).show(500).css({"stroke":"#51c000"})});
      
      $('#mySvg').append(pathEl);
      _l+=50;
      }
      

      Live Demo in JSFiddle

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-02
        • 1970-01-01
        • 2017-01-18
        • 2021-05-14
        相关资源
        最近更新 更多