2010-02-19 13 views
34

Ho provato a modificare le immagini sul mio sito da img a svg, cambiando img tag per embed e object tag. Tuttavia, l'implementazione della funzione onclick, che precedentemente era contenuta nel tag img, si sta rivelando molto difficile.Fare una cliccabile oggetto immagine SVG con onclick, evitando posizionamento assoluto

Ho trovato onclick non ha avuto effetto se inserito all'interno del tag object o embed.

Quindi, ho creato uno div esclusivamente per lo svg e inserito onclick in questo tag div. Ma, nessun effetto a meno che il visitatore non clicchi sui bordi/padding dell'immagine.

Ho letto di sovrapporre un div, ma sto cercando di evitare di utilizzare il posizionamento absolute o di specificare position affatto.

C'è un altro modo per applicare onclick a un svg?

Qualcuno ha riscontrato questo problema? Domande e suggerimenti sono benvenuti.

risposta

0

Hai esaminato la proprietà CSS z-index per rendere il contenitore dev "in cima" allo svg? Poiché il div è (presumibilmente) trasparente, vedrai comunque l'immagine esattamente come prima.

Questo, credo, è il modo migliore per risolvere il problema. z-index è utile solo per gli elementi che hanno una proprietà position di fixed, relative o, come hai sentito, absolute. Tuttavia, non è necessario spostare l'oggetto.

Ad esempio:

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

Per quello che vale, sarebbe anche essere un po 'più elegante e sicuro da usare, non onClick a tutti, ma invece di impegnare l'evento click utilizzando JavaScript. Questo è un altro problema, comunque.

+0

Questo non funziona. –

0

Supponendo che non sia necessario il supporto per browser incrociato (cosa impossibile con un plug-in per IE), hai provato a utilizzare svg as a background image?

Roba sperimentale, ma ho pensato di parlarne.

+0

Bella idea, ma la mancanza di supporto per Firefox mi allontana da questa idea. –

3

Ho ottenuto questo funzionamento attraverso le ultime versioni di Firefox, Chrome, Safari e Opera.

Si basa su una div trasparente prima dell'oggetto che ha posizione assoluta e imposta larghezza e altezza in modo che copra il tag dell'oggetto sottostante.

Eccola, sono stato un po 'porcili linea pigri e usati:

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

Ho usato il seguente JavaScript per collegare un evento ad esso:

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

Si può avere un evento onclick nella stessa svg, lo faccio sempre nel mio lavoro.fare un rettangolo sopra lo spazio della tua SVG, (in modo da definire l'ultima, ricordate SVG utilizza il modello di pittori)

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

poi come un attributo al rect aggiungere l'onclick (questo può essere fatto con js o jQuery come bene).

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

questo funzionerà nella maggior parte dei browser moderni, http://caniuse.com/svg ... ma se avete bisogno di compatibilità incrociata, è possibile implementare Google Chrome Frame. http://www.google.com/chromeframe

+3

WOWZA! 3k views/2 anni, e nessuno ha inventato questo? lol crazy .. – RGB

+0

Sì, questo ha funzionato per me, volevo solo aggiungere alcuni commenti/chiarimenti. Si prega di vedere la risposta inviata. – codepuppy

+0

Bella soluzione. Per il CSS sembra che tutto ciò che è necessario sia 'fill-opacity: 0'. Perché imposti 'stroke',' fill' e 'stroke-opacity'? – evanrmurphy

1

È possibile utilizzare seguente codice:

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

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

b3ng0 ha scritto un codice simile, ma non funziona. z-index di parent deve essere auto.

6

Questo è iniziato come un commento sulla soluzione di RGB, ma non ho potuto inserirlo in modo da averlo convertito in una risposta. L'ispirazione per la quale è interamente RGB.

La soluzione RGB ha funzionato per me. Tuttavia ho voluto notare un paio di punti che possono aiutare gli altri che arrivano a questo post (come me) che non sono così familiari quale svg e che potrebbe benissimo aver generato il loro file svg da un pacchetto di grafica (come avevo fatto io).

Quindi, per applicare soluzioni di RGB che ho usato:

Il css

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

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

il codice HTML per codificare l'inserimento del vostro preesistente file in formato SVG nel tag di gruppo all'interno del codice 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> 

Tuttavia nel mio caso ho diverse icone SVG che desidero di essere cliccabile e incorprating ciascuno di questi nel tag SVG stava iniziando a diventare ingombrante.

Quindi come approccio alternativo dove potrei utilizzare le classi ho usato jquery.svg. Questa è probabilmente una vergognosa applicazione di questo plugin che può fare ogni genere di cose con SVG. Ma ha funzionato utilizzando il seguente codice:

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

dove html

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

Il vantaggio per il mio pensiero è che posso utilizzare la classe appropriata dove mai sono necessarie le icone ed evitare un bel po 'di codice nel corpo dell'html che aiuta la leggibilità. E ho solo bisogno di incorporare il file svg pre esistente una volta.

Modifica: Ecco una versione più netta della sceneggiatura per gentile concessione di Keith Wood: utilizzando l'impostazione URL di caricamento di .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

ha funzionato semplicemente sostituendo il tag <embed/> con <img/> ed eliminazione type.

Per esempio, nel mio codice, invece di:

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

che non risponde al clic, ho scritto:

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

Funziona in Internet Explorer e Google Chrome, e spero anche negli altri browser.

+0

Immagino che tu stia sfuggendo alle quotazioni per xml o qualcosa del genere, ma questo ha funzionato almeno in IE, quando non funzionava quando mostrava un file svg in un (simile all'esempio di embed). Finché utilizzi i browser moderni, non vedo perché questo non sarebbe il modo più semplice quando usi html5/js roba come whyoz

+1

Provato a sostituire un riferimento con img src per ottenere onclick di funzionare. Testato lavorando con Safari, Chrome e Firefox e Chrome su Android. Grazie per questa soluzione - è molto più semplice ed evita di ingombrare il mio svg con javascript in linea. –

0

Forse quello che stai cercando è la proprietà puntatore-evento del puntatore dell'elemento SVG, che puoi leggere su SVG w3C working group docs.

È possibile utilizzare i CSS per impostare ciò che accade all'elemento SVG quando viene cliccato, ecc

0

Quando l'incorporamento SVG stesso di origine utilizzando <object>, è possibile accedere ai contenuti interni utilizzando objectElement.contentDocument.rootElement. Da lì, si può facilmente collegare i gestori di eventi (ad esempio via onclick, addEventListener(), etc.)

Ad esempio:

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

Si noti che questo non è possibile per il cross-origin <object> elementi a meno che anche controlla il server di origine <object> e può impostare le intestazioni CORS lì. Per i casi di origine incrociata senza intestazioni CORS, l'accesso a contentDocument è bloccato.

0

Se si utilizza solo inline svg non ci sono problemi.

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

Problemi correlati