2012-03-24 16 views
20

Ho un'estensione dove sto memorizzando/recuperando una sezione della struttura DOM (sempre una selezione di testo sullo schermo) che l'utente ha selezionato. Quando sto memorizzando una selezione, accludo la sezione in un tag SPAN e evidenziamo il testo in giallo. Ciò fa sì che la struttura DOM attorno al testo selezionato divida in vari nodi di testo. Questo mi crea un problema poiché quando provo a ripristinare questa selezione (senza aggiornare la pagina), questo causa problemi poiché la struttura DOM è stata modificata.Unione di nodi di testo insieme dopo aver inserito l'intervallo

La mia domanda è come evitare che la struttura DOM si divida dopo aver inserito lo SPAN? Se questo non può essere raggiunto, come dovrei riassemblare la struttura DOM dopo aver rimosso il tag SPAN al suo stato originale?

//Insert the span 
var sel = restoreSelection(mootsOnPage[i].startXPath); 
var range = sel.getRangeAt(0).cloneRange(); 
var newNode = document.createElement('span'); 
newNode.className = 'highlightYellow'; 
range.surroundContents(newNode); 


//Original DOM structure 
<p>Hello there, how are you today</p> 


//What the DOM looks like after insertion of SPAN 
<p> 
    "Hello there, " 
    <span class="highlightYellow">how</span 
    " are you today" 
</p> 
+0

Perché questo è importante? Hai altro codice che dipende da una struttura specifica? – bernie

+0

Sì, lo so. Sto usando il codice trovato qui (http://home.arcor.de/martin.honnen/javascript/storingSelection1.html) per aiutarmi a memorizzare/ripristinare una selezione di testo. Richiede che la struttura DOM sia invariata. – Jon

+0

Interessante, grazie per il chiarimento e buona fortuna – bernie

risposta

-5

È possibile utilizzare questo per scartare il contenuto.

$(".highlightYellow").contents().unwrap(); 

Demo: http://jsfiddle.net/R4hfa/

+2

Mentre ho letto la domanda dell'OP, non stanno chiedendo come rimuovere lo span. Stanno chiedendo come riassemblare i nodi di testo che sono stati divisi al momento dell'aggiunta dello span. – jfriend00

+0

da quello che ho capito, sta evidenziando la parte di un contenuto e lo memorizza e quando tenta di ripristinarlo, ottiene il contenuto modificato a causa dell'evidenziazione (che ha aggiunto degli span aggiuntivi). Questo 'La mia domanda è: come impedire che la struttura DOM si divida dopo aver inserito lo SPAN?' Non può essere fatto a meno che non copra tutto il testo con 'span.highlightYellow'. Invece la mia risposta risponde a 'come dovrei riassemblare la struttura DOM dopo aver rimosso il tag SPAN al suo stato originale?' Domanda. – codef0rmer

+0

La tua domanda risponde a come rimuovere il tag span che è stato inserito. Se questo è tutto ciò che chiedeva allora, ce l'hai. Ho pensato che stessero chiedendo come riportare i nodi di testo a come erano prima che venissero divisi attorno al tag span a cui ho cercato di rispondere. L'unica cosa su cui potremmo essere d'accordo è che la questione non è del tutto chiara su questo punto. – jfriend00

5

L'atto stesso di inserire un tag <span> altera il DOM. Questo è, un po 'per definizione, quello che stai facendo quando chiami surroundContents(). Non è possibile aggiungere un tag span senza alterare il DOM che include la divisione dei nodi di testo e l'aggiunta di nuovi elementi per lo span.

Inoltre, a meno che il testo selezionato includa solo nodi di testo interi e la selezione non si avvii/si arresti mai nel mezzo di un nodo di testo, sarà necessario dividere i nodi di testo per collocare lo span nel punto giusto. Quando in seguito rimuovi i tag span, avrai nodi di testo aggiuntivi. Questo non dovrebbe davvero importare nulla, ma se pensi davvero di dover riportare i nodi divisi al loro stato, posso pensare ad un paio di opzioni:

1) Salva il parentNode originale prima dell'intervallo è inserito in esso. Clona, ​​aggiungi l'estensione al clone, sostituisci il nodo originale con il clone e salva l'originale. Quando si desidera ripristinare, reinserire l'originale e rimuovere quello clonato.

2) Quando si rimuove lo span, eseguire una funzione che cerca nodi di testo vicini e combinarli.

3) Scopri perché è importante che ci siano più nodi di testo rispetto a prima, perché questo non dovrebbe importare alcun codice o display.

+5

So che questo è vecchio, ma il tuo # 3. Può essere importante per il testo che evidenzia i plugin che si basano su nodi di testo. Se il plugin guarda tutti i nodi di testo degli elementi selezionati per le corrispondenze, non troverà una corrispondenza divisa tra due nodi di testo adiacenti (probabilmente a causa di un'evidenziazione precedente annullata). L'unione dei due risolverebbe il problema, anche se suppongo che il plugin di evidenziazione possa farlo mentre cerca le corrispondenze. –

+5

Voglio solo aggiungere un commento riguardante il n. C'è un metodo DOM che fa questo: [normalize()] (https://developer.mozilla.org/en-US/docs/DOM/Node.normalize) – tcovo

+0

@tcovo - Interessante. Non ho mai saputo di normalizzare(). Buono a sapersi. – jfriend00

63

Usa element.normalize().

Dopo aver rimosso lo span inserito, è possibile utilizzare il metodo element.normalize() per unire i nodi di testo aggiuntivi creati in seguito all'inserimento/rimozione dello span. Il metodo normalize() mette l'elemento specificato e tutti i suoi sottoalberi in un formato "normalizzato" (cioè nessun nodo di testo nel sottoalbero è vuoto e non ci sono nodi di testo adiacenti). Trovato, grazie al commento di @ tcovo.

I nodi di testo all'interno di un elemento si rompono se si inseriscono nodi e quindi si rimuovono. Sfortunatamente non si riorganizzano automaticamente una volta rimosso il nodo aggiuntivo. Per rispondere alle domande delle persone sul "perché" questo è importante, di solito causa problemi quando si lavora con l'evidenziazione del testo nell'interfaccia utente.

+1

Wow grazie per il suggerimento! – silkAdmin

+3

Santa merda, grazie! Ho cercato 2 ore. Tieni presente che 'normalize()' deve essere chiamato su un elemento DOM e non su un oggetto jQuery. Dovrai selezionare il primo oggetto nell'array selettore jQuery come '$ ('section.scope p') [0] .normalize();' – Archonic

+11

questo dovrebbe essere contrassegnato come risposta, piuttosto che quello contrassegnato ora. – shankardevy

1

Quando si utilizza normalize() fare attenzione! Eliminerà i nodi come <br/> e modificherà il testo e la sua visualizzazione.

normalize() è buono, ma ha i suoi svantaggi.

Così <p>"this is an "<br/>"example"</p> si trasformerà in <p>this is an example</p>

C'è un modo per utilizzare normalize() ma mantenendo le <br/> s?

Problemi correlati