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>
Подключаем 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 (в более старых нет возможности сейчас проверить).
На этом всё. Если будут вопросы — спрашивайте в комментариях.
Статья классная!
Только не совсем полная…
Вы могли бы раскрыть еще такой вопрос по SVG:
У SVG есть внутренняя функция на JavaScript:
Как ее выполнить???
Заранее СПАСИБО!!!
P.S.: Буду ждать «SVG на собственной шкуре. Часть 3»
Сори, пропал код на JavaScript:
Я предполагаю, что ошибка может быть по нескольким причинам:
1) В коде идет обращение getElementById(obj.id), однако ни где не объявлен id.
2) Вместо
необходимо писать
Хотя может это из-за парсера в комментах ты убрал, но восклицашку я тоже не вижу.
3) Надеюсь функция вызывается по событию после полной загрузки документа?
4) Цвета заданные в стилях имеют больший приоритет
В общем как-то так работает:
После обращение, например через onclick
Кстати, имеется спецификация на это дело http://www.w3.org/TR/SVG/script.html
PS Я пока не придумал про что писать в третьей части, не нашел темы, которая бы 100500 раз в интернете уже не писалась. Да и третьей частью можно назвать статью Кроссбраузерный SVG логотип
PPS Чтобы в коментах на движке WordPress проходил код, необходимо скобочки < и > заменять на HTML сущности < и > соответственно. Такой вот привередливый WP.
Все правильно…
Но код JS работает только по событию:
onclick=»js_func(bla-bla-bla)»
Я не совсем об этом…
Как вызвать функцию без обращения к событиям???
Функция же есть прописана в CDATA????
Т.е. в документе HTML есть объект SVG в теге embed c id=’svg’
Ч.з var SVG = document.getElementById(«svg»).getSVGDocument();
получаем весь SVG (в том числе и js_func()),
как ее выполнить??? без onclick и проч.
Заранее СПС!!!
Вот этого я не знаю. Либо выноси скрипт из SVG в HTML, либо делай события в SVG.
Хорошие люди мне подсказали, что есть способ
Добавляем в наш HTML документ вот такую функцию (описание смотреть в исходном коде по ссылке выше):
Далее, делаем инициализацию функции — как в примере по onload у body или «ручками» когда потребуется.
И теперь мы имеем доступ к функциям внутри SVG
Проверена работоспособность в Firefox 21 и Opera 12.10, и отсутствие работоспособности в Chrome 29
BaNru — РЕСПЕКТ!!!!
Chrome 27 — работает!!!
Даже не надо писать функцию init();.
Ну тут функция написана в первую очередь для старых браузеров.
Рад что помог 🙂
Для навигации по узлам DOM SVG из скрипта на родительской HTML страницы, я в свое время пошел другим путем: в SVG по событию onload запускается скрипт, который рекурсивно перебирает родителей, пока не найдет объект window HTML, в нем вызывается функция инициализации (собственно по ее наличию окно и идентифицируется), в которую передается событие onload SVG. Поле target этого события и есть корень иерархии SVG. Далее из него делаем объект jQuery и идем к нужному SVG элементу через children(), find() и тд. Работает кроссбраузерно и не зависит от места и способа вставки SVG. Об этом есть статья на моем сайте http://svgmnemo.ru/pub/svgdyn.html