2014-07-25 11 views
7

Sto creando una struttura dom che comprende un elemento SVG:SVG non mostrerà fino a quando posso modificare l'elemento in strumenti di sviluppo Chrome

<div data-bind="with: searchable_select.f0000001" style="verticalAlign: top"> 
    <input data-bind="value: select_filter_value, valueUpdate: 'afterkeydown', event: { change: change_filter_, blur: blur_filter_ }" style="display: none"> 
    <div> 
    <select data-bind="options: select_list, value: working_value, event: { change: change_selector_ }, optionsText: 'label', optionsValue: 'value'" style="display: inline-block; maxWidth: 150px"> 
     <option value="person_full_name_asc">Member Full Name (A-Z)</option> 
     <option value="person_full_name_desc">Member Full Name (Z-A)</option> 
    </select> 
    <svg style="display: inline-block; verticalAlign: middle" width="18" height="18" xmlns="http://www.w3.org/2000/svg" version="1.1"> 
     <g> 
     <circle cx="6" cy="6" r="5" fill="#AAAAAA" stroke="#000000" stroke-width="2"></circle>  
     <path fill="#AAAAAA" stroke="#000000" stroke-width="2" d="M10,10 L17,17"></path> 
     </g> 
    </svg> 
    </div> 
</div> 

L'elemento SVG in realtà non visualizzare. Quando trovo l'elemento svg negli strumenti di sviluppo di Chrome, sia la larghezza che l'altezza vengono visualizzati come zero.

Ho provato a rimuovere l'attributo di stile. Ho provato a impostare la larghezza e l'altezza nell'attributo style.

Ho copiato lo SVG in un file HTML separato:

<html> 
<head><title>maggen</title></head> 
<body> 
    <svg style="display: inline-block; verticalAlign: middle" width="18" height="18" xmlns="http://www.w3.org/2000/svg" version="1.1"> 
    <g> 
     <circle cx="6" cy="6" r="5" fill="#AAAAAA" stroke="#000000" stroke-width="2"></circle> 
     <path fill="#AAAAAA" stroke="#000000" stroke-width="2" d="M10,10 L17,17"></path> 
    </g> 
    </svg> 
</body> 
</html> 

Dove si mostra bene.

Se avvolgo l'elemento svg in un div, viene visualizzato l'elemento svg. Infatti, se modifico l'HTML negli strumenti di sviluppo di Chrome, verrà visualizzato.

Quindi, sì, perché? Ho fatto una ricerca su Google per questo, ma o non c'è o (più probabilmente) il mio Google Fu non è all'altezza del compito. Voglio dire, certo, posso avvolgerlo in un div - e forse è la cosa giusta da fare - ma preferirei non perché poi avrei bisogno di avvolgere altre cose in div e la dom inizierà a essere ingombra.

MODIFICA: Su un'intuizione, ho provato a modificare l'attributo viewport nell'elemento SVG negli strumenti di Chrome. Ecco! L'elemento è visibile! Aspettatevi quando ho incluso l'attributo viewport durante la creazione del documento, non è visibile. Così ho provato ad aggiungere un attributo casuale negli strumenti di Chrome all'elemento SVG. Ecco! L'elemento è visibile! Quindi, ho pensato, il problema è specifico di Chrome e ho provato a farlo funzionare in Firefox ...

... dove l'elemento non viene visualizzato.

MODIFICA: Grande, quindi non è garantito che lo si avvolga in un div. Ma fare una "modifica come HTML" negli strumenti di sviluppo di Chrome lo fa apparire.

EDIT: Bene, ho ottenuto che funzioni correttamente e, sì, risulta essere una funzione del Javascript che crea gli elementi DOM. C'è un sacco di roba nel codice, ma posso bollire fino a questo:

Questo codice funziona (createElement crea un tag e imposta attributi basati sul passato nei parametri):

var div = this.createElement(
    'div', 
    element_name + '_div', 
    null, style_options, null, null 
); 

div.innerHTML = [ 
    '<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width=' + width + ' height=' + height + '>', 
    svg_xml.join(''), 
    '</svg>' 
].join(''); 

if (parent) parent.appendChild(div); 
return div; 

Questo codice doesn 't:

var svg = this.createElement('svg', element_name, null, style_options, classlist, { 
    viewport: '0 0 ' + width + ' ' + height, 
    version: "1.1", 
    xmlns: "http://www.w3.org/2000/svg", 
    width: width, 
    height: height 
}); 

svg.innerHTML = svg_xml.join(''); 

if (parent) parent.appendChild(svg); 
return svg; 

Quindi, certo, ho qualcosa che funziona ora, ma non capisco perché. O più al punto, non capisco perché un modo funziona e l'altro no. Ho un paio di ipotesi, ma sono solo supposizioni selvagge, davvero.

+0

hai provato a lavorare in larghezza l'attributo Viewbox? Per esempio. Matthias

+1

Devi aggiungere il codice che hai scritto per creare gli elementi DOM, altrimenti ci stai chiedendo di leggere quale sia il problema e non siamo troppo bravi quella. –

+0

In realtà ho provato a utilizzare l'attributo viewBox. Non ha fatto differenza La mia ipotesi migliore a questo punto ha a che fare con quando l'elemento viene effettivamente reso. – aikimcr

risposta

13

"Ho qualcosa che funziona ora, ma non capisco perché."

Il problema è che i metodi si stava utilizzando non creano un elemento SVG nel namespace SVG. L'attributo xmlns influisce solo sul comportamento di un parser XML, non sui metodi DOM.

Non sono sicuro di quale libreria si sta utilizzando per il metodo this.createElement() con più parametri. Tuttavia, ho il sospetto che probabilmente inizi chiamando il metodo base document.createElement(tagName). Questo è ciò che MDN says about the standard DOM createElement method:

In un documento HTML crea l'elemento HTML specificato o HTMLUnknownElement se l'elemento non è noto. ... In altri documenti crea un elemento con un namespace nullURI.

In altre parole, perché sei (presumibilmente, indirettamente) chiamando createElement su un documento HTML, si crea sempre un elemento HTML. Un elemento HTML con il nome del tag "svg" è trattato come un elemento di tipo span sconosciuto.

Al contrario, usare div.innerHTML per passare una stringa di markup crea correttamente l'elemento SVG perché invoca il parser HTML5 per capire quale tipo di elemento creare. Lo spazio dei nomi viene determinato utilizzando le stesse regole di quando si analizza il markup da un file. La modifica dell'HTML negli strumenti per sviluppatori di Chrome ha lo stesso effetto.

Nota a margine: evitare di chiamare .innerHTML su un elemento SVG. Alcuni browser lo supportano, ma non fa parte delle specifiche. Non ricevi un errore perché la tua variabile svg è in realtà un'istanza di HTMLUnknownElement. Il passaggio del codice SVG al metodo innerHTML di un genitore <div> di solito funziona, sebbene vi siano alcuni bug con l'animazione SMIL. Come dice @Robert Longson nei commenti, è possibile utilizzare lo DOMParser object per analizzare codice HTML o XML in un documento.

L'altro modo per creare dinamicamente un elemento SVG è utilizzare document.createElementNS(namespaceURI, tagName). Dovrai inoltre utilizzare questo metodo per creare tutti gli elementi figlio di SVG. Una volta creati, potresti essere in grado di impostare attributi, stili e classi usando i tuoi metodi di libreria. (Ma non hai specificato quale libreria stai usando, quindi non sono sicuro.)

+0

In realtà non sto usando una libreria. È tutto roll-my-own. Ma fa proprio quello che descrivi, quindi la tua spiegazione è esattamente ciò di cui avevo bisogno. Spiega chiaramente il problema. Sto anche andando a sperimentare con createElementNS per questo. Grazie. – aikimcr

+0

Buono a sapersi. Poiché è la tua funzione, dovrebbe essere abbastanza semplice adattarsi. – AmeliaBR

Problemi correlati