【问题标题】:Create and access SVG tag with jQuery? [duplicate]使用 jQuery 创建和访问 SVG 标签? [复制]
【发布时间】:2012-08-01 07:50:53
【问题描述】:

是否可以像这样在 jQuery 中创建 SVG 标签:

var dragSVG = $('<svg xmlns="http://www.w3.org/2000/svg"></svg>');
dragSVG.append('<rect x="0" y="0" width="20" height="20" style="fill:red"></rect>');

如果是这样,如何访问 DOM? IE。如果是 HTML,我会执行以下操作:

return dragSVG.html();

但由于它不是 HTML,所以会引发异常......或者我错过了一些完全基本的东西!?

编辑:

我将尝试更清楚地解释我想要实现的目标;我有一个代表 SVG '项目' 的按钮,可以将它拖到主 SVG 画布上。当用户开始拖动时,我想在鼠标下显示 SVG“项目”以提供用户反馈。当用户将它放到画布上时,我需要将“项目”移动到主画布上。

      $('#testBtnDrag').draggable({
          opacity: 0.7,
          revert: 'invalid',
          cursorAt: { top: 0, left: 0},
          helper: function (event) {
              var dragSVG = '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20"><rect x="0" y="0" width="20" height="20" style="fill:red"></rect></svg>';
              return dragSVG;
          }              
      });

      // I can't attach the droppable to the SVG tag directly, IE / FF don't work with this
      // so we have to attach it to a <div> tag that wraps the <svg>.
      $('#drawArea').droppable({
        accept: '.svg-item',
        drop: function (event, ui) {
          // Get the mouse offset relative to the <svg> canvas
          var posX = event.originalEvent.clientX - $(this).offset().left;
          var posY = event.originalEvent.clientY - $(this).offset().top;

          // Get the dragged element and put it onto the "main" canvas
          var rawSVG = ui.helper.children().html()  // This won't work!
          var mainCanvas = $('#drawArea > svg');
          mainCanvas.append(rawSVG);
        }
      });

  });

【问题讨论】:

    标签: javascript jquery svg


    【解决方案1】:

    不要破解 JQuery;只需创建一个简单的单行函数,该函数创建一个 SVG 元素并将返回的元素包装在 JQuery 中,然后您可以在其上使用任何您想要的 JQuery 函数,即:

        function createSvg(tagName) {
            return document.createElementNS("http://www.w3.org/2000/svg", tagName);
        }
        function sayHi() { 
            alert('hi'); 
        }
        $(document).ready(function() {
            var svg = $(createSvg("svg"))
                .attr('width', 500)
                .attr('height', 500);
            $('body').append(svg);
            var rect = $(createSvg("rect"))
                .attr("id","rect1")
                .attr("x","20")
                .attr("y","150")
                .attr("height","72")
                .attr("width","120")
                .attr("rx","20")
                .attr("stroke","black")
                .attr("fill","white");
            $("svg").append(rect);
            $("#rect1").on("click", sayHi);
            $("#rect1").attr("x",150);
        });
    

    【讨论】:

      【解决方案2】:

      我已经将 SVG 与 jQuery 一起使用,无需在 jQuery 核心库中进行任何更改。您只需要生成如下所示的 svg 标签

      var svg = $('&lt;svg&gt;&lt;/svg&gt;').attr('xmlns','@987654321@');

      使用 jquery 并通过 $('body').html(svg); jQuery 将其添加到 dom 然后将其视为 dom 对象,您可以在此标记上调用任何与 dom 相关的方法,就像您可以添加属性等一样。您可以将 var svg 保持在全局范围内,这样您可用于进一步参考,您还可以分配 id 或 class 属性,以便您可以使用 jquery 访问它。

      【讨论】:

      • 这不起作用,因为如果使用 XHTML 命名空间创建 SVG 将不会呈现。
      【解决方案3】:

      一个&lt;svg&gt;&lt;path&gt;等都是SVGAnimatedString对象,jQuery本身不能产生它们,因为是使用@ 987654325@ 用于创建标签的功能。 jQuery 的简单 hack 看起来像:

          // line 526 in jquery-X.X.X.js, in my case it is jquery-1.9.1.js   
          // Single tag
          if ( parsed ) {
              // ----------------------------------------------------
              var xml_html_element;
              if ( parsed[1] == "svg" || parsed[1] == "path" ) {
                  xml_html_element = context.createElementNS( "http://www.w3.org/2000/svg", parsed[1] );
              } else {
                  xml_html_element = context.createElement( parsed[1] );
              }
              return [xml_html_element];
              // ----------------------------------------------------
              //return [ context.createElement( parsed[1] ) ];
      
          }
      

      现在,你可以像这样使用 jQuery:

      var $svg = $("<svg>").attr({'version': "1.1"});
      var $path = $("<path>").attr({
          'd': 'M' + 10 + ',' + 100 + ' C' + 200 + ',' + 150 + ' ' + 200 + ',' + 170 + ' ' + 300 + ',' + 250,
          'fill': "none",
          'stroke': "rgba(100,100,100,0.9)",
          'stroke-width': "1"
      });
      var $body = $("body");
      $body.append($svg.append($path));
      

      当然,为了您的个人需要,您可以在此 hack 中扩展 SVG 标签的数量:

      parsed[1] == "svg" || parsed[1] == "path" || parsed[1] == "line" || etc. ...   
      

      【讨论】:

      • 您可以在那里看到的所有svg标签列表:developer.mozilla.org/en-US/docs/SVG/Element
      • +1,但有件事告诉我直接编辑 jquery 源代码可能不是解决这个问题的最佳方法。
      • 这只是一个有趣的轻量级技巧,如实验和私人使用。当然不是用于商业用途!
      • 我猜在生产的情况下你会做一个简单的函数,也许叫它$svg,它接受一个SVG标签,创建SVG DOM元素,然后将它包装在一个jQuery中对象。
      【解决方案4】:

      SVG 本质上是一种 XML 文件格式。请改用 parseXML()。如果这不起作用,请尝试 http://keith-wood.name/svggraphRef.html.

      【讨论】:

      • ParseXML 允许我在 XML 上使用 jQuery 函数,就好像它是 html 一样,但我认为它不会允许我重新访问“原始”DOM,对吗?请参阅上面的编辑。
      • 我还是有点困惑。你所谓的 SVG 画布实际上是一个
        并且你正在将你的 绘制到另一个在画布上移动的
        上?
      • 抱歉,我不想直接深入细节来混淆问题,但我使用 Raphael SVG 库在
        中创建“主画布”带有 ID“drawArea”的标签。因此,虽然您的回答在遍历主画布元素时有很大帮助,但我仍然看不到如何将 标记从 ui.helper 中取出
      • 好吧,我不了解 Raphael 库,但也许您可以坚持使用更简单的方法?看看这里pnorg.org/index.php?race=2,这是我写的一些游戏。 svg 图像直接编码到网页中。如果您将鼠标移到聊天消息上,我会使用简单的 getElementById() 在轨道周围移动气泡图像。我不确定这是否会对您有所帮助,但请看一下。
      猜你喜欢
      相关资源
      最近更新 更多
      热门标签