Подтвердить что ты не робот

Внедрение внешнего SVG в HTML для обработки JavaScript

У меня есть изображение SVG, показывающее географические регионы. http://upload.wikimedia.org/wikipedia/commons/7/71/Nederland_gemeenten_2009.svg

Я хочу отобразить изображение SVG на веб-странице и использовать комбинацию JavaScript и CSS для взаимодействия с изображением. (т.е. обнаруживать клики по региону, устанавливая другой цвет фона для региона).

Я знаю, что этот вопрос задается несколько раз в StackOverflow, но я не могу найти полный образец кода для дальнейшей работы. Любые рекомендации по пакетам JavaScript, такие как jQuery или плагины, приветствуются.

4b9b3361

Ответ 1

Мое понимание вопроса заключается в том, что существуют различные аспекты, которые необходимо решить:

  • Как подготовить изображение для взаимодействия
  • Как вставить изображение на страницу
  • Как использовать CSS с SVG
  • Как использовать JavaScript для взаимодействия

Подготовка изображения

Прежде всего, я бы рекомендовал очистить изображение. Inkscape оставляет там все, что вам не нужно, включая элементы и атрибуты в пространствах имен sodipodi: и inkscape:, а также повторяющиеся и/или избыточные атрибуты стиля. Вам не нужно удалять это, но это экономит вам время в полосе пропускания/загрузки, и если вы хотите работать с соответствием CSS, чем на вашем пути. Атрибуты стиля на вашем пути.

В вашем файле примера у вас есть 472 раза тот же атрибут стиля. Удалите все из них и создайте эквивалентное правило CSS один раз.

Вы также можете добавить некоторую информацию о муниципалитетах к разметке. Вы можете, например, изменить идентификаторы каждого пути, представляющего муниципалитет, в соответствии с его названием. Вы также можете использовать атрибут data-* для этой цели. Последнее имеет то преимущество, что вы можете использовать пробелы. См. Ниже, как это полезно для взаимодействия, особенно с CSS.

Вставка изображения

Я бы рекомендовал использовать встроенный SVG, особенно если вы хотите взаимодействовать с 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>

Упрощенный пример загрузки SVG с помощью 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);

Как использовать CSS

SVG можно стилизовать так же, как HTML. Конечно, SVG имеет собственный набор свойств, например fill-opacity или stroke-dasharray, и не поддерживает много свойств HTML, например margin, position или тому подобное. Но механизмы выбора на 100% одинаковы.

Вы можете смешать CSS для встроенного SVG с CSS для вашего HTML, либо внутри элемента <style>, либо внешнего файла CSS. Вы также можете использовать элемент <style> внутри атрибутов SVG и style.

Предполагая, что вы предоставили свои значки SVG значимые или атрибуты data-*, два способа выделения муниципалитетов с использованием CSS:

#Bronckhorst, #Laarbeek {fill:red}

или

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

Или, конечно, вы можете изменить атрибуты стиля соответствующих элементов. Свойства также поддерживаются как атрибут, т.е. style="stroke-width:2" также может быть указан как stroke-width="2". Если одно и то же свойство задается как с атрибутом, так и с CSS (либо с использованием атрибута style, элемента стиля или внешней таблицы стилей), CSS переопределяет атрибут.

взаимодействие с JavaScript

Взаимосвязь между HTML и SVG в отношении взаимодействия с JavaScript практически отсутствует, по крайней мере, до тех пор, пока вы используете простой ванильный DOM. Это означает, что специальные функции HTML, такие как innerHTML, не поддерживаются в SVG (т.е. Нет innerSVG). Но SVG имеет собственный набор специфических для DOM-методов графики (см. Спецификации W3C).

Одна вещь, о которой нужно знать, - это работа с пространствами имен. Все элементы SVG должны находиться в пространстве имен SVG, а при создании их с использованием JavaScript вместо createElement() следует использовать createElementNS():

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. Существуют также специальные библиотеки SVG, такие как Raphaël и D3.js которые могут быть полезны для конкретных целей и заслуживают внимания. Raphaël особенно полезен для совместимости с pre-HTML5 Internet Explorer версий с 6 по 8, которые не поддерживают SVG. Однако, как я понимаю, он действительно подходит только для генерации графики полностью с использованием JavaScript, а не для работы с существующей графикой, потому что это слой абстракции над SVG. D3.js будет более подходящим для приложений, подобных вашим, если вас не устраивает простой DOM (и, честно говоря, я делаю это несправедливо, просто называя его специальной библиотекой SVG, потому что он больше).

Вы можете использовать onclick и аналогичные атрибуты и стандартный DOM addEventListener(). Очень простым примером использования событий JavaScript было бы добавить прослушиватель событий к элементу <svg>, который сообщает имя муниципалитета, на который пользователь нажал:

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

Боковое примечание: Toopltips Тот же эффект, который вы получаете с помощью атрибута title в HTML, может быть достигнут с помощью элемента <title> в SVG. Просто поместите элемент <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>

Ответ 2

Только для записи (зная, что это наступает год спустя), я нашел SnapSVG отлично подходящим для манипуляции SVG. Тот же парень, который был за Рафаэлем:

http://snapsvg.io