如何使用 JavaScript 访问 SVG 元素?
我正在摆弄 SVG,希望能够在 Illustrator 中创建 SVG 文件并使用 JavaScript 访问元素。
这是 Illustrator 推出的 SVG 文件(它似乎还向我删除的文件开头添加了一堆垃圾):
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="276.843px" height="233.242px" viewBox="0 0 276.843 233.242" enable-background="new 0 0 276.843 233.242"
xml:space="preserve">
<path id="delta" fill="#231F20" d="M34.074,86.094L0,185.354l44.444,38.519l80.741-0.74l29.63-25.186l-26.667-37.037
c0,0-34.815-5.926-37.778-6.667s-13.333-28.889-13.333-28.889l7.407-18.519l31.111-2.963l5.926-21.481l-12.593-38.519l-43.704-5.185
L34.074,86.094z"/>
<path id="cargo" fill="#DFB800" d="M68.148,32.761l43.704,4.445l14.815,42.963l-7.407,26.667l-33.333,2.963l-4.444,14.074
l54.074-1.481l22.222,36.296l25.926-3.704l25.926-54.074c0,0-19.259-47.408-21.481-47.408s-31.852-0.741-31.852-0.741
l-19.259-39.259L92.593,8.316L68.148,32.761z"/>
<polygon id="beta" fill="#35FF1F" points="86.722,128.316 134.593,124.613 158.296,163.872 190.889,155.724 214.593,100.909
194.593,52.02 227.186,49.057 246.444,92.02 238.297,140.909 216.074,172.761 197.556,188.316 179.778,169.798 164.963,174.983
163.481,197.946 156.815,197.946 134.593,159.428 94.593,151.279 "/>
<path class="monkey" id="alpha" fill="#FD00FF" d="M96.315,4.354l42.963,5.185l18.519,42.222l71.852-8.148l20.74,46.667l-5.926,52.593
l-24.444,34.074l-25.185,15.555l-14.074-19.259l-8.889,2.964l-1.481,22.222l-14.074,2.963l-25.186,22.963l-74.074,4.444
l101.481,4.444c0,0,96.297-17.777,109.63-71.852S282.24,53.983,250.389,20.65S96.315,4.354,96.315,4.354z"/>
</svg>
正如您可能看到的,每个元素都有一个 ID,我希望能够使用 JavaScript 访问各个元素,以便我可以更改 fill
属性并响应单击等事件。
HTML 是非常基础的:
<!DOCTYPE html>
<html>
<head>
<title>SVG Illustrator Test</title>
</head>
<body>
<object data="alpha.svg" type="image/svg+xml" id="alphasvg" width="100%" height="100%"></object>
</body>
</html>
我想这确实是两个问题:
是否可以用这种方式来实现,而不是使用 Raphaël 或 jQuery SVG 之类的东西?
如果可以的话,技术是什么?
更新
目前,我已经使用 Illustrator 创建 SVG 文件,并且使用 Raphaël JS 创建路径并简单地从 SVG 文件复制点数据并将其粘贴到 path()
函数中。通过手动编码点数据来创建地图可能需要的复杂路径(据我所知)极其复杂。
I'm messing around with SVG and I was hoping I could create SVG files in Illustrator and access elements with JavaScript.
Here's the SVG file Illustrator kicks out (it also seems to add a load of junk to the beginning of the file that I've removed):
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="276.843px" height="233.242px" viewBox="0 0 276.843 233.242" enable-background="new 0 0 276.843 233.242"
xml:space="preserve">
<path id="delta" fill="#231F20" d="M34.074,86.094L0,185.354l44.444,38.519l80.741-0.74l29.63-25.186l-26.667-37.037
c0,0-34.815-5.926-37.778-6.667s-13.333-28.889-13.333-28.889l7.407-18.519l31.111-2.963l5.926-21.481l-12.593-38.519l-43.704-5.185
L34.074,86.094z"/>
<path id="cargo" fill="#DFB800" d="M68.148,32.761l43.704,4.445l14.815,42.963l-7.407,26.667l-33.333,2.963l-4.444,14.074
l54.074-1.481l22.222,36.296l25.926-3.704l25.926-54.074c0,0-19.259-47.408-21.481-47.408s-31.852-0.741-31.852-0.741
l-19.259-39.259L92.593,8.316L68.148,32.761z"/>
<polygon id="beta" fill="#35FF1F" points="86.722,128.316 134.593,124.613 158.296,163.872 190.889,155.724 214.593,100.909
194.593,52.02 227.186,49.057 246.444,92.02 238.297,140.909 216.074,172.761 197.556,188.316 179.778,169.798 164.963,174.983
163.481,197.946 156.815,197.946 134.593,159.428 94.593,151.279 "/>
<path class="monkey" id="alpha" fill="#FD00FF" d="M96.315,4.354l42.963,5.185l18.519,42.222l71.852-8.148l20.74,46.667l-5.926,52.593
l-24.444,34.074l-25.185,15.555l-14.074-19.259l-8.889,2.964l-1.481,22.222l-14.074,2.963l-25.186,22.963l-74.074,4.444
l101.481,4.444c0,0,96.297-17.777,109.63-71.852S282.24,53.983,250.389,20.65S96.315,4.354,96.315,4.354z"/>
</svg>
As you can probably see, each element has an ID, and I was hoping to be able to access individual elements with JavaScript so I could change the fill
attribute and respond to events such as clicks.
The HTML is bog basic:
<!DOCTYPE html>
<html>
<head>
<title>SVG Illustrator Test</title>
</head>
<body>
<object data="alpha.svg" type="image/svg+xml" id="alphasvg" width="100%" height="100%"></object>
</body>
</html>
I guess this is two questions really:
Is it possible to do it this way, as opposed to using something like Raphaël or jQuery SVG?
If it is possible, what's the technique?
UPDATE
At the moment, I've resorted to using Illustrator to create the SVG file, and I'm using Raphaël JS to create paths and simply copying the point data from the SVG file and pasting it into the path()
function. Creating complex paths such as might be needed for a map, by coding the point data manually is (to my knowledge) prohibitively complex.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
确实。
此带注释的代码片段有效:
请注意,此技术的局限性在于它受到同源策略的限制,因此
alpha.svg
必须托管在与.html 相同的域上
文件,否则对象的内部 DOM 将无法访问。重要的事情要运行此 HTML,您需要将 HTML 文件托管到 IIS、Tomcat 等 Web 服务器
Definitely.
This annotated code snippet works:
Note that a limitation of this technique is that it is restricted by the same-origin policy, so
alpha.svg
must be hosted on the same domain as the.html
file, otherwise the inner DOM of the object will be inaccessible.Important thing to run this HTML, you need host HTML file to web server like IIS, Tomcat
如果您使用 jQuery,则需要等待
$(window).load
,因为嵌入的 SVG 文档可能尚未在$(document).ready
加载In case you use jQuery you need to wait for
$(window).load
, because the embedded SVG document might not be yet loaded at$(document).ready
如果您对 SVG 使用
标签,那么您无法操作其内容(据我所知)。
正如接受的答案所示,使用
我最近需要这个,并在 gulp 构建期间使用 gulp-inject 将 SVG 文件的内容作为
元素直接注入到 HTML 文档中,这是然后使用 CSS 选择器和
querySelector
/getElementBy*
就可以轻松使用。If you are using an
<img>
tag for the SVG, then you cannot manipulate its contents (as far as I know).As the accepted answer shows, using
<object>
is an option.I needed this recently and used
gulp-inject
during my gulp build to inject the contents of an SVG file directly into the HTML document as an<svg>
element, which is then very easy to work with using CSS selectors andquerySelector
/getElementBy*
.