3

我有一个 SVG 文档,其中绘制了三个圆圈:

<?xml version="1.0"?>
<svg width="450" height="80" xmlns="http://www.w3.org/2000/svg">
    <script>
    document.fillCircle = function(id) {
        var circles = document.getElementsByTagName('circle'),
            circle  = document.getElementById(id);

        [].forEach.call(circles, function(circle) {
            circle.setAttribute('fill','#ffffff');
        });

        circle.setAttribute('fill', '#000000');
    }
    </script>
    <g>
        <line y1="35" x1="35" y2="35" x2="375" stroke-width="3" stroke="#000000"/>
        <circle id="state1" r="30" cy="35" cx="35"  stroke-width="3" stroke="#000000" fill="#ffffff" onclick="fillCircle(this.id);"/>
        <circle id="state2" r="30" cy="35" cx="205" stroke-width="3" stroke="#000000" fill="#ffffff" onclick="fillCircle(this.id);"/>
        <circle id="state3" r="30" cy="35" cx="375" stroke-width="3" stroke="#000000" fill="#ffffff" onclick="fillCircle(this.id);"/>
    </g>
</svg>

出于测试目的,我有该onclick=""方法,但实际上该文档是我的 html 文档中的一个对象:

<object id="test" data="test-vector.svg" width="100px" height="100px"></object>

我有一个数据集,这三个圆圈显示了每个项目的“进度”。我通过从服务器中提取新列表来定期更新 JSON 集。对于每个更改的项目,我想更新实心圆圈。

我想根据一些 javascript 更新 svg。但是,我无法进入 SVG 的 DOM。我真的不在乎svg 是否在 svg 中,fillCircle()是否必须使用或其他东西,但这种 javascript 对我不起作用。<embed><object>

<html>
<body>
    <object id="test" data="test-vector.svg"></object>
    <script>
        var svg = document.getElementById('test');
        console.log(svg);
        svg.fillCircle('state2');
    </script>
</body>
</html>

我尝试了我在 SO 上找到的几件事,比如this onethis one,但无论我测试什么,例外总是:

Uncaught TypeError: Object #<HTMLObjectElement> has no method 'fillCircle'
4

2 回答 2

8

var object = document.getElementById("test")会给你对象元素,但在对象加载之前你不能调用它。一旦你有了它,你就可以使用 object.contentDocument 来处理嵌入的 svg 文档。

<html>
<body>
    <object id="test" data="test-vector.svg" onload="f()" ></object>
    <script>
        function f() {
            var svg = document.getElementById('test');
            svg.contentDocument.fillCircle('state2');
        }
    </script>
</body>
</html>
于 2012-10-08T15:47:10.723 回答
2

Why don't you embed the SVG directly in your HTML code (using SVG tags)? According to W3, this works in all modern browsers (and IE >= 9). Accessing and changing the circles' properties with JS is then trivial...

<html>
    <body>
        <svg>...</svg>
    </body>
</html>


If you want to keep your HTML/SVG structure though, you can do the following:

var svg = document.getElementById("test");
svg.onload = function(){
    svg.contentDocument.fillCircle("state2");
};

The trick is to wait for the SVG object to load (onload event); not till then you can safely use the contentDocument property. Btw, this is also described in this solution on SO (you posted a link to it). ;)

于 2012-10-08T15:58:52.440 回答