假设是这样的:

<html>
<head>
 <script type="text/javascript" src="jquery.js"></script>
 <script type="text/javascript">
 $(document).ready(function(){
  $("svg").append('<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red"/>');
 });
 </script>
</head>
<body>
 <svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100" width="200px" height="100px">
 </svg>
</body>

为什么我什么都看不见?

推荐答案

当您将标记字符串传递给$时,它将使用<div>(或其他适合于<tr>等特殊情况的容器)上的浏览器innerHTML属性解析为HTML.innerHTML无法解析SVG或其他非HTML内容,即使它可以解析,也无法判断<circle>应该在SVG名称空间中.

innerHTML在SVGElement上不可用,它只是HtmleElement的一个属性.目前也没有innerSVG属性或其他方式(*)将内容解析为SVGElement.因此,应该使用DOM样式的方法.jQuery不能让您轻松访问创建SVG元素所需的命名空间方法.实际上,jQuery根本不是为SVG设计的,许多操作可能会失败.

HTML5promise ,在future 的普通HTML(text/html)文档中使用<svg>而不使用xmlns.但这只是一个解析器破解(**),SVG内容仍然是SVG名称空间中的SVG元素,而不是HTMLElements,因此您将无法使用innerHTML,即使它们是HTML文档的一部分.

但是,对于今天的浏览器,您必须使用XHTML(适当地用作application/xhtml+xml;保存时使用.xhtml文件扩展名进行本地测试)才能使SVG工作.(不管怎样,这是有意义的;SVG是一个完全基于XML的标准.)这意味着您必须转义脚本挡路中的<个符号(或包含在CDATA节中),并包含XHTMLxmlns声明.示例:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"><head>
</head><body>
    <svg id="s" xmlns="http://www.w3.org/2000/svg"/>
    <script type="text/javascript">
        function makeSVG(tag, attrs) {
            var el= document.createElementNS('http://www.w3.org/2000/svg', tag);
            for (var k in attrs)
                el.setAttribute(k, attrs[k]);
            return el;
        }

        var circle= makeSVG('circle', {cx: 100, cy: 50, r:40, stroke: 'black', 'stroke-width': 2, fill: 'red'});
        document.getElementById('s').appendChild(circle);
        circle.onmousedown= function() {
            alert('hello');
        };
    </script>
</body></html>

*:虽然有DOM Level 3 LS's parseWithContext,但浏览器支持非常差.编辑添加:然而,虽然不能将标记注入SVGElement,但可以使用innerHTML将新的SVGElement注入HtmleElement,然后将其传输到所需的目标.不过可能会慢一点:

<script type="text/javascript"><![CDATA[
    function parseSVG(s) {
        var div= document.createElementNS('http://www.w3.org/1999/xhtml', 'div');
        div.innerHTML= '<svg xmlns="http://www.w3.org/2000/svg">'+s+'</svg>';
        var frag= document.createDocumentFragment();
        while (div.firstChild.firstChild)
            frag.appendChild(div.firstChild.firstChild);
        return frag;
    }

    document.getElementById('s').appendChild(parseSVG(
        '<circle cx="100" cy="50" r="40" stroke="black" stroke-width="2" fill="red" onmousedown="alert(\'hello\');"/>'
    ));
]]></script>

**:我讨厌HTML5的作者们似乎害怕XML,并决心把基于XML的功能塞进HTML的烂摊子里.XHTML多年前就解决了这些问题.

Html相关问答推荐

用完全透明的边框切割出圆圈?

Flexbox响应式图像不会缩小

srcset和大小总是下载最大的

有没有可能一个按钮,有焦点,然后再次点击它清除它的焦点,只是使用css?

如何获得一个背景图像,不是模糊的内部容器,但模糊的外部'

电话号码验证器(Angular )

只有一行上有溢出的CSS网格

使具有FLEX父项的溢出自动的子元素收缩

如何从多个TO中获取一个范围标记以溢出其父标记

如何使用css横向显示英文和中日韩文字?

为什么 Select 元素在带有数据绑定的Blazor上行为怪异?

可以';t使我的导航栏在HTML/CSS中正确对齐

带有图像的虚线边框

网格布局中的组件

UL 的行为就像它不属于任何类别

如何使我的设计适合与我的框架尺寸不同的视口?

子 div 在父 div 中溢出

如何为某些行具有 rowspan 的表的每个奇数行着色

本地 css 样式表未链接

辅助功能:alt 或 alt="" 用于装饰图像