【问题标题】:Get innerHTML of svg-tag result in undefined in IE获取 svg-tag 的 innerHTML 结果在 IE 中未定义
【发布时间】:2015-03-23 16:13:03
【问题描述】:

我在使用 Internet Explorer 中的 javascript 获取 svg 标记的 html 内容时遇到了一些问题。

我的javascript代码如下:

console.log($('.icon')[0].innerHTML);

和我的 html 文档中的标签:

<svg class="icon"><use>testing</use></svg>

这在 Chrome、Firefox 和我们拥有的东西中运行良好,但在 Internet Explorer 中我留下了一个未定义的错误。是不是我的 Javascript 和 jQuery 的混合体?

为什么我似乎无法获取我的 svg-tag 的内容?我尝试了一些不同的方法,但经常得到“SCRIPT5007:无法设置未定义或空引用的属性‘innerHTML’”

帮帮我:)谢谢!

【问题讨论】:

  • 我只尝试了 document.getElementsByTagName('svg')[0].innerHTML。 undefined 还是一样的错误。
  • 在 IE11 上,我能够简单地将 SVG 元素附加到一个空的 div 并获得 确实 返回正确内容的 its inninterHTML。包括 &lt;svg&gt; 标签本身,但这并不难用正则表达式。
  • outerHTML 也是带有 SVG 元素的 IE 的问题:stackoverflow.com/q/29888050/633107

标签: javascript jquery internet-explorer svg


【解决方案1】:

如何使用XMLSerializer。以某种方式获取元素,然后执行此操作...

console.log(new XMLSerializer().serializeToString(element));

【讨论】:

    【解决方案2】:

    Internet Explorer 当前不支持 SVG 元素上的 innerHTML 方法。但是,我们确实在内部打开了一个问题,以跟踪我们对该功能的考虑。与此同时,我将探索其他解决方案,例如 InnerSVG polyfill,据称它适用于 Internet Explorer 9 及更高版本。

    【讨论】:

    • 是的,我看到了 InnerSVG polyfill。但认为这必须是一种更简单的方法,至少对于我的小项目来说。我刚刚想出了我的答案,它为我解决了这个问题。
    • Polyfill 非常简单;你只需参考它,你就完成了。 Internet Explorer、Chrome 和 Firefox 都继续使用相同的代码。
    • 我们使用一个对象标签并从一个单独的 url 获取我们的 svg。 innerSVG 似乎对我不起作用。有人对此有任何想法吗?
    • @Sampson,您是否有一个链接,我们可以在其中跟踪问题的状态以支持 svg 元素的 innerHTML?
    • 嗨@Samspon :-)
    【解决方案3】:

    以下代码将为您提供来自给定 SVG 的字符串形式的内容。 它基于great answer of Robert Longson

    const svgNode = document.getElementsByTagName('svg')[0];
    const serializer = new XMLSerializer();
    
    const svgContent = Array.prototype.map.call(
      svgNode.childNodes, 
      (child) => serializer.serializeToString(child)
    ).join('');
    

    【讨论】:

      【解决方案4】:

      最终我找到了某种解决方案。也许是一种骇人听闻的方式?但至少对我有用。

      而不是获取我在 IE 中无法获取的原始 innerhtml。我尝试通过这样做来获取我的 svg-tag 中的每个元素节点:

      var element = document.getElementsByTagName('svg')[0].childNodes;
      for (i = 0; i < element.length; i++) {
          if (element[i].nodeName != '#text') {
              console.log(element[i]);
          }
      }
      

      【讨论】:

        【解决方案5】:

        console.log($('.icon').parent().html()); 在 IE11 中适合我。

        传递的字符串以 XML 声明开头 &lt;?xml version="1.0" encoding="iso-8859-1" ?&gt; 这似乎是作为 svg 节点的父级处理的。

        【讨论】:

        • 对我来说,这是一个非常简单和正确的解决方案。对我有用,谢谢。
        【解决方案6】:
        (function () {
            var svg = document.createElementNS("http://www.w3.org/2000/svg","svg");
            if(typeof svg["innerHTML"] !== "undefined") {
                return;
            }
        
            var node = $('<script type="text/svg_template"></script>');
        
            Object.defineProperty(SVGElement.prototype, 'innerHTML', {
                get: function() {           
                    try {
                        var childNode = this.firstChild;
                        while (childNode) {
                            node.append($.clone(childNode));
                            childNode = childNode.nextSibling;
                        }
                        return node.html();
                    } finally {
                        node.empty();
                    }
                }
            })
        })();
        

        设置html使用:

        $(svg).html()
        

        在 IE11 上测试

        【讨论】:

        • 非常适合 IE 11。jquery html() 也可以正常工作
        【解决方案7】:

        作为一种解决方法,您可以将 SVG 元素附加到临时 DIV,获取该 DIV 的内部 html 并从该字符串中删除 SVG 开始和结束标记。

        let parentHtml = $('<div />').append($('svg')).html();
        let svgInner = parentHtml.replace(/(<svg)([^<]*|[^>]*)/g, '').replace('</svg>', '');
        alert(svgInner);
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <svg xmlns="http://www.w3.org/2000/svg"
              xmlns:xlink="http://www.w3.org/1999/xlink">
            <rect x="10" y="10" height="100" width="100"
                  style="stroke:#ff0000; fill: #0000ff"/>
        </svg>

        【讨论】:

          【解决方案8】:

          对于实际的标签内部内容,您可以使用以下内容:

          function innerHTML(anySvgElement) {
            var d = document.createElement('div');
            d.appendChild(anySvgElement);
            // Given all SVG tags contain only letters and no numbers, we can strip out the outer tag (the anySvgElement itself)
            return d.innerHTML.replace(/<([a-z]+)[^>]+>(.*)(<\/\1>)/i, '$2')
          }
          

          对于纯文本内部内容,请改用node.textContent

          【讨论】:

            【解决方案9】:

            您可以创建自己的innerHTML,如下setSVGenter image description here

            其实只需要注意两步:创建SVG上下文标签和设置属性(带上下文)

            createElementNS 和 setAttributeNS 是你可能需要的两个方法!

            常见的命名空间如下:

            【讨论】:

            • 在 IE9 和 IE11 上测试
            猜你喜欢
            • 2022-01-21
            • 1970-01-01
            • 1970-01-01
            • 2015-06-17
            • 2017-10-19
            • 2021-04-26
            • 1970-01-01
            • 1970-01-01
            • 2016-12-27
            相关资源
            最近更新 更多