2012-01-18 13 views
20

Questa potrebbe sembrare una richiesta strana, ed è abbastanza fuori dal comune, ma è una sfida che sto cercando di risolvere.JavaScript: come serializzare un elemento DOM come una stringa da utilizzare in seguito?

Supponiamo di avere un elemento DOM composto da HTML e alcuni CSS applicati e alcuni listener di eventi JS. Vorrei clonare questo elemento (e tutti i CSS e JS applicati), serializzarlo come una stringa che potrei salvare in un database da aggiungere al DOM in una richiesta futura.

So che jQuery ha alcuni di questi metodi (come $ .css() per ottenere gli stili calcolati), ma come posso fare tutte queste cose e trasformarle in una stringa che posso salvare in un database?

Aggiornamento: Ecco un elemento di esempio:

<div id="test_div" class="some_class"> 
    <p>With some content</p> 
</div> 

<style> 
#test_div { width: 200px } 
.some_class { background-color: #ccc } 
</style> 

<script> 
$('#test_div').click(function(){ 
    $(this).css('background-color','#0f0'); 
}); 
</script> 

... e forse una serializzazione di esempio:

var elementString = $('#test_div').serializeThisElement(); 

che si tradurrebbe in una stringa che sembra qualcosa di simile:

<div id="test_div" 
    class="some_class" 
    style="width:200px; background-color:#ccc" 
    onclick="javascript:this.style.backgroundColor='#0f0'"> 
    <p>With some content</p> 
</div> 

così ho potuto inviarlo come richiesta AJAX:

$.post('/save-this-element', { element: elementString } //... 

Quanto sopra è solo un esempio. Sarebbe l'ideale se la serializzazione potesse sembrare molto simile all'esempio originale, ma se tutto fosse uguale all'originale, mi andrebbe bene.

+0

stiamo parlando di un singolo elemento? O una struttura DOM annidata di dimensioni arbitrarie? – nrabinowitz

+0

Puoi fornire una stringa di output di esempio che ti aspetteresti? –

+7

La memorizzazione dei riferimenti ai callback degli eventi non sarà affidabile. –

risposta

1
var elem = ...; 
var clone = elem.cloneNode(true); 
var uuid = get_uuid(); 
storedElements[uuid] = clone; 
storeInDatabase(uuid); 

/* some time later */ 

getFromDatabase(function (uuid) { 
    var elem = storedElements[uuid]; 
    /* do stuff */ 
}); 
+0

Questo presuppone l'archiviazione in memoria dell'elemento DOM, giusto? Non è chiaro se il PO vuole essere in grado di tornare in una nuova sessione ed essere in grado di deserializzare un elemento memorizzato - il suo approccio non avrebbe funzionato per questo scenario. – nrabinowitz

+0

@nrabinowitz nessun approccio funzionerebbe per quello scenario (senza motivo). – Raynos

+0

Bene, sono d'accordo che sarebbe stato difficile, e i gestori di eventi potrebbe essere impossibile da replicare in modo efficace (a meno che non si stava raccogliendo da un elenco limitato di gestori predefiniti). Ma dire che non è possibile sembra un po 'eccessivo. – nrabinowitz

-3

Questo ha senso se si utilizza jQuery?

$(this).serialize() 

Per esempio visita:

http://api.jquery.com/serialize/

+4

No, nonostante il nome, .serialize() non serializza gli oggetti al testo, ma piuttosto serializza i dati dei moduli in una stringa che può essere passato a un server – LocalPCGuy

1

Ho un pezzo di codice da un esempio di http://api.jquery.com/jQuery.extend/ che penso vi aiuterà a ottenere una stringa completa del vostro oggetto. Non ho ancora capito come tornare a un oggetto ancora. Ad ogni modo, penso che sia un inizio. Forse qualcun altro potrebbe completare questa risposta ... o io stesso lo faccio dopo.

Prima di tutto, creare un clone completo del vostro elemento:

var el = $('div').clone(true, true); 

Poi, il codice da api.jquery.com:

var printObj = function(obj) { 
    var arr = []; 
    $.each(obj, function(key, val) { 
     var next = key + ": "; 
     next += $.isPlainObject(val) ? printObj(val) : val; 
     arr.push(next); 
    }); 
    return "{ " + arr.join(", ") + " }"; 
}; 

Infine:

var myString = printObj($(el).get(0)); 
+0

fa questo eventi troppo? – ThinkingStiff

+0

Sì, penso di sì. Almeno se document.write (myString), vedrai l'intera cosa "stringificata". Come ho detto prima, semplicemente non ho provato un modo per trasformare la stringa indietro come un oggetto e vedere come si comporta. – emanuelpoletto

1

Penso che la cosa più facile da usare per ricreare il tuo oggetto HTML sarebbe un oggetto JSON, quindi avresti bisogno di una funzione che restituisca un Oggetto JSON, che è possibile quindi stringificare per archiviare in un DB. Qualcosa di simile a quanto segue potrebbe indirizzarti nella giusta direzione, ma ovviamente non sta funzionando completamente come è, sarebbe piuttosto dipendente dall'elemento DOM e dovresti scrivere anche la funzione di deserializeObject.

// NOT TESTED OR WORKING PROPERLY, FOR EXAMPLE ONLY 
    // htmlObject is a raw HTML DOM element 
    function serializeObject (htmlObject) { 
     var objectToStore = { 
      htmlElement: htmlObject.toString(), 
      id: htmlElement.id, 
      attrs: getAttrs(htmlObject) }, 
      css: htmlElement.style.cssText 
     } 
     return objectToStore; 
    } 
    function getAttrs(htmlObject) { 
     var tmp = [], i; 
     for (i = 0, i<htmlObject.attributes.length; i++) { 
     tmp.push({htmlObject.attributes[i].nodeName: htmlObject.attributes[i].value}); 
     } 
     return tmp; 
    } 
6

XMLSerializer.serializeToString() può essere utilizzato per convertire i nodi DOM a stringa.

var s = new XMLSerializer(); 
var d = document; 
var str = s.serializeToString(d); 
alert(str); 

MDN Link

Problemi correlati