Ещё один простой блог в интернете, одного из жителей Сызрани, который считает себя дизайнером, WEB-мастером и фотографом-любителем

просто блог

QR CODE для записиQR CODE для записи “SVG на собственной шкуре. Часть 2 — обращение к DOM SVG файла с помощью JavaScript”

SVG на собственной шкуре. Часть 2 — обращение к DOM SVG файла с помощью JavaScript

В предыдущей статье «SVG на собственной шкуре. Часть 1 — создание SVG файла в CorelDraw» я рассказывал, как легко можно создать и оптимизировать SVG файл. Также был эксперимент, в первую очередь для своего блога, о котором я рассказывал в статье «Скрипт смены стиля пользователем в WP и не только…». Также писал вкратце про SVG анимацию в статье «RE: Анимированный PNG в Firefox, Opera и WebKit? Легко!» На этом я конечно не остановился, и проводил ещё «эксперимент», о котором, к сожалению, а может к счастью мне лень было писать. Но вот оно свершилось, на меня снизошла неведомая сила, которая заставила написать данную статью.

На данный момент SVG всё продолжает набирать популярность. Хотя и не бешеными темпами, но однозначно можно сказать, что всё больше людей смотрят в сторону SVG, поскольку все современные браузеры уже имеют полную поддержку. Очень часто можно найти статьи о преимуществах, о формате, но мало реальных примеров и в частности о том, как получить доступ к DOM дереву встраиваемого SVG файла на страницу. А это на самом деле очень просто:

document.getElementById("svg").getSVGDocument();

где getElementById(«svg») — ищет элемент с ID = «svg», а getSVGDocument() — получает сам SVG файл

Теперь SVG файл у нас «в руках» и мы можем делать с ним практически всё что угодно. Например можно обратиться к элементу по тегу (getElementsByTagName) или по его ID (getElementById)

// Получаем объект SVG
var SVG = document.getElementById("svg").getSVGDocument();
// Получаем элемент (тег) в SVG файле
var STYLE = SVG.getElementById('ID');

Из-за того, что JavaScript я знаю на уровне нуба, то дальше я приведу пример на jQuery. Думаю те кто хорошо знаком с JavaScript и так всё знают, остальным же будет интереснее и удобнее работать с помощью jQuery или другого любимого фреймворка, разница будет не большая.

Чтобы было понятнее приведу сразу пример:

Ну а теперь обо всё по порядку.
Для начала создаем SVG файл.

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200">

<defs>
	<style type="text/css">
		<![CDATA[
			#r1{fill:red;}
			#r2{fill:yellow;}
			#r3{fill:blue;}
			#r4{fill:lime;}
			#r5{fill:aqua;}
		]]>
	</style>
</defs>

<g>
	<rect id="r1" width="200" height="200" x="0" y="0" />
	<rect id="r2" width="80" height="80" x="10" y="10" />
	<rect id="r3" width="80" height="80" x="110" y="110" />
	<rect id="r4" width="80" height="80" x="10" y="110" />
	<rect id="r5" width="80" height="80" x="110" y="10" />
</g>

</svg>
Если вы будете использовать подобное в боевых условиях, то вы должны знать, что политика безопасности браузеров запрещает работать с SVG файлами расположенными на чужом домене. Обязательно располагайте SVG файлы на своем (на котором выполняются манипуляции с SVG) домене.

Подключаем jQuery, если он не подключен и сам файл на страницу

<embed id="svg" type="image/svg+xml" src="/путь_к_файлу/test.svg" height="200" width="200">

В примере выполняется своя функция «color» по клику на ссылке с необходимыми параметрами — цвет и ID элемента. Сами ссылки выглядят стандартно

<a onclick="color('ff00ff','r1');">rect 1</a>

Ну и JS функция «color»:

function color(new_color, rect){
	// Получаем объект SVG
	var SVG = document.getElementById("svg").getSVGDocument();
	// Получаем эелемент (тег) в SVG файле
	var STYLE = SVG.getElementById(rect);
	// Меняем стили с помощью jQ
	$(STYLE).css('fill', '#'+new_color);
}

Обратите внимания, что многие CSS свойства у SVG отличаются от HTML стилей. Так в примере вместо background-color необходимо писать fill

Данный пример проверен на работоспособность в последних версиях Firefox, Opera и Chrome (в более старых нет возможности сейчас проверить).

Демонстрация

На этом всё. Если будут вопросы — спрашивайте в комментариях.

  1. Андрей # link

    Статья классная!
    Только не совсем полная…

    Вы могли бы раскрыть еще такой вопрос по SVG:
    У SVG есть внутренняя функция на JavaScript:

    Как ее выполнить???
    Заранее СПАСИБО!!!

    P.S.: Буду ждать «SVG на собственной шкуре. Часть 3»

  2. Андрей # link

    Сори, пропал код на JavaScript:

    <script type="text/javascript">
    [CDATA[
    
     function replace_color(obj)
    {
      var x=document.getElementById(obj.id);
      var curattr=x.getAttribute("fill");
      if (curattr=="red") {x.setAttribute("fill","springgreen")} 
      else {x.setAttribute("fill","red")}
     }
    ]]
    </script>
  3. BaNru # link

    Я предполагаю, что ошибка может быть по нескольким причинам:
    1) В коде идет обращение getElementById(obj.id), однако ни где не объявлен id.
    2) Вместо

    [CDATA[
    ]]

    необходимо писать

    <![CDATA[
    ]]>

    Хотя может это из-за парсера в комментах ты убрал, но восклицашку я тоже не вижу.
    3) Надеюсь функция вызывается по событию после полной загрузки документа?
    4) Цвета заданные в стилях имеют больший приоритет

    В общем как-то так работает:

    <script type="text/javascript">
    <![CDATA[
    
    function replace_color(obj){
    	var x=document.getElementById(obj);
    	var curattr = x.getAttribute("fill");
    	if ( curattr == "red" ) {
    		x.setAttribute("fill","springgreen");
    	} else {
    		x.setAttribute("fill","red");
    	}
    }
    
    ]]>
    </script>

    После обращение, например через onclick

    <rect id="r2" fill="green" width="80" height="80" x="10" y="10" onclick="replace_color('r2');"></rect>

    Кстати, имеется спецификация на это дело http://www.w3.org/TR/SVG/script.html

    PS Я пока не придумал про что писать в третьей части, не нашел темы, которая бы 100500 раз в интернете уже не писалась. Да и третьей частью можно назвать статью Кроссбраузерный SVG логотип

    PPS Чтобы в коментах на движке WordPress проходил код, необходимо скобочки < и > заменять на HTML сущности &lt; и &gt; соответственно. Такой вот привередливый WP.

  4. Андрей # link

    Все правильно…

    Но код JS работает только по событию:
    onclick=»js_func(bla-bla-bla)»

    Я не совсем об этом…

    Как вызвать функцию без обращения к событиям???
    Функция же есть прописана в CDATA????

    Т.е. в документе HTML есть объект SVG в теге embed c id=’svg’
    Ч.з var SVG = document.getElementById(«svg»).getSVGDocument();
    получаем весь SVG (в том числе и js_func()),
    как ее выполнить??? без onclick и проч.

    Заранее СПС!!!

  5. BaNru # link

    Вот этого я не знаю. Либо выноси скрипт из SVG в HTML, либо делай события в SVG.

  6. BaNru # link

    Хорошие люди мне подсказали, что есть способ

    Добавляем в наш HTML документ вот такую функцию (описание смотреть в исходном коде по ссылке выше):

    <script type="text/javascript">
    <!--
    
    var svgdoc = null;
    var svgwin = null;
    
    function init()
    {
    
      var embed = document.getElementById('svg'); // Тут наш SVG
      try {
        svgdoc = embed.getSVGDocument();
      }
      catch(exception) {
        alert('The GetSVGDocument interface is not supported');
      }
    
    
      if (svgdoc && svgdoc.defaultView)  // try the W3C standard way first
        svgwin = svgdoc.defaultView;
      else if (embed.window)
        svgwin = embed.window;
      else try {
        svgwin = embed.getWindow();
      }
      catch(exception) {
        alert('The DocumentView interface is not supported\r\n' +
              'Non-W3C methods of obtaining "window" also failed');
      }
    
    }
    
    // -->
    </script>

    Далее, делаем инициализацию функции — как в примере по onload у body или «ручками» когда потребуется.

    <body onload="init()"></body>

    И теперь мы имеем доступ к функциям внутри SVG

    svgwin.funkciya_iz_svg();

    Проверена работоспособность в Firefox 21 и Opera 12.10, и отсутствие работоспособности в Chrome 29

  7. Андрей # link

    BaNru — РЕСПЕКТ!!!!

    Chrome 27 — работает!!!
    Даже не надо писать функцию init();.

    var el_svg = document.getElementById('svg').getSVGDocument();
    svgwin = el_svg.defaultView;
    svgwin.alert_svg();
  8. BaNru # link

    Ну тут функция написана в первую очередь для старых браузеров.

    Рад что помог 🙂

  9. Serge Ryadkow # link

    Для навигации по узлам DOM SVG из скрипта на родительской HTML страницы, я в свое время пошел другим путем: в SVG по событию onload запускается скрипт, который рекурсивно перебирает родителей, пока не найдет объект window HTML, в нем вызывается функция инициализации (собственно по ее наличию окно и идентифицируется), в которую передается событие onload SVG. Поле target этого события и есть корень иерархии SVG. Далее из него делаем объект jQuery и идем к нужному SVG элементу через children(), find() и тд. Работает кроссбраузерно и не зависит от места и способа вставки SVG. Об этом есть статья на моем сайте http://svgmnemo.ru/pub/svgdyn.html

Оставить комментарий

В блоге включена ручная модерация комментариев. Нет смысла повторно отправлять комментарий.
Поля отмеченный звездочкой * обязательны к заполнению

Перед отправкой формы: