wake-up-neo.net

Ein svg-Bildobjekt mit onclick anklickbar machen, um eine absolute Positionierung zu vermeiden

Ich habe versucht, die Bilder auf meiner Website von img in svg zu ändern, img-Tags in embed- und object-Tags zu ändern. Am schwierigsten ist jedoch die Implementierung der onclick-Funktion, die zuvor im img-Tag enthalten war.

Ich fand, dass onclick keine Auswirkung hatte, wenn sie innerhalb des Tags object oder embed platziert wurde.

Also habe ich eine div ausschließlich für das svg erstellt und onclick in dieses div-Tag eingefügt. Keine Wirkung, es sei denn, der Besucher klickt auf die Ränder/Auffüllung des Bildes.

Ich habe über das Überlagern einer div gelesen, versuche jedoch die Verwendung der absolute-Positionierung oder die Angabe von position zu vermeiden.

Gibt es eine andere Möglichkeit, Onclick auf ein SVG anzuwenden?

Hat jemand dieses Problem festgestellt? Fragen und Anregungen sind willkommen.

47
user256410

Sie können ein Onclick-Ereignis in der SVG-Datei selbst durchführen. Ich mache dies ständig in meiner Arbeit. Machen Sie ein Rect über dem Raum Ihrer SVG (so definieren Sie es zuletzt, denken Sie daran, dass SVG das Malermodell verwendet) 

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

fügen Sie dann als ein Attribut dem Rect den Onclick hinzu (dies kann auch mit Js oder Jquery erfolgen).

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

dies wird in den meisten modernen Browsern funktionieren, http://caniuse.com/svg ... Wenn Sie jedoch Cross-Kompatibilität benötigen, können Sie Google Chrome Frame implementieren. http://www.google.com/chromeframe

55
RGB

Dies begann als Kommentar zur Lösung von RGB, aber ich konnte es nicht anpassen und habe es in eine Antwort umgewandelt. Die Inspiration dafür ist ausschließlich RGB.

Die Lösung von RGB hat für mich funktioniert. Ich möchte jedoch ein paar Punkte ansprechen, die anderen dabei helfen könnten, an diesem Beitrag anzukommen (wie ich), die nicht so vertraut sind, welche SVG-Dateien und wer möglicherweise ihre SVG-Datei aus einem Grafikpaket generiert haben (wie ich es hatte).

Um die RGB-Lösungen anzuwenden, habe ich verwendet:

Das CSS

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

Das Jquery-Skript

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

Der HTML-Code zum Kodieren der Aufnahme Ihrer bereits vorhandenen SVG-Datei in den Gruppentag im SVG-Code.

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

In meinem Fall habe ich jedoch mehrere SVG-Symbole, die ich anklickbar machen möchte. Jedes dieser Elemente in den SVG-Tag zu integrieren, wurde langsam.

Als alternativen Ansatz, bei dem ich Klassen einsetzen konnte, habe ich jquery.svg verwendet. Dies ist wahrscheinlich eine beschämende Anwendung dieses Plugins, das mit SVGs alle möglichen Dinge tun kann. Es funktionierte jedoch mit folgendem Code:

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

wo HTML

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

Der Vorteil meines Denkens besteht darin, dass ich die entsprechende Klasse verwenden kann, wo immer die Symbole benötigt werden, und viel Code im Rumpf des HTML-Codes vermeiden, der die Lesbarkeit erleichtert. Und ich muss nur einmal die vorhandene SVG-Datei einbauen.

Edit: Hier ist eine schönere Version des Skripts mit freundlicher Genehmigung von Keith Wood: Verwendung der Lade-URL-Einstellung von .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
codepuppy

Ich habe diese Funktion für die neuesten Versionen von Firefox, Chrome, Safari und Opera verwendet.

Es basiert auf einem transparenten div vor dem Objekt mit absoluter Position und festgelegter Breite und Höhe, sodass das darunterliegende Objekt-Tag abgedeckt wird.

Hier ist es, ich war ein bisschen faul und habe Inline-Styes benutzt:

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

Ich habe das folgende JavaScript verwendet, um ein Ereignis daran anzuschließen:

<script type="text/javascript">
    var toolbar = document.getElementById("toolbar");
    toolbar.onclick = function (e) {
        alert("Hello");
    };
</script>
4
Richard Garside

Es funktionierte, indem einfach das <embed/>-Tag durch <img/> ersetzt und das type-Attribut gelöscht wurde. 

Zum Beispiel in meinem Code anstelle von:

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

was das Klicken nicht beantwortet, schrieb ich:

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

Es funktioniert in Internet Explorer und Google Chrome, und ich hoffe, dass es auch in den anderen Browsern funktioniert.

Sie könnten folgenden Code verwenden:

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

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

b3ng0 hat ähnlichen Code geschrieben, funktioniert aber nicht. Der z-Index des übergeordneten Elements muss automatisch sein.

1
Oleg Torbasow

Wenn Sie nur Inline-SVG verwenden, gibt es kein Problem.

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

Vielleicht suchen Sie nach der pointer-events - Eigenschaft des SVG-Elements, die Sie in der SVG w3C-Arbeitsgruppe docs nachlesen können.

Sie können CSS verwenden, um festzulegen, was mit dem SVG-Element passiert, wenn es angeklickt wird usw.

0
Danny Bullis

Klicken Sie mit dem Ereignis click auf das Element <g> von SVG in <object>. Funktioniert 100%. Schauen Sie sich das verschachtelte Javascript in <svg> an. Vergessen Sie nicht, window.parent.location.href= einzufügen, wenn Sie die übergeordnete Seite umleiten möchten.

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

0
Imeksbank

Haben Sie die Verwendung der CSS-Eigenschaft z-index geprüft, damit der Container dev "oben auf" der svg ist? Da das div (vermutlich) transparent ist, sehen Sie das Bild immer noch genau wie zuvor.

Ich glaube, dies ist der beste Weg, um Ihr Problem zu lösen. z-index ist nur für Elemente nützlich, die eine position-Eigenschaft von fixed, relative oder, wie Sie gehört haben, absolute ist. Sie müssen das Objekt jedoch nicht wirklich verschieben.

Zum Beispiel:

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

Für das, was es wert ist, wäre es auch ein bisschen eleganter und sicherer, onClick überhaupt nicht zu verwenden, sondern das Click-Ereignis mit JavaScript zu binden. Das ist jedoch ein ganz anderes Thema.

0
b3ng0

Beim Einbetten von Same-Origin-SVGs mit <object> können Sie mit objectElement.contentDocument.rootElement auf den internen Inhalt zugreifen. Von dort aus können Sie Ereignishandler einfach anhängen (z. B. über onclick, addEventListener() usw.).

Zum Beispiel:

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

Beachten Sie, dass dies nicht möglich ist für Cross-Origin-<object>-Elemente, sofern Sie nicht auch den <object> Origin-Server steuern und dort CORS-Header setzen können. Bei Fällen ohne Herkunftsnachweis ohne CORS-Header ist der Zugriff auf contentDocument gesperrt.

0
candu

Angenommen, Sie benötigen keine Cross-Browser-Unterstützung (was ohne ein Plugin für den IE nicht möglich ist), haben Sie versucht, svg als Hintergrundbild zu verwenden ?

Experimentelles Zeug sicher, aber ich dachte, ich würde es erwähnen.

0
Russell Leggett