Simpan objek JSON dalam atribut data dalam HTML jQuery

134

Saya menyimpan data menggunakan data-pendekatan dalam tag HTML seperti:

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

Saya kemudian mengambil data dalam panggilan balik seperti ini:

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

Itu bekerja dengan baik. Apa yang saya terjebak adalah mencoba untuk menyelamatkan objek, bukan hanya salah satu properti itu. Saya mencoba melakukan ini:

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

Kemudian saya mencoba mengakses properti nama seperti ini:

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

Log memberitahu saya undefined. Jadi sepertinya saya bisa menyimpan string sederhana dalam data-atribut tetapi saya tidak bisa menyimpan objek JSON ...

Saya juga mencoba menggunakan sintaks anak ini tanpa hasil:

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

Adakah ide tentang cara menyimpan objek aktual di tag HTML menggunakan data-pendekatan ini?

zumzum
sumber

Jawaban:

140

alih-alih menanamkannya dalam teks gunakan saja $('#myElement').data('key',jsonObject);

itu tidak akan benar-benar disimpan dalam html, tetapi jika Anda menggunakan jquery.data, semua itu tetap diabstraksikan.

Untuk mendapatkan kembali JSON jangan uraikan , panggil saja:

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

Jika Anda mendapatkan [Object Object]alih-alih JSON langsung, cukup akses JSON Anda dengan kunci data:

var getBackMyJSON = $('#myElement').data('key').key;
nathan gonzalez
sumber
1
Jadi dengan menggunakan pendekatan data memungkinkan saya untuk menyimpan nilai untuk setiap tombol hapus (setiap tombol mendapatkan objek json yang berbeda ...) Saya miliki di tabel dengan memasukkan tag hmtl seperti yang saya tunjukkan di atas. Apakah yang Anda sarankan akan memungkinkan saya untuk mengaitkan setiap objek dengan tombol hapus yang sesuai? Bagaimana saya melakukannya, bagaimana saya menggunakan $ ('# myElement'). di jalan yang sama? Maaf, saya tidak berpengalaman dalam hal ini. Terima kasih
zumzum
Jadi saya akhirnya menetapkan indeks untuk setiap tombol html: <td> <button class = 'delete' data-index = '"+ i +"'> Hapus </button> </td>, dan menyimpan array objek JSON dalam variabel $ objek. Kemudian ketika sebuah tombol diklik saya melihat indeks tombol dengan melakukan: var buttonIndex = $ (this) .data ('index'); dan kemudian saya mendapatkan objek yang sesuai dari yang sebelumnya disimpan seperti ini: $ objects [buttonIndex]. Ini berfungsi dengan baik, tidak yakin apakah itu cara yang benar untuk melakukannya. Terima kasih atas tanggapan Anda!
zumzum
Jika bidang berisi JSON dari pengkodean PHP, Anda mungkin hanya ingin melakukan ini sebagai gantinya: htmlspecialchars(json_encode($e))(ide dari Nicolas menjawab komentar).
CPHPython
dalam contoh pertama, apakah jsonObjectperlu dirubah? sunting: kalau-kalau itu membantu orang lain, saya baru saja menemukan jawaban untuk pertanyaan itu di sini: stackoverflow.com/a/42864472 "You don't need to stringify objects to store them using jQuery.data()"
user1063287
154

Sebenarnya, contoh terakhir Anda:

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

tampaknya berfungsi dengan baik (lihat http://jsfiddle.net/GlauberRocha/Q6kKU/ ).

Yang menyenangkan adalah bahwa string dalam atribut data secara otomatis dikonversi ke objek JavaScript. Sebaliknya, saya tidak melihat kelemahan dalam pendekatan ini! Satu atribut cukup untuk menyimpan seluruh rangkaian data, siap digunakan dalam JavaScript melalui properti objek.

(Catatan: agar atribut data secara otomatis diberi tipe Objek daripada String, Anda harus berhati-hati untuk menulis JSON yang valid, khususnya untuk menyertakan nama kunci dalam tanda kutip ganda).

Nicolas Le Thierry d'Ennequin
sumber
20
Jika membantu siapa pun, berikut adalah cara untuk mengakses diatas: $('div').data('foobar').foo. api.jquery.com/data
Gary
5
@GlauberRocha, Bagaimana jika data berisi kutipan tunggal? 'tidak bekerja untuk saya sementara saya echo json_encode($array)dari php. Karena itu akan mengakhiri nilai atribut dengan kutipan tunggal. Adakah saran kecuali keluar dari kutipan tunggal secara manual dari array.?
Ravi Dhoriya ツ
1
@ Log1c ツ Hanya sebuah ide: coba enkode 'sebagai &amp;quot;(entitas HTML dua-lolos) Anda sehingga dirender di sumber Anda sebagai & quot ;. Tapi mungkin itu jenis hal yang ingin Anda hindari ketika Anda mengatakan "melarikan diri dari kutipan tunggal secara manual" ...
Nicolas Le Thierry d'Ennequin
2
@GlauberRocha terima kasih atas jawabannya. Saya menyelesaikannya menggunakan trik yang sama. Saya menggunakan htmlspecialchars () [ php.net/manual/en/function.htmlspecialchars.php] . Itu terpecahkan. :)
Ravi Dhoriya ツ
1
Saya mengalami kesulitan menggunakan metode ini ketika salah satu properti objek adalah string yang berisi kutipan tunggal. Atribut data berakhir pada kutipan tunggal pertama yang ditemui dan karena itu bukan JSON yang valid, ia akan ditafsirkan sebagai string. Mungkin dimungkinkan untuk menyandikan string, tetapi saya menemukan solusi termudah adalah dengan hanya menggunakan beberapa atribut data.
Jon Hulka
43

Beginilah cara kerjanya untuk saya.

Obyek

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

Set

Encode objek yang dirubah dengan komponen encodeURIC () dan tetapkan sebagai atribut:

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

Dapatkan

Untuk mendapatkan nilai sebagai objek, parsing yang didekodekan, dengan decodeURIComponent () , nilai atribut:

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

Banyak masalah dengan menyimpan data serial dapat diselesaikan dengan mengubah string serial ke base64 .

String base64 dapat diterima di mana saja tanpa repot.

Melihat:

The WindowOrWorkerGlobalScope.btoa()Metode menciptakan basis-64 dikodekan ASCII string dari objek String di mana setiap karakter dalam string diperlakukan sebagai byte data biner.

The WindowOrWorkerGlobalScope.atob()fungsi decode serangkaian data yang telah dikodekan menggunakan basis-64 encoding.

Konversikan ke / dari sesuai kebutuhan.

Dan
sumber
Ini bekerja sangat baik untuk melewatkan Objek kompleks ke atribut.
baacke
Sayangnya, boot memiliki masalah Unicode dan tidak cocok untuk semua bahasa.
AhmadJavadiNejad
Untuk penggunaan browserwindow.btoa
Henry
1
Metode ini cukup tahan banting. Namun, begitu Anda mengambil dan membatalkan penyandian string base64 Anda, Anda telah membuat serial JSON. Jadi, Anda perlu JSON.parsemenggunakan sebelum Anda dapat menggunakan hasilnya sebagai objek.
Henry
13

Bagi saya ini berfungsi seperti itu, karena saya perlu menyimpannya di templat ...

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

// Later
var dataObj = $('div').data('dataObj'); // jQuery automatically unescape it
molokoloco
sumber
1
terima kasih sudah berbagi..tepat apa yang saya cari ... terus mendapatkan [Object Object] ketika mencoba mengurai jawaban yang diterima.
Greater King
@greaterKing Anda tidak mem-parsing JSON dari jawaban yang diterima, Anda cukup mengaksesnya melalui kunci yang sama dengan nama data jadi jika Anda memiliki misalnya $('body').data('myData', { h: "hello", w: "world" })_____________________________________________________________________________________________________ Anda akan mendapatkan objek JSON Anda oleh$('body').data().myData
jave.web
Untuk mempermudah, Anda bisa melakukannya '<div data-dataObj=\''+ JSON.stringify(dataObj) +'\'></div>'. Itu semua adalah kutipan tunggal, awal dan akhir hanya lolos, jadi itu akan sama dengan memiliki'{"some":"thing"}'
IamFace
1
@IamFace - replace()membahas kemungkinan tanda kutip tunggal muncul di data json, yang sepenuhnya mungkin.
billynoah
3

Triknya bagi saya adalah menambahkan tanda kutip ganda di sekitar kunci dan nilai . Jika Anda menggunakan fungsi PHP seperti json_encodeakan memberi Anda string yang dikodekan JSON dan ide bagaimana menyandikan Anda dengan benar.

jQuery('#elm-id').data('datakey') akan mengembalikan objek string, jika string dikodekan dengan benar sebagai json.

Sesuai dokumentasi jQuery: ( http://api.jquery.com/jquery.parsejson/ )

Melewati string JSON yang salah menghasilkan pengecualian JavaScript yang dilemparkan. Misalnya, berikut ini semua string JSON tidak valid:

  1. "{test: 1}"( testtidak memiliki tanda kutip ganda di sekitarnya).
  2. "{'test': 1}"( 'test'menggunakan tanda kutip tunggal, bukan tanda kutip ganda).
  3. "'test'"( 'test'menggunakan tanda kutip tunggal, bukan tanda kutip ganda).
  4. ".1"(angka harus dimulai dengan angka; "0.1"akan valid).
  5. "undefined"( undefinedtidak dapat direpresentasikan dalam string JSON;, nullbagaimanapun, dapat).
  6. "NaN"( NaNtidak dapat direpresentasikan dalam string JSON; representasi langsung dari Infinity juga n
George Donev
sumber
2

Kombinasikan penggunaan window.btoadan window.atobbersama dengan JSON.stringifydan JSON.parse.

- Ini berfungsi untuk string yang berisi tanda kutip tunggal

Pengkodean data:

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

Decoding data:

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

Berikut adalah contoh bagaimana data dibangun dan diterjemahkan kemudian dengan peristiwa klik.

Buat html dan enkode data:

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

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

Decode data dalam event click handler:

$("#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"] 
}
Wayne
sumber
0

Menggunakan sintaks jquery .data (obj) yang didokumentasikan memungkinkan Anda untuk menyimpan objek pada elemen DOM. Memeriksa elemen tidak akan menunjukkan data-atribut karena tidak ada kunci yang ditentukan untuk nilai objek. Namun, data dalam objek dapat dirujuk dengan kunci dengan .data("foo")atau seluruh objek dapat dikembalikan .data().

Jadi dengan asumsi Anda mengatur lingkaran dan 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" }
pengguna2069751
sumber
0

Untuk beberapa alasan, jawaban yang diterima hanya berfungsi bagi saya jika digunakan sekali pada halaman, tetapi dalam kasus saya saya mencoba untuk menyimpan data pada banyak elemen pada halaman dan entah bagaimana data itu hilang pada semua kecuali elemen pertama.

Sebagai alternatif, saya akhirnya menulis data ke dom dan menguraikannya kembali saat diperlukan. Mungkin kurang efisien, tetapi bekerja dengan baik untuk tujuan saya karena saya benar-benar membuat prototipe data dan tidak menulis ini untuk produksi.

Untuk menyimpan data yang saya gunakan:

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

Untuk kemudian membaca kembali data sama dengan jawaban yang diterima, yaitu:

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

Melakukannya dengan cara ini juga membuat data muncul di dom jika saya memeriksa elemen dengan debugger Chrome.

Shane E.
sumber
0

.data()berfungsi dengan baik untuk sebagian besar kasus. Satu-satunya saat saya punya masalah adalah ketika string JSON sendiri memiliki satu kutipan. Saya tidak dapat menemukan cara mudah untuk melewati ini sehingga terpaksa menggunakan pendekatan ini (saya menggunakan Coldfusion sebagai bahasa 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>
Sajjan Sarkar
sumber
0

Sebagai catatan, saya menemukan kode berikut berfungsi. Ini memungkinkan Anda untuk mengambil array dari tag data, mendorong elemen baru, dan menyimpannya kembali di tag data dalam format JSON yang benar. Karena itu kode yang sama dapat digunakan lagi untuk menambahkan elemen lebih lanjut ke array jika diinginkan. Saya menemukan bahwa $('#my-data-div').attr('data-namesarray', names_string);menyimpan array dengan benar, tetapi $('#my-data-div').data('namesarray', names_string);tidak berhasil.

<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);
Bazley
sumber
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...
Vishal Patel
sumber
0

Kode ini berfungsi dengan baik untuk saya.

Enkode data dengan btoa

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

Dan kemudian memecahkannya dengan atob

let tourData = $(this).data("json");
tourData = atob(tourData);
Hp Sharma
sumber
Sayangnya, boot memiliki masalah Unicode dan tidak cocok untuk semua bahasa.
AhmadJavadiNejad