Memorizza l'oggetto JSON nell'attributo data in HTML jQuery


134

Sto memorizzando i dati usando l' data-approccio in un tag HTML in questo modo:

<td><"button class='delete' data-imagename='"+results[i].name+"'>Delete"</button></td>

Sto quindi recuperando i dati in un callback come questo:

$(this).data('imagename');

Funziona benissimo. Ciò su cui sono bloccato è cercare di salvare l'oggetto anziché solo una delle sue proprietà. Ho provato a fare questo:

<td><button class='delete' data-image='"+results[i]+"'>Delete</button></td>

Quindi ho provato ad accedere alla proprietà name in questo modo:

var imageObj = $(this).data('image');
console.log('Image name: '+imageObj.name);

Il diario mi dice undefined. Quindi sembra che posso memorizzare semplici stringhe negli data-attributi ma non riesco a memorizzare oggetti JSON ...

Ho anche provato a usare questo bambino di sintassi senza fortuna:

<div data-foobar='{"foo":"bar"}'></div>

Qualche idea su come archiviare un oggetto reale nel tag HTML usando l' data-approccio?

Risposte:


140

invece di incorporarlo nel testo basta usare $('#myElement').data('key',jsonObject);

in realtà non verrà archiviato nell'html, ma se si utilizza jquery.data, tutto ciò viene comunque sottratto.

Per riavere JSON non analizzarlo , basta chiamare:

var getBackMyJSON = $('#myElement').data('key');

Se ricevi [Object Object]invece di JSON diretto, accedi al tuo JSON con la chiave dati:

var getBackMyJSON = $('#myElement').data('key').key;

1
Quindi l'uso dell'approccio dati mi permette di memorizzare il valore per ciascun pulsante di eliminazione (ogni pulsante ottiene un diverso oggetto json ...) che ho nella tabella inserendo il tag hmtl come mostrato sopra. Quello che stai suggerendo mi consentirà di associare ogni oggetto al pulsante di eliminazione corrispondente? Come lo farei, come dovrei usare $ ('# myElement'). nello stesso modo? Mi dispiace, non ho esperienza su questo. Grazie
zumzum il

Quindi ho finito per assegnare un indice a ciascun pulsante html: <td> <button class = 'delete' data-index = '"+ i +"'> Elimina </button> </td> e memorizzando un array di oggetti JSON in una variabile $ objects. Quindi quando si fa clic su un pulsante, guardo l'indice del pulsante facendo: var buttonIndex = $ (this) .data ('index'); e quindi ottengo l'oggetto corrispondente dal precedentemente salvato in questo modo: $ objects [buttonIndex]. Funziona bene, non sono sicuro che sia il modo corretto di farlo. Grazie per il tuo feedback!
zumzum,

Se il campo contiene il codice JSON dalla codifica PHP, ti consigliamo di farlo: htmlspecialchars(json_encode($e))(idea di Nicolas, rispondi ai commenti).
CPHPython,

nel primo esempio, jsonObjectdeve essere rigoroso? edit: in caso aiuta chiunque altro, ho appena trovato la risposta a questa domanda qui: stackoverflow.com/a/42864472 "You don't need to stringify objects to store them using jQuery.data()"
user1063287

154

In realtà, il tuo ultimo esempio:

<div data-foobar='{"foo":"bar"}'></div>

sembra funzionare bene (vedi http://jsfiddle.net/GlauberRocha/Q6kKU/ ).

La cosa bella è che la stringa nell'attributo data viene automaticamente convertita in un oggetto JavaScript. Non vedo alcun inconveniente in questo approccio, al contrario! Un attributo è sufficiente per memorizzare un intero set di dati, pronto per l'uso in JavaScript tramite le proprietà degli oggetti.

(Nota: affinché agli attributi di dati sia assegnato automaticamente il tipo Object anziché String, è necessario fare attenzione a scrivere JSON valido, in particolare per racchiudere i nomi delle chiavi tra virgolette doppie).


20
Se aiuta nessuno, ecco come accedere alla sopra: $('div').data('foobar').foo. api.jquery.com/data
Gary

5
@GlauberRocha, Cosa succede se i dati contengono una virgoletta singola? 'non funziona per me mentre echo json_encode($array)provengo da PHP. Poiché terminerà il valore dell'attributo con una virgoletta singola. Qualche suggerimento tranne la fuga manuale di una singola virgoletta dall'array.
Ravi Dhoriya ツ

1
@ Log1c ツ Solo un'idea: prova a codificare il tuo 'come &amp;quot;(entità HTML con doppio escape) in modo che venga visualizzato nel tuo sorgente come & quot ;. Ma forse è questo il tipo di cose che vuoi evitare quando dici "scappare manualmente da una singola virgoletta" ...
Nicolas Le Thierry d'Ennequin il

2
@GlauberRocha grazie per la risposta. L'ho risolto usando lo stesso trucco. Ho usato htmlspecialchars () [ php.net/manual/en/function.htmlspecialchars.php] . Risolto. :)
Ravi Dhoriya ツ

1
Ho riscontrato problemi con questo metodo quando una delle proprietà dell'oggetto era una stringa contenente una singola virgoletta. L'attributo data termina alla prima virgoletta singola rilevata e poiché non è JSON valido, viene interpretato come una stringa. Potrebbe essere possibile codificare la stringa, ma ho scoperto che la soluzione più semplice era usare solo più attributi di dati.
Jon Hulka,

43

Ecco come ha funzionato per me.

Oggetto

var my_object ={"Super Hero":["Iron Man", "Super Man"]};

Impostato

Codifica l'oggetto con stringhe con encodeURIComponent () e imposta come attributo:

var data_str = encodeURIComponent(JSON.stringify(my_object));
$("div#mydiv").attr("data-hero",data-str);

Ottenere

Per ottenere il valore come oggetto, analizza il valore dell'attributo decodificato, con decodeURIComponent () :

var data_str = $("div#mydiv").attr("data-hero");
var my_object = JSON.parse(decodeURIComponent(data_str));

14

Molti problemi con la memorizzazione di dati serializzati possono essere risolti convertendo la stringa serializzata in base64 .

Una stringa base64 può essere accettata praticamente ovunque senza complicazioni.

Date un'occhiata al:

Il WindowOrWorkerGlobalScope.btoa()metodo crea una stringa ASCII codificata in base 64 da un oggetto String in cui ogni carattere nella stringa viene trattato come un byte di dati binari.

La WindowOrWorkerGlobalScope.atob()funzione decodifica una stringa di dati che è stata codificata utilizzando la codifica base-64.

Converti in / da secondo necessità.


Funziona davvero bene per passare oggetti complessi in attributi.
Baacke,

Sfortunatamente, l'avvio presenta un problema Unicode e non è adatto a tutte le lingue.
AhmadJavadiNejad

Per l'uso del browserwindow.btoa
Henry,

1
Questo metodo è IMO piuttosto antiproiettile. Tuttavia, una volta recuperata e decodificata la stringa base64, è stato serializzato JSON. Quindi è necessario utilizzare JSON.parseprima di poter utilizzare il risultato come oggetto.
Henry,

13

Per me funziona così, dato che devo memorizzarlo nel modello ...

// Generate HTML
var gridHtml = '<div data-dataObj=\''+JSON.stringify(dataObj).replace(/'/g, "\\'");+'\'></div>';

// Later
var dataObj = $('div').data('dataObj'); // jQuery automatically unescape it

1
grazie per aver condiviso ... esattamente quello che stavo cercando ... continuavo a ottenere [Object Object] quando cercavo di analizzare la risposta accettata.
GreaterKing

@greaterKing non analizzi il JSON dalla risposta accettata, accedi semplicemente tramite la chiave che è uguale al nome dei dati, quindi se hai ad esempio $('body').data('myData', { h: "hello", w: "world" })_____________________________________________________________________________________________ otterrai il tuo oggetto JSON entro$('body').data().myData
jave.web

Per semplificare, puoi farlo '<div data-dataObj=\''+ JSON.stringify(dataObj) +'\'></div>'. Quelle sono tutte virgolette singole, l'inizio e la fine sono appena sfuggite, quindi sarebbe lo stesso che avere'{"some":"thing"}'
IamFace

1
@IamFace - replace()affronta la possibilità che appaiano singole virgolette nei dati json, il che è del tutto possibile.
Billynoah,

3

Il trucco per me era aggiungere doppie virgolette attorno a chiavi e valori . Se usi una funzione PHP come json_encodeti darà una stringa codificata JSON e un'idea su come codificare correttamente la tua.

jQuery('#elm-id').data('datakey') restituirà un oggetto della stringa, se la stringa è codificata correttamente come json.

Come da documentazione jQuery: ( http://api.jquery.com/jquery.parsejson/ )

Passando in una stringa JSON non valida si genera un'eccezione JavaScript. Ad esempio, le seguenti sono tutte stringhe JSON non valide:

  1. "{test: 1}"( testnon ha doppie virgolette attorno).
  2. "{'test': 1}"( 'test'utilizza virgolette singole anziché doppie).
  3. "'test'"( 'test'utilizza virgolette singole anziché doppie).
  4. ".1"(un numero deve iniziare con una cifra; "0.1"sarebbe valido).
  5. "undefined"( undefinednon può essere rappresentato in una stringa JSON; nulltuttavia, può essere).
  6. "NaN"( NaNnon può essere rappresentato in una stringa JSON; anche la rappresentazione diretta di Infinity è n

2

Combina l'uso di window.btoae window.atobinsieme a JSON.stringifye JSON.parse.

- Funziona con stringhe contenenti virgolette singole

Codifica dei dati:

var encodedObject = window.btoa(JSON.stringify(dataObject));

Decodifica dei dati:

var dataObject = JSON.parse(window.atob(encodedObject));

Ecco un esempio di come i dati vengono costruiti e decodificati in seguito con l'evento click.

Costruisci l'html e codifica i dati:

var encodedObject = window.btoa(JSON.stringify(dataObject));

"<td>" + "<a class='eventClass' href='#' data-topic='" + encodedObject + "'>" 
+ "Edit</a></td>"

Decodifica i dati nel gestore eventi click:

$("#someElementID").on('click', 'eventClass', function(e) {
            event.preventDefault();
            var encodedObject = e.target.attributes["data-topic"].value;
            var dataObject = JSON.parse(window.atob(encodedObject));

            // use the dataObject["keyName"] 
}

0

L'uso della sintassi jquery .data (obj) documentata consente di memorizzare un oggetto sull'elemento DOM. L'ispezione dell'elemento non mostrerà l' data-attributo perché non è stata specificata alcuna chiave per il valore dell'oggetto. Tuttavia, i dati all'interno dell'oggetto possono essere referenziati dalla chiave con .data("foo")o l'intero oggetto può essere restituito con .data().

Quindi supponendo che tu abbia impostato un loop e result[i] = { name: "image_name" }:

$('.delete')[i].data(results[i]); // => <button class="delete">Delete</delete>
$('.delete')[i].data('name'); // => "image_name"
$('.delete')[i].data(); // => { name: "image_name" }

0

Per qualche motivo, la risposta accettata ha funzionato per me solo se utilizzata una volta nella pagina, ma nel mio caso stavo cercando di salvare i dati su molti elementi della pagina e i dati sono stati in qualche modo persi su tutti tranne il primo elemento.

In alternativa, ho finito per scrivere i dati sul dom e analizzarli di nuovo quando necessario. Forse è meno efficiente, ma ha funzionato bene per il mio scopo perché sto davvero prototipando i dati e non sto scrivendo questi per la produzione.

Per salvare i dati che ho usato:

$('#myElement').attr('data-key', JSON.stringify(jsonObject));

Quindi rileggere i dati è lo stesso della risposta accettata, vale a dire:

var getBackMyJSON = $('#myElement').data('key');

In questo modo anche i dati apparivano nel dom se volevo ispezionare l'elemento con il debugger di Chrome.


0

.data()funziona perfettamente per la maggior parte dei casi. L'unica volta che ho avuto un problema è stato quando la stringa JSON stessa aveva una sola virgoletta. Non sono riuscito a trovare un modo semplice per superare questo così ricorso a questo approccio (sto usando Coldfusion come linguaggio server):

    <!DOCTYPE html>
        <html>
            <head>
                <title>
                    Special Chars in Data Attribute
                </title>
                <meta http-equiv="X-UA-Compatible" content="IE=edge">
                <script src="https://code.jquery.com/jquery-1.12.2.min.js"></script>
                <script>
                    $(function(){
                        var o = $("##xxx");
                        /**
                            1. get the data attribute as a string using attr()
                            2. unescape
                            3. convert unescaped string back to object
                            4. set the original data attribute to future calls get it as JSON.
                        */
                        o.data("xxx",jQuery.parseJSON(unescape(o.attr("data-xxx"))));
                        console.log(o.data("xxx")); // this is JSON object.
                    });
                </script>
                <title>
                    Title of the document
                </title>
            </head>
            <body>
                <cfset str = {name:"o'reilly's stuff",code:1}>
<!-- urlencode is a CF function to UTF8 the string, serializeJSON converts object to strin -->
                <div id="xxx" data-xxx='#urlencodedformat(serializejson(str))#'>
                </div>
            </body>
        </html>

0

Per la cronaca, ho trovato il seguente codice funziona. Consente di recuperare l'array dal tag di dati, inserire un nuovo elemento e archiviarlo nel tag di dati nel formato JSON corretto. Lo stesso codice può quindi essere nuovamente utilizzato per aggiungere ulteriori elementi all'array, se lo si desidera. Ho scoperto che $('#my-data-div').attr('data-namesarray', names_string);memorizza correttamente l'array, ma $('#my-data-div').data('namesarray', names_string);non funziona.

<div id="my-data-div" data-namesarray='[]'></div>

var names_array = $('#my-data-div').data('namesarray');
names_array.push("Baz Smith");
var names_string = JSON.stringify(names_array);
$('#my-data-div').attr('data-namesarray', names_string);

0
!DOCTYPE html>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
$("#btn1").click(function()
{
person = new Object();
person.name = "vishal";
person.age =20;
    $("div").data(person);
});
  $("#btn2").click(function()
{
    alert($("div").data("name"));
});

});

</script>
<body>
<button id="btn1">Attach data to div element</button><br>
<button id="btn2">Get data attached to div element</button>
<div></div>
</body>


</html>

Anser:-Attach data to selected elements using an object with name/value pairs.
GET value using object propetis like name,age etc...

0

Questo codice funziona bene per me.

Codifica i dati con btoa

let data_str = btoa(JSON.stringify(jsonData));
$("#target_id").attr('data-json', data_str);

E poi decodificalo con atob

let tourData = $(this).data("json");
tourData = atob(tourData);

Sfortunatamente, l'avvio presenta un problema Unicode e non è adatto a tutte le lingue.
AhmadJavadiNejad
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.