Делаем объект изображения svg интерактивным с помощью onclick, избегая абсолютного позиционирования - PullRequest
50 голосов
/ 19 февраля 2010

Я пытался изменить изображения на моем сайте с img до svg, меняя теги img на embed и object. Но реализация функции onclick, которая ранее содержалась в теге img, оказывается наиболее сложной.

Я обнаружил, что onclick не имел никакого эффекта при размещении внутри тега object или embed.

Итак, я сделал div исключительно для svg и поместил onclick в этот тег div. Но без эффекта, если посетитель не нажмет на края / отступы изображения.

Я читал о наложении div, но стараюсь не использовать absolute позиционирование или вообще указывать position.

Есть ли другой способ применить onclick к svg?

Кто-нибудь сталкивался с этой проблемой? Вопросы и предложения приветствуются.

Ответы [ 11 ]

56 голосов
/ 18 апреля 2012

Вы можете иметь событие onclick в самой svg, я делаю это все время в своей работе. сделайте прямоугольник над пространством вашего SVG (так определите его в последний раз, помните, SVG использует модель художников)

rect.btn {
  stroke:#fff;
  fill:#fff;
  fill-opacity:0;
  stroke-opacity:0;
}

затем в качестве атрибута к прямоугольнику добавьте 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

6 голосов
/ 24 октября 2012

Это началось с комментария к решению 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>
4 голосов
/ 19 августа 2010

Я работал в последних версиях 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>
3 голосов
/ 24 марта 2013

Это сработало, просто заменив тег <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, и я надеюсь, что в других браузерах тоже.

1 голос
/ 08 декабря 2017

Если вы просто используете встроенный 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>
  
1 голос
/ 15 сентября 2012

Вы можете использовать следующий код:

<style>
    .svgwrapper {
        position: relative;
    }
    .svgwrapper {
        position: absolute;
        z-index: -1;
    }
</style>

<div class="svgwrapper" onClick="function();">
    <object src="blah" />
</div>

b3ng0 написал похожий код, но он не работает. z-индекс родителя должен быть автоматическим.

0 голосов
/ 22 февраля 2019

Щелкните элемент SVG <g> в <object> с событием щелчка. Работает на 100%. Посмотрите на вложенный JavaScript в <svg>. Не забудьте вставить window.parent.location.href=, если вы хотите перенаправить родительскую страницу.

https://www.tutorialspoint.com/svg/svg_interactivity.htm

0 голосов
/ 13 апреля 2016

При встраивании 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!');
});

Обратите внимание, что невозможно для элементов с перекрестным происхождением <object>, если только вы не управляете сервером происхождения <object> и не можете установить там заголовки CORS. В случаях перекрестного происхождения без заголовков CORS доступ к contentDocument заблокирован.

0 голосов
/ 01 апреля 2013

Возможно, вам нужно свойство pointer-events элемента SVG, о котором вы можете прочитать в документации рабочей группы SVG w3C .

Вы можете использовать CSS, чтобы установить, что происходит с элементом SVG при его нажатии и т. Д.

0 голосов
/ 24 марта 2010

Предполагая, что вам не нужна кросс-браузерная поддержка (что невозможно без плагина для IE), вы пытались использовать svg в качестве фонового изображения ?

Экспериментальный материал, конечно, но подумал, что упомяну это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...