Создание объекта изображения svg с возможностью щелчка с помощью onclick, избегая абсолютного позиционирования
Я попытался изменить изображения на своем сайте с img
до svg
, изменив теги img
на теги embed
и object
. Но реализация функции onclick
, которая ранее содержалась в теге img
, оказалась наиболее сложной.
Я обнаружил, что onclick
не имеет эффекта при размещении внутри тега object
или embed
.
Итак, я создал div
исключительно для svg и поместил onclick
в этот тег div
. Но без эффекта, если посетитель не нажимает на края/дополнение изображения.
Я прочитал о наложении a div
, но стараюсь избегать использования позиционирования absolute
или вообще указывать position
.
Есть ли другой способ применить onclick к svg?
Кто-нибудь столкнулся с этой проблемой? Вопросы и предложения приветствуются.
Ответы
Ответ 1
У вас может быть событие onclick в самом svg, я делаю это все время в своей работе. сделайте прямоугольник над пространством вашего svg (так что определите его последним, помните, что svg использует модель живописцев)
rect.btn {
stroke:#fff;
fill:#fff;
fill-opacity:0;
stroke-opacity:0;
}
то в качестве атрибута rect добавьте onclick (это можно сделать с помощью js или jquery).
<div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g>
<circle ... //your img svg
<rect class="btn" x="0" y="0" width="10" height="10" onclick="alert('click!')" />
</g>
</svg>
</div>
это будет работать в большинстве современных браузеров, http://caniuse.com/svg... хотя, если вам нужна перекрестная совместимость, вы можете реализовать Google Chrome Frame. http://www.google.com/chromeframe
Ответ 2
Это началось с комментария к решению RGB, но я не смог его вписать, поэтому преобразовал его в ответ. Источником вдохновения для которого являются исключительно RGB.
Решение RGB сработало для меня. Тем не менее, я хотел бы отметить пару моментов, которые могут помочь другим, приходящим на этот пост (таким как я), которые не настолько знакомы с тем, какой SVG, и которые вполне могли сгенерировать свой файл SVG из графического пакета (как я это сделал).
Поэтому для применения решений RGB я использовал:
CSS
<style>
rect.btn {
stroke:#fff;
fill:#fff;
fill-opacity:0;
stroke-opacity:0;
}
</style>
Скрипт jquery
<script type="text/javascript" src="../_public/_jquery/jquery-1.7.1.js"></script>
<script type="text/javascript">
$("document").ready(function(){
$(".btn").bind("click", function(event){alert("clicked svg")});
});
</script>
HTML-код для кодирования включения вашего ранее существующего файла SVG в тег group внутри кода SVG.
<div>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
<g>
<image x="0" y="0" width="10" height="10"
xlink:href="../_public/_icons/booked.svg" width="10px"/>
<rect class="btn" x="0" y="0" width="10" height="10"/>
</g>
</svg>
</div>
Тем не менее, в моем случае у меня есть несколько значков SVG, на которые я хочу кликать, и включение каждого из них в тег SVG становилось громоздким.
Поэтому в качестве альтернативного подхода, где я мог бы использовать классы, я использовал jquery.svg. Вероятно, это позорное применение этого плагина, который может делать все виды вещей с SVG. Но это сработало с использованием следующего кода:
<script type="text/javascript" src="../_public/_jquery/jquery-1.7.1.js"></script>
<script type="text/javascript" src="jquery.svg.min.js"></script>
<script type="text/javascript">
$("document").ready(function(){
$(".svgload").bind("click", function(event){alert("clicked svg")});
for (var i=0; i < 99; i++) {
$(".svgload:eq(" + i + ")").svg({
onLoad: function(){
var svg = $(".svgload:eq(" + i + ")").svg('get');
svg.load("../_public/_icons/booked.svg", {addTo: true, changeSize: false});
},
settings: {}}
);
}
});
</script>
где HTML
<div class="svgload" style="width: 10px; height: 10px;"></div>
Преимущество моего мышления заключается в том, что я могу использовать соответствующий класс там, где когда-либо нужны значки, и избегать большого количества кода в теле HTML, что способствует удобочитаемости. И мне нужно только включить ранее существующий файл SVG один раз.
Редактирование: Вот более точная версия скрипта, предоставленная Китом Вудом: использование настройки URL загрузки .svg.
<script type="text/javascript" src="../_public/_jquery/jquery-1.7.1.js"></script>
<script type="text/javascript" src="jquery.svg.min.js"></script>
<script type="text/javascript">
$("document").ready(function(){
$('.svgload').on('click', function() {
alert('clicked svg new');
}).svg({loadURL: '../_public/_icons/booked.svg'});
});
</script>
Ответ 3
Я работал над последними версиями Firefox, Chrome, Safari и Opera.
Он полагается на прозрачный div перед объектом, который имеет абсолютное положение и устанавливает ширину и высоту, чтобы он закрывал тег объекта ниже.
Вот он, я немного ленив и использовал встроенные стили:
<div id="toolbar" style="width: 600px; height: 100px; position: absolute; z-index: 1;"></div>
<object data="interface.svg" width="600" height="100" type="image/svg+xml">
</object>
Я использовал следующий JavaScript для подключения к нему события:
<script type="text/javascript">
var toolbar = document.getElementById("toolbar");
toolbar.onclick = function (e) {
alert("Hello");
};
</script>
Ответ 4
Он работал, просто заменив тег <embed/>
на <img/>
и удалив атрибут type.
Например, в моем коде вместо
<embed src=\"./images/info_09c.svg\" type=\"image/svg+xml\" width=\"45\" onClick='afiseaza_indicatie($i, \"$indicatii[$i]\")'>
который не отвечает на щелчок, я написал:
<img src=\"./images/info_09c.svg\" height=\"25\" width=\"25\" onClick='afiseaza_indicatie($i, \"$indicatii[$i]\")'>
Он работает в Internet Explorer и Google Chrome, и я надеюсь, что в других браузерах тоже.
Ответ 5
Вы можете использовать следующий код:
<style>
.svgwrapper {
position: relative;
}
.svgwrapper {
position: absolute;
z-index: -1;
}
</style>
<div class="svgwrapper" onClick="function();">
<object src="blah" />
</div>
b3ng0 написал похожий код, но он не работает. z-index родителя должен быть авто.
Ответ 6
Вы изучили использование свойства CSS z-index
, чтобы сделать контейнер-контейнер "сверху" svg? Поскольку div (предположительно) прозрачен, вы все равно увидите изображение точно так же, как раньше.
Я считаю, что это лучший практический, не-хак, предназначенный для решения вашей проблемы. z-index
полезен только для элементов, имеющих свойство position
fixed
, relative
или, как вы слышали, absolute
. Однако на самом деле вам не нужно перемещать объект.
Например:
<style>
.svgwrapper {
position: relative;
z-index: 1;
}
</style>
<div class="svgwrapper" onClick="function();">
<object src="blah" />
</div>
Для чего это стоит, было бы также немного более элегантно и безопасно вообще не использовать onClick, а вместо этого привязывать событие click с помощью javascript. Но это еще одна проблема.
Ответ 7
Предполагая, что вам не нужна поддержка кросс-браузера (что невозможно без плагина для IE), попробовали ли вы использовать svg в качестве фонового изображения?
Экспериментальный материал наверняка, но подумал, что я бы сказал об этом.
Ответ 8
Возможно, вы ищете свойство SVG-элемента pointer-events, о котором вы можете прочитать в документах рабочей группы SVG w3C.
Вы можете использовать CSS для установки того, что происходит с элементом SVG при нажатии и т.д.
Ответ 9
При встраивании SVG с одним и тем же источником, используя <object>
, вы можете получить доступ к внутреннему содержимому с помощью objectElement.contentDocument.rootElement
. Оттуда вы можете легко присоединить обработчики событий (например, через onclick
, addEventListener()
и т.д.)
Например:
var object = /* get DOM node for <object> */;
var svg = object.contentDocument.rootElement;
svg.addEventListener('click', function() {
console.log('hooray!');
});
Обратите внимание, что это невозможно для элементов cross-origin <object>
, если вы также не управляете сервером происхождения <object>
и можете устанавливать заголовки CORS там. Для случаев с перекрестным происхождением без заголовков CORS доступ к contentDocument
блокируется.
Ответ 10
Если вы просто используете inline svg, проблем нет.
<svg id="svg1" xmlns="http://www.w3.org/2000/svg" style="width: 3.5in; height: 1in">
<circle id="circle1" r="30" cx="34" cy="34" onclick="circle1.style.fill='yellow';"
style="fill: red; stroke: blue; stroke-width: 2"/>
</svg>