Rendre un objet image svg cliquable avec onclick, en évitant le positionnement absolu

j'ai essayé de changer les images sur mon site de img à svg , en changeant img tags à embed et object tags. Mais la mise en œuvre de la fonction onclick , qui était auparavant contenue dans la balise img , s'avère très difficile.

j'ai trouvé onclick n'a eu aucun effet lorsqu'il est placé à l'intérieur de la object ou embed tag.

donc, j'ai fait un div exclusivement pour le svg, et placé onclick dans cette étiquette div . Mais, aucun effet à moins que le visiteur clique sur les bords/rembourrage de l'image.

j'ai lu à propos de la superposition d'un div , mais j'essaie d'éviter d'utiliser des "1519140920 positionnement", ou en spécifiant position .

y a-t-il une autre façon d'appliquer onclick à une svg?

quelqu'un A rencontré ce problème? Les questions et les suggestions sont les bienvenues.

39
demandé sur Rui Jarimba 2010-02-19 15:05:47

10 réponses

Vous pouvez avoir un événement onclick dans le svg lui-même, je le fais tout le temps dans mon travail. faites un rect sur l'espace de votre svg, (donc définissez-le en dernier, rappelez-vous svg utilise le modèle des peintres)

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

puis comme attribut au rect ajouter le onclick (cela peut être fait avec js ou jquery aussi).

<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>

cela fonctionnera dans la plupart des navigateurs modernes, http://caniuse.com/svg ...si vous avez besoin de la croix compatibilité, Vous pouvez mettre en œuvre Google Chrome Frame. http://www.google.com/chromeframe

49
répondu RGB 2014-05-03 17:28:05

cela a commencé comme un commentaire sur la solution de RGB, mais je n'ai pas pu l'insérer, donc je l'ai converti en réponse. L'inspiration est entièrement de RGB.

la solution de RGB a fonctionné pour moi. Cependant, j'ai tenu à noter quelques points qui peuvent aider d'autres arrivées à ce post (comme moi) qui ne sont pas aussi familiers que SVG et qui peuvent très bien avoir généré leur fichier SVG à partir d'un paquet graphique (comme je l'ai fait).

pour appliquer les solutions de RGB J'ai utilisé:

The CSS

 <style>
    rect.btn {
        stroke:#fff;
        fill:#fff;
        fill-opacity:0;
        stroke-opacity:0;
    }
</style>

Le script 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>

le code HTML pour coder l'inclusion de votre fichier SVG préexistant dans la balise de groupe à l'intérieur du code 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>

cependant, dans mon cas, j'ai plusieurs icônes SVG que je souhaite être cliquable et l'intégration de chacun d'eux dans la balise SVG commençait à devenir encombrante.

comme alternative approche où je pourrais employer des Classes que j'ai utilisé jquery.svg. C'est probablement une application honteuse de ce plugin qui peut faire toutes sortes de choses avec SVG. Mais il a fonctionné en utilisant le code suivant:

<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>

où HTML

<div class="svgload" style="width: 10px; height: 10px;"></div>

L'avantage de ma pensée est que je peux utiliser la classe appropriée où jamais les icônes sont nécessaires et éviter beaucoup de code dans le corps du HTML qui favorise la lisibilité. Et j'ai seulement besoin de incorporez le fichier SVG préexistant une fois.

Edit: Ici est un plus propre version du script de courtoisie de Keith Bois: à l'aide .le réglage de l'URL de chargement de 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>
6
répondu codepuppy 2018-06-29 17:08:31

j'ai obtenu ce travail à travers les dernières versions de Firefox, Chrome, Safari et Opéra.

il s'appuie sur un div transparent devant l'objet qui a la position absolue et définit la largeur et la hauteur de sorte qu'il couvre la balise objet ci-dessous.

le voici, j'ai été un peu paresseux et utilisé des styles inline:

<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>

j'ai utilisé le JavaScript suivant pour connecter un événement à lui:

<script type="text/javascript">
    var toolbar = document.getElementById("toolbar");
    toolbar.onclick = function (e) {
        alert("Hello");
    };
</script>
4
répondu Richard Garside 2010-08-18 21:57:43

il a fonctionné en remplaçant simplement la balise <embed/> par <img/> et en supprimant l'attribut type.

par exemple, dans mon code, au lieu de:

<embed src=\"./images/info_09c.svg\" type=\"image/svg+xml\" width=\"45\" onClick='afiseaza_indicatie($i, \"$indicatii[$i]\")'> 

qui ne répond pas au clic, j'ai écrit:

<img src=\"./images/info_09c.svg\" height=\"25\" width=\"25\" onClick='afiseaza_indicatie($i, \"$indicatii[$i]\")'> 

il fonctionne dans Internet Explorer et Google Chrome, et j'espère que dans les autres navigateurs aussi.

3
répondu Mihai Daniel Frumușelu 2013-03-25 03:00:20

vous pouvez utiliser le code suivant:

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

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

b3ng0 a écrit un code similaire mais il ne fonctionne pas. l'index z du parent doit être automatique.

1
répondu Oleg Torbasow 2012-09-15 06:47:38

avez-vous cherché à utiliser la propriété CSS z-index pour que le conteneur dev soit" en haut " de la svg? Parce que la div est (probablement) transparente, vous verrez toujours l'image exactement comme avant.

C'est, je crois, la meilleure pratique, non-hack, destinée à résoudre votre problème. z-index est seulement utile pour les éléments qui ont une position propriété de fixed , relative , ou, comme vous l'avez entendu, absolute . Cependant, vous n'avez pas en fait déplacer l'objet.

par exemple:

<style>
    .svgwrapper {
        position: relative;
        z-index: 1;
    }
</style>
<div class="svgwrapper" onClick="function();">
    <object src="blah" />
</div>

pour ce que cela vaut, il serait également un peu plus élégant et sûr de ne pas utiliser onClick du tout, mais à la place de lier l'événement de clic en utilisant javascript. C'est une autre question tout à fait, si.

0
répondu b3ng0 2010-02-19 20:23:25

en supposant que vous n'avez pas besoin de support de navigateur croisé (ce qui est impossible sans un plugin pour IE), avez-vous essayé d'utiliser svg comme une image de fond ?

Expérimental, c'est sûr, mais j'ai pensé le mentionner.

0
répondu Russell Leggett 2010-03-24 15:09:24

peut-être que ce que vous recherchez est la propriété pointer-events de SVG element, que vous pouvez lire à propos de la propriété du groupe de travail SVG W3C docs .

vous pouvez utiliser CSS pour définir ce qui arrive à L'élément SVG quand il est cliqué, etc.

0
répondu Danny Bullis 2013-04-01 02:08:33

lors de l'intégration de SVG d'origine identique en utilisant <object> , vous pouvez accéder au contenu interne en utilisant objectElement.contentDocument.rootElement . De là, vous pouvez facilement attacher les gestionnaires d'événements (par exemple via onclick , addEventListener() , etc.)

par exemple:

var object = /* get DOM node for <object> */;
var svg = object.contentDocument.rootElement;
svg.addEventListener('click', function() {
  console.log('hooray!');
});

notez qu'il s'agit de pas possible pour les éléments cross-origin <object> sauf si vous contrôlez également le serveur <object> et que vous pouvez y placer des en-têtes CORS. Pour cas d'origine croisée sans en-têtes CORS, l'accès à contentDocument est bloqué.

0
répondu candu 2016-04-13 18:43:25

si vous utilisez simplement inline svg, il n'y a aucun problème.

<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>
  
0
répondu peter 2017-12-08 16:48:05