簡體   English   中英

在 HTML 中嵌入外部 SVG 以進行 JavaScript 操作

[英]Embedding external SVG in HTML for JavaScript manipulation

我有一個 SVG 圖像,顯示了地理區域。 http://upload.wikimedia.org/wikipedia/commons/7/71/Nederland_gemeenten_2009.svg

我想在網頁上顯示 SVG 圖像,並使用 JavaScript 和 CSS 的組合與圖像進行交互。 (即,檢測區域上的點擊,為區域設置不同的背景顏色)。

我知道在 StackOverflow 上多次問過這個問題,但我找不到完整的代碼示例來進一步研究。 歡迎任何關於 JavaScript 包(如 jQuery)或插件的建議。

我對這個問題的理解是有不同的方面需要解決:

  1. 如何准備用於交互的圖像
  2. 如何在頁面中嵌入圖片
  3. 如何在 SVG 中使用 CSS
  4. 如何使用 JavaScript 進行交互

准備圖像

首先,我建議清理圖像。 Inkscape 會留下您不需要的所有類型的東西,其中包括sodipodi:inkscape:命名空間中的元素和屬性以及重復和/或冗余的樣式屬性。 不必刪除,但它可以節省你一些帶寬/加載時間,如果你想用CSS樣式表的工作,比作風屬性在你的方式。

在您的示例文件中,您有 472 次相同的樣式屬性。 刪除所有這些並創建一個等效的 CSS 規則一次。

您還可以在標記中添加一些有關市政當局的信息。 例如,您可以根據名稱更改代表自治市的每條路徑的 ID。 您也可以為此使用data-*屬性。 后者的優點是可以使用空格。 請參閱下文,了解這對交互有何用處,尤其是與 CSS 交互時。

嵌入圖像

我建議使用 SVG inline,特別是如果你想與 CSS/JavaScript 交互。 這意味着,您只需將 SVG 標記添加到您的 HTML,或者您使用 Ajax 加載和插入它。 后者的好處是周圍頁面加載速度更快,響應速度更快。

內聯 SVG 元素的示例:

<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>

如何使用 Ajax 加載 SVG 的簡化示例:

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.onload = function(e) {
  // You might also want to check for xhr.readyState/xhr.status here
  document.getElementById("svgContainer")
    .appendChild(xhr.responseXML.documentElement);
};
xhr.send("");

如何使用 CSS

SVG 可以像 HTML 一樣設置樣式。 當然,SVG 有它自己的一組屬性,比如fill-opacitystroke-dasharray並且不支持很多 HTML 的屬性,比如marginposition等。 但是選擇器機制是 100% 相同的。

您可以在<style>元素或外部 CSS 文件中將內聯 SVG 的 CSS 與 HTML 的 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" 如果使用屬性和 CSS(使用樣式屬性、樣式元素或外部樣式表)設置相同的屬性,則 CSS 會覆蓋該屬性。

JavaScript 交互

HTML 和 SVG 在 JavaScript 交互方面基本上沒有區別,至少只要您使用普通的 DOM。 這意味着,SVG 不支持像innerHTML這樣的 HTML 特定功能(即沒有innerSVG )。 但是 SVG 有它自己的圖形特定的 DOM 方法集(請參閱 W3C 規范)。

需要注意的一件事是使用命名空間。 所有SVG元素應該在SVG命名空間,使用JavaScript,創造他們的時候createElementNS()已被用來代替createElement()

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

同樣,XLink 命名空間中的屬性(即xlink:href )必須使用setAttributeNS()而不是setAttribute()

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

由於像 jQuery 這樣的庫部分依賴於 HTML 特定功能,因此在操作 SVG 時避免它們更安全。 [編輯:自從我寫下這個答案以來,情況可能有所改善。 不是 jQuery 用戶,我不知道現在它的工作情況如何。] 還有像D3.js這樣的 SVG 特定庫,它們可以用於特定目的,值得一看。 (當我簡單地將它稱為 SVG 特定庫時,我正在做 D3.js 不公正,因為它更多)。

您可以使用onclick和類似屬性以及標准 DOM addEventListener() 使用 JavaScript 事件的一個非常簡單的示例是向<svg>元素添加一個事件偵聽器,該元素報告用戶單擊的自治市的名稱:

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

旁注:工具提示使用 SVG 中的<title>元素可以實現在 HTML 中使用title屬性獲得的相同效果。 只需將<title>元素放在 SVG 元素中,懸停時,您會看到帶有<title>元素內容的工具提示。

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

只是為了記錄(知道這一點晚了一年)我發現 SnapSVG 非常適合 SVG 操作。 拉斐爾背后的那個人:

http://snapsvg.io

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM