定义并在动态创建的页面中使用

defs and use in a dynamically created page

本文关键字:动态 创建 定义      更新时间:2023-09-26

我用javascript指令从头构建一个svg文档。首先创建id为

的defs
<defs><g id="id45"> ... </g></defs>

并正确调用它们

<use xlink:href="#id45" x="0" y="0">

唉,它没有显示任何"used"元素。

然而,当我将javascript生成的结果(Firefox 40.0.3)复制粘贴到一个全新的.html文件中时,一切都很好。正如你在这里看到的(参见丑陋的粉色和蓝色盒子):

<html lang="jap">
    <head>
        <meta charset="utf-8">
        <title>plot</title>
        <link rel="stylesheet" type="text/css" href="screen.css">
    </head>
    <body>
<svg viewBox="-10 -10 456 129" width="456px" height="129px" id="kanji_grid">
<defs><g id="kanji_grid_box"><rect height="129" width="129" y="0" x="0"></rect><line y2="129" x2="64.5" y1="0" x1="64.5"></line><line y2="64.5" x2="129" y1="64.5" x1="0"></line></g></defs>
<rect class="frame" height="129" width="456" y="-10" x="-10"></rect><g transform="translate(0, 0)"><use style="fill:blue" xlink:href="#kanji_grid_box" y="10" x="10"></use><path class="main_stroke" d="M53.21,18.37C53.75,20.5,53.47,21.78,52.96,23.62C50.38,33,42.62,52.75,35.75,64C34.36,66.27,34.75,67.5,36.75,67.5C48.38,67.5,65.21,74.98,75.58,83.91C78.14,86.12,80.26,88.42,81.75,90.75"></path><circle class="start_circle" r="6" cy="18.37" cx="53.21"></circle></g><g transform="translate(109, 0)"><use style="fill:blue" xlink:href="#kanji_grid_box" y="10" x="10"></use><path d="M53.21,18.37C53.75,20.5,53.47,21.78,52.96,23.62C50.38,33,42.62,52.75,35.75,64C34.36,66.27,34.75,67.5,36.75,67.5C48.38,67.5,65.21,74.98,75.58,83.91C78.14,86.12,80.26,88.42,81.75,90.75"></path><path class="main_stroke" d="M69.62,42.18C70.12,43.88,70.25,45.75,69.61,48.11C65.93,61.8,54.61,81.6,27,91.75"></path><circle class="start_circle" r="6" cy="42.18" cx="69.62"></circle></g><g transform="translate(218, 0)"><use style="fill:blue" xlink:href="#kanji_grid_box" y="10" x="10"></use><path d="M53.21,18.37C53.75,20.5,53.47,21.78,52.96,23.62C50.38,33,42.62,52.75,35.75,64C34.36,66.27,34.75,67.5,36.75,67.5C48.38,67.5,65.21,74.98,75.58,83.91C78.14,86.12,80.26,88.42,81.75,90.75"></path><path d="M69.62,42.18C70.12,43.88,70.25,45.75,69.61,48.11C65.93,61.8,54.61,81.6,27,91.75"></path><path class="main_stroke" d="M13.88,50.43C17.36,51.82,21.14,51.28,24.76,50.96C44.28,49.26,66.8,46.88,85.37,46.33C89.03,46.22,92.58,46.23,95.99,47.75"></path><circle class="start_circle" r="6" cy="50.43" cx="13.88"></circle></g><g class="final" transform="translate(327, 0)"><path d="M53.21,18.37C53.75,20.5,53.47,21.78,52.96,23.62C50.38,33,42.62,52.75,35.75,64C34.36,66.27,34.75,67.5,36.75,67.5C48.38,67.5,65.21,74.98,75.58,83.91C78.14,86.12,80.26,88.42,81.75,90.75"></path><path d="M69.62,42.18C70.12,43.88,70.25,45.75,69.61,48.11C65.93,61.8,54.61,81.6,27,91.75"></path><path d="M13.88,50.43C17.36,51.82,21.14,51.28,24.76,50.96C44.28,49.26,66.8,46.88,85.37,46.33C89.03,46.22,92.58,46.23,95.99,47.75"></path></g>
</svg>
</body></html>

可能是动态生成的<defs>还不够快?我怎样才能避开这个呢?

下面是我用来构建整个svg文档的函数
Node.prototype.svg_grow = function(node_name, node_attr) {
    /*
        node_name is a string
        node_attr is a map of string to string
    */
    var n = document.createElementNS("http://www.w3.org/2000/svg", node_name);
    this.appendChild(n);
    if (typeof node_attr !== 'undefined') {
        for (let key in node_attr) {
            n.setAttribute(key, node_attr[key]);
        }
    }
    return n;
}

然后我用这种结构:

<!DOCTYPE html><html><head></head><body>
<svg id="kanji_grid">
</svg>
<script>
var s_svg = document.getElementById("kanji_grid");
var s_defs = s_svg.svg_grow('defs');
var s_g = s_defs.svg_grow('g', {'id':"kanji_box"});
s_g.svg_grow('rect', {'x':0, 'y':0, 'width':s+2*b, 'height':s+2*b});
etc...
</script>
</body></html>

您正在尝试使用setAttribute在<use>元素上创建xlink:href属性,不是吗?

这不起作用,因为您需要使用setAttributeNS在xlink命名空间中创建它。例如

node.setAttributeNS("http://www.w3.org/1999/xlink", "xlink:href", "#id45");