2012-01-18 7 views
20

Może to wydawać się dziwną prośbą i jest to dość niezwykłe, ale jest to wyzwanie, które próbuję rozwiązać.JavaScript: jak serializować element DOM jako ciąg do późniejszego użycia?

Załóżmy, że masz element DOM, który składa się z kodu HTML i niektórych zastosowanych stylów CSS oraz niektórych detektorów zdarzeń JS. Chciałbym sklonować ten element (i wszystkie stosowane CSS i JS), serializować je jako ciąg, który mógłbym zapisać w bazie danych, aby dodać ją do DOM w przyszłym żądaniu.

Wiem, że jQuery ma kilka z tych metod (takich jak $ .css(), aby uzyskać obliczone style), ale jak mogę zrobić te wszystkie rzeczy i przekształcić je w ciąg znaków, który mogę zapisać w bazie danych?

Aktualizacja: Tutaj jest elementem przykład:

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

... a może serializacji próbki:

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

co skutkowałoby sznurku, który wygląda mniej więcej tak:

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

, więc mogę wysłać go jako żądanie AJAX:

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

Powyższe stanowi jedynie przykład. Byłoby idealnie, gdyby serialowanie mogło wyglądać bardzo podobnie do oryginalnego przykładu, ale dopóki będzie to samo, co oryginał, byłoby mi z tym dobrze.

+0

Czy mówimy o jednym elemencie? Lub zagnieżdżoną strukturę DOM o dowolnym rozmiarze? – nrabinowitz

+0

Czy możesz podać przykładowy ciąg wyjściowy, którego można się spodziewać? –

+7

Przechowywanie odwołań do wywołań zwrotnych zdarzeń nie będzie niezawodne. –

Odpowiedz

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

Zakłada to przechowywanie elementu DOM w pamięci, prawda? Nie jest dla mnie jasne, czy OP chce być w stanie powrócić na nową sesję i móc deserializować przechowywany element - twoje podejście nie zadziałałoby w tym scenariuszu. – nrabinowitz

+0

@nrabinowitz nie byłoby podejście do tego scenariusza (bez powodu). – Raynos

+0

Cóż, zgadzam się, że byłoby to trudne, a obsługa zdarzeń mogłaby być niemożliwa do powielenia (chyba że wybierano z ograniczonej listy wstępnie zdefiniowanych procedur obsługi). Ale powiedzenie, że to niemożliwe, wydaje się nieco przesadzone. – nrabinowitz

-3

Czy ma to sens, jeśli używasz jQuery?

$(this).serialize() 

Na przykład wizyta:

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

+4

Nie, pomimo swojej nazwy, .serialize() nie serializuje obiektów do tekstu, ale przekształca dane formularza w ciąg znaków, który można przekazać do serwera. – LocalPCGuy

1

Mam kawałek kodu z przykładu http://api.jquery.com/jQuery.extend/ że myślę, że pomogą Ci uzyskać pełny ciąg Twojego obiektu. Po prostu nie wiedziałem, jak wrócić do obiektu. W każdym razie, myślę, że to początek. Może ktoś inny może ukończyć tę odpowiedź ... lub sam to zrobię później.

Przede wszystkim stworzyć kompletny klon swojego elementu:

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

Następnie kod z 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(", ") + " }"; 
}; 

Wreszcie:

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

Czy to też powoduje zdarzenia? – ThinkingStiff

+0

Tak, tak myślę. Przynajmniej jeśli będziesz document.write (myString), zobaczysz całość "usztywniona". Jak już wspomniałem, po prostu nie przetestowałem sposobu, aby z powrotem przywrócić łańcuch jako obiekt i zobaczyć, jak się on zachowuje. – emanuelpoletto

1

Myślę, że najłatwiejszą rzeczą do odtworzenia obiektu HTML byłby obiekt JSON, więc potrzebna byłaby funkcja, która zwróciłaby Obiekt JSON, który można następnie uszeregować w celu przechowywania w DB. Coś takiego jak poniższe może wskazywać ci właściwy kierunek, ale oczywiście nie działa tak jak jest, byłoby całkiem zależne od elementu DOM i musiałbyś napisać funkcję również do 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() może być użyty do konwersji węzłów DOM na łańcuch.

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

MDN Link

Powiązane problemy