在HTML中嵌入外部SVG以进行JavaScript操作 [英] Embedding external SVG in HTML for JavaScript manipulation

查看:96
本文介绍了在HTML中嵌入外部SVG以进行JavaScript操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个SVG图像,显示地理区域。
http://upload.wikimedia.org/wikipedia/commons /7/71/Nederland_gemeenten_2009.svg



我想在网页上显示SVG图像,并使用JavaScript和CSS的组合与图片。 (即,检测对区域的点击,为区域设置不同的背景颜色)。

我知道这个问题在StackOverflow上被问了好几次,但是我无法找到一个完整的代码示例来进一步处理。欢迎任何有关JavaScript包的建议,如jQuery或插件。

解决方案

我对这个问题的理解是有不同的方面需要解决:


  1. 如何为图片进行互动准备

  2. 如何在图片中嵌入图片

  3. 如何使用JavaScript进行交互

准备image



首先,我建议清理图像。 Inkscape将所有您不需要的东西都保留下来,其中包括 sodipodi中的元素和属性: inkscape:名称空间以及重复和/或冗余样式属性。您不必 来移除它,但它为您节省了一些带宽/加载时间,并且如果您想使用CSS匹配,那么样式属性就是您的方式。 b
$ b

在你的示例文件中,你有472次相同的样式属性。删除所有这些,并创建一个等效的CSS规则一次。



您也可以添加一些关于城市的信息加入标记。你可以例如根据其名称更改代表市政的每个路径的ID。您也可以为此使用 data - * 属性。后者的优点是可以使用空格。请参阅下面的内容,了解它如何用于交互,特别是与CSS的交互。



嵌入图片



我建议使用SVG内联,特别是如果您想与CSS / JavaScript交互。这意味着,您只需将SVG标记添加到HTML中,或者使用Ajax加载并插入它。后者的好处是周围的页面加载速度更快,并且感觉更具响应性。



一个内联SVG元素的示例:

 < div id =svgContainer> 
<! - 这是一个HTML div,里面是SVG - >
< svg xmlns =http://www.w3.org/2000/svgwidth =100pxheight =100px>
< / svg>
< / div>

如何使用Ajax加载SVG的简单示例:

  xhr = new XMLHttpRequest(); 
xhr.open(GET,my.svg,false);
//下面的行只是为了安全起见;
//如果您的服务器以正确的MIME类型提供SVG,则不需要
xhr.overrideMimeType(image / svg + xml);
xhr.send();
document.getElementById(svgContainer)
.appendChild(xhr.responseXML.documentElement);

如何使用CSS



SVG的样式可以像HTML一样。当然,SVG有它自己的一组属性,比如 fill-opacity 或者 stroke-dasharray ,并且不支持很多HTML的属性,如 margin position 等等。但是选择器机制是完全相同的。

您可以将内联SVG的CSS与HTML的CSS混合使用,可以在 < style> 元素或外部CSS文件。您还可以使用SVG代码中的< style> 元素和 style 属性。



假设你给了你的SVG元素有意义的ID或 data - * 属性,那么使用CSS突出显示城市的两种方法是:

  #Bronckhorst,#Laarbeek {fill:red} 

  * [data-gemeente = Bronckhorst],* [data-gemeente = Laarbeek ] {fill:red} 

当然,您可以更改各个元素的样式属性。属性也支持作为属性,即 style =stroke-width:2也可以像 stroke-width =2 code>。如果同时使用属性和CSS(使用style属性,样式元素或外部样式表)设置相同的属性,CSS将覆盖该属性。



JavaScript交互

HTML和SVG在JavaScript交互方面基本上没有区别,至少只要使用普通的vanilla DOM。这意味着,SVG中不支持HTML特定的功能,例如 innerHTML (即没有 innerSVG )。但是SVG有自己的图形特定的一套DOM方法(请参阅W3C规范) 。



要注意的一件事是使用名称空间。所有SVG元素都应该在SVG名称空间中,并且在使用JavaScript创建它们时,必须使用 createElementNS()来代替 createElement() code>:

  var use = document.createElementNS(http://www.w3.org/2000/同样,在XLink命名空间中的属性(即 > 
$ b
> xlink:href
)必须使用 setAttributeNS()而不是 setAttribute()

  use.setAttributeNS(http://www.w3.org/1999/xlink,href, #foo)

像jQuery这样的库部分依赖于HTML特有的功能,避免它们更安全操纵SVG时。还有一些特定于SVG的库,如Raphaël D3.js ,它可以用于特定目的,值得一看。 Raphaël特别适用于兼容HTML5以前版本的Internet Explorer版本6至8,该版本没有SVG支持。然而,据我所知,它仅适用于完全使用JavaScript生成图形,而不是使用现有图形,因为它是SVG之上的抽象层。如果你对普通的DOM不满意,D3.js会更适合像你这样的应用程序(并且,当我简单地称它为SVG特定的库时,我会这样做是不公正的,因为它更多)。

b
$ b

您可以使用 onclick 以及类似的属性和标准DOM addEventListener()。使用JavaScript事件的一个非常简单的例子是将事件侦听器添加到报告用户点击的市政府名称的< svg> 元素中:

  document.getElementsByTagName(svg)[0] 
.addEventListener(click,function(evt){
alert(evt.target.getAttribute(data-gemeente))
},
false)

附注:Toopltips
与在HTML中使用 title 属性相同的效果可以使用SVG中的< title> 元素来实现。只需在SVG元素中放置一个< title> 元素并悬停,就会看到< title>的内容的工具提示元素。

 < svg xmlns =http://www.w3.org/2000/svg width =100pxheight =100px> 
< rect width =100height =100>
< title> test< / title>
< / rect>
< / svg>


I have a SVG image, showing geographical regions. http://upload.wikimedia.org/wikipedia/commons/7/71/Nederland_gemeenten_2009.svg

I want to display the SVG image on a webpage, and using a combination of JavaScript and CSS to interact with the image. (ie, detect clicks on a region, setting a different background color for a region).

I know this question is asked several times on StackOverflow, but I cannot find a complete code sample to work on further. Any recommendations on JavaScript packages, like jQuery, or plug-ins are welcome.

解决方案

My understanding of the question is that there are different aspects to be solved:

  1. How to prepare the image for interaction
  2. How to embed the image in the page
  3. How to use CSS with SVG
  4. How to use JavaScript for interaction

Preparing the image

First of all, I'd recommend to clean up the image. Inkscape leaves all kind of stuff there that you don't need, which includes elements and attributes in the sodipodi: and inkscape: namespaces as well as repetitive and/or redundant style attributes. You don't have to remove that, but it saves you some bandwidth/loading time, and if you want to work with CSS matching, than the style attributes are in your way.

In your example file, you have 472 times the same style attribute. Remove all of them and create an equivalent CSS rule once.

You might also add some info about the municipalities to the markup. You could e.g. change the IDs of each path representing a municipality according to its name. You could also use a data-* attribute for this purpose. The latter has the advantage that you can use spaces. See below for how this is useful for interaction, especially with CSS.

Embedding the image

I'd recommend using the SVG inline, especially if you want to interact with CSS/JavaScript. This means, you just add the SVG markup to your HTML, or you load and insert it using Ajax. The latter has the benefit that the surrounding page loads faster and feels more responsive.

An example of an inline SVG element:

<div id="svgContainer">
  <!-- This is an HTML div, and inside goes the SVG -->
  <svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
    <circle r="50" cx="50" cy="50" fill="green"/>
  </svg>
</div>

A simplified example of how to load SVG using Ajax:

xhr = new XMLHttpRequest();
xhr.open("GET","my.svg",false);
// Following line is just to be on the safe side;
// not needed if your server delivers SVG with correct MIME type
xhr.overrideMimeType("image/svg+xml");
xhr.send("");
document.getElementById("svgContainer")
  .appendChild(xhr.responseXML.documentElement);

How to use CSS

SVG can be styled just like HTML. Of course, SVG has it's own set of properties, like fill-opacity or stroke-dasharray and does not support a lot of HTML's properties, like margin, position or the like. But the selector mechanisms are 100% the same.

You can mix the CSS for your inline SVG with the CSS for your HTML, either inside a <style> element or an external CSS file. You can also use the <style> element inside the SVG code and style attributes.

Assuming you gave your SVG elements meaningful IDs or data-* attributes, two ways of highlighting municipalities using CSS would be:

#Bronckhorst, #Laarbeek {fill:red}

or

*[data-gemeente=Bronckhorst], *[data-gemeente=Laarbeek] {fill:red}

Or, of course, you can change the style attributes of the respective elements. Properties are also supported as attribute, i.e. style="stroke-width:2" can also be specified like stroke-width="2". If the same property is set using both an attribute and CSS (either using the style attribute, a style element or an external stylesheet), the CSS overrides the attribute.

JavaScript interaction

There is basically no difference between HTML and SVG regarding JavaScript interaction, at least as long as you use plain vanilla DOM. This means, HTML specific features like innerHTML are not supported in SVG (i.e. there is no innerSVG). But SVG has its own graphics specific set of DOM methods (see the W3C specs).

One thing to be aware of is the work with namespaces. All SVG elements should be in the SVG namespace, and when creating them using JavaScript, createElementNS() has to be used instead of createElement():

var use = document.createElementNS("http://www.w3.org/2000/svg","use")

Likewise, attributes in the XLink namespace (namely xlink:href) have to be manipulated using setAttributeNS() instead of setAttribute():

use.setAttributeNS("http://www.w3.org/1999/xlink","href","#foo")

As libraries like jQuery partly rely on HTML specific features, it's safer to avoid them when manipulating SVG. There are also SVG specific libraries like Raphaël and D3.js which can be useful for specific purposes and are worth a look. Raphaël is especially useful for being compatible with pre-HTML5 Internet Explorer versions 6 to 8, which don't have SVG support. However, as I understand it, it's really only suited for generating graphics entirely using JavaScript rather than working with existing graphics because it's an abstraction layer above SVG. D3.js would be more suited for applications like yours if you're not happy with plain DOM (and, honestly, I'm doing it injustice when simply calling it an SVG specific library, because it's more).

You can use onclick and similar attributes and standard DOM addEventListener(). A very simple example of using JavaScript events would be to add an event listener to the <svg> element that reports the name of a municipality that a user clicked on:

document.getElementsByTagName("svg")[0]
  .addEventListener("click",function(evt){
    alert(evt.target.getAttribute("data-gemeente"))
  },
  false)

Side note: Toopltips The same effect that you get using the title attribute in HTML can be achieved using the <title> element in SVG. Just put a <title> element inside an SVG element and on hover, you see a tooltip with the content of the <title> element.

<svg xmlns="http://www.w3.org/2000/svg" width="100px" height="100px">
  <rect width="100" height="100">
    <title>test</title>
  </rect>
</svg>

这篇关于在HTML中嵌入外部SVG以进行JavaScript操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆