Lưu trữ đối tượng JSON trong thuộc tính dữ liệu trong HTML jQuery


134

Tôi đang lưu trữ dữ liệu bằng cách sử dụng cách data-tiếp cận trong thẻ HTML như vậy:

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

Sau đó tôi đang lấy dữ liệu trong một cuộc gọi lại như thế này:

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

Điều đó làm việc tốt. Những gì tôi bị mắc kẹt là cố gắng lưu đối tượng thay vì chỉ một trong các thuộc tính của nó. Tôi đã cố gắng để làm điều này:

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

Sau đó, tôi đã cố gắng truy cập vào tài sản tên như thế này:

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

Nhật ký cho tôi biết undefined. Vì vậy, có vẻ như tôi có thể lưu trữ các chuỗi đơn giản trong các data-thuộc tính nhưng tôi không thể lưu trữ các đối tượng JSON ...

Tôi cũng đã thử sử dụng cú pháp của đứa trẻ này nhưng không có may mắn:

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

Bạn có ý tưởng nào về cách lưu trữ một đối tượng thực tế trong thẻ HTML bằng cách sử dụng data-phương pháp này không?

Câu trả lời:


140

thay vì nhúng nó vào văn bản chỉ cần sử dụng $('#myElement').data('key',jsonObject);

nó thực sự sẽ không được lưu trữ trong html, nhưng nếu bạn đang sử dụng jquery.data, thì tất cả những thứ đó đều được trừu tượng hóa.

Để lấy lại JSON, đừng phân tích cú pháp , chỉ cần gọi:

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

Nếu bạn nhận được [Object Object]thay vì JSON trực tiếp, chỉ cần truy cập JSON của bạn bằng khóa dữ liệu:

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

1
Vì vậy, sử dụng phương pháp tiếp cận dữ liệu cho phép tôi lưu trữ giá trị cho mỗi nút xóa (mỗi nút có một đối tượng json khác nhau ...) Tôi có trong bảng bằng cách đặt thẻ hmtl như tôi đã trình bày ở trên. Là những gì bạn đang đề xuất sẽ cho phép tôi liên kết từng đối tượng với nút xóa tương ứng? Tôi sẽ làm điều đó như thế nào, tôi sẽ sử dụng $ ('# myEuity') như thế nào. theo cùng một cách? Xin lỗi, tôi không có kinh nghiệm về điều này. Cảm ơn
zumzum

Vì vậy, cuối cùng tôi đã gán một chỉ mục cho mỗi nút html: <td> <button class = 'xóa' data-index = '"+ i +"'> Xóa </ button> </ td> và lưu trữ một mảng các đối tượng JSON trong một biến $ object. Sau đó, khi một nút được nhấp, tôi nhìn vào chỉ mục nút bằng cách thực hiện: var buttonIndex = $ (this) .data ('index'); và sau đó tôi nhận được đối tượng tương ứng từ lưu trước đó như sau: $ object [buttonIndex]. Điều này hoạt động tốt, không chắc chắn nếu đó là cách làm chính xác. Cảm ơn phản hồi của bạn!
zumzum

Nếu trường chứa JSON từ mã hóa PHP, bạn có thể chỉ muốn làm điều này thay vào đó: htmlspecialchars(json_encode($e))(ý tưởng từ Nicolas trả lời bình luận).
CPHPython

trong ví dụ đầu tiên, có jsonObjectcần phải được xâu chuỗi không? chỉnh sửa: trong trường hợp nó giúp được ai khác, tôi chỉ tìm thấy câu trả lời cho câu hỏi đó tại đây: stackoverflow.com/a/42864472 "You don't need to stringify objects to store them using jQuery.data()"
user1063287

154

Trên thực tế, ví dụ cuối cùng của bạn:

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

dường như đang hoạt động tốt (xem http://jsfiddle.net/GlauberRocha/Q6kKU/ ).

Điều thú vị là chuỗi trong thuộc tính data- được tự động chuyển đổi thành đối tượng JavaScript. Tôi không thấy bất kỳ nhược điểm nào trong cách tiếp cận này, ngược lại! Một thuộc tính là đủ để lưu trữ toàn bộ tập hợp dữ liệu, sẵn sàng sử dụng trong JavaScript thông qua các thuộc tính đối tượng.

(Lưu ý: để các thuộc tính dữ liệu được tự động đưa ra loại Đối tượng thay vì Chuỗi, bạn phải cẩn thận để viết JSON hợp lệ, đặc biệt là đặt các tên khóa trong dấu ngoặc kép).


20
Nếu nó giúp được bất cứ ai, đây là cách truy cập ở trên : $('div').data('foobar').foo. api.jquery.com/data
Gary

5
@GlauberRocha, Nếu dữ liệu chứa một trích dẫn thì sao? 'không làm việc cho tôi trong khi tôi echo json_encode($array)từ php. Vì nó sẽ chấm dứt giá trị thuộc tính bằng trích dẫn duy nhất. Bất kỳ đề xuất nào ngoại trừ thoát một trích dẫn thủ công từ mảng.?
Ravi Dhoriya

1
@ Log1c ツ Chỉ là một ý tưởng: hãy thử mã hóa 'dưới dạng &amp;quot;(thực thể HTML thoát kép) để nó được hiển thị trong nguồn của bạn dưới dạng & quot;. Nhưng có lẽ đó là điều bạn muốn tránh khi bạn nói "thoát một trích dẫn bằng tay" ...
Nicolas Le Thierry d'Enơcơ

2
@GlauberRocha cảm ơn bạn đã trả lời. Tôi đã giải quyết nó bằng cách sử dụng thủ thuật tương tự. Tôi đã sử dụng htmlspecialchars () [ php.net/manual/en/feft.htmlspecialchars.php] . Nó đã giải quyết. :)
Ravi Dhoriya

1
Tôi gặp rắc rối khi sử dụng phương thức này khi một trong các thuộc tính đối tượng là một chuỗi chứa một trích dẫn. Thuộc tính dữ liệu kết thúc ở trích dẫn đơn đầu tiên gặp phải và vì nó không hợp lệ JSON, nên nó được hiểu là một chuỗi. Có thể mã hóa chuỗi, nhưng tôi thấy giải pháp đơn giản nhất là chỉ sử dụng nhiều thuộc tính dữ liệu.
Jon Hulka

43

Đây là cách nó làm việc cho tôi.

Vật

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

Bộ

Mã hóa đối tượng được xâu chuỗi bằng encodeURIComponent () và đặt làm thuộc tính:

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

Được

Để nhận giá trị dưới dạng một đối tượng, phân tích cú pháp được giải mã, với decodeURIComponent () , giá trị thuộc tính:

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

14

Rất nhiều vấn đề với việc lưu trữ dữ liệu tuần tự hóa có thể được giải quyết bằng cách chuyển đổi chuỗi được xê-ri hóa thành cơ sở64 .

Một chuỗi base64 có thể được chấp nhận ở bất cứ đâu mà không phiền phức.

Hãy xem:

Các WindowOrWorkerGlobalScope.btoa()phương pháp tạo ra một cơ sở-64 chuỗi ASCII mã hóa từ một đối tượng String trong đó mỗi nhân vật trong chuỗi được xử lý như một byte dữ liệu nhị phân.

Các WindowOrWorkerGlobalScope.atob()chức năng giải mã một chuỗi các dữ liệu đã được mã hóa sử dụng cơ sở-64 mã hóa.

Chuyển đổi sang / từ khi cần thiết.


Điều này hoạt động thực sự tốt để chuyển các đối tượng phức tạp vào các thuộc tính.
baacke

Thật không may, boot có vấn đề Unicode và không phù hợp với tất cả các ngôn ngữ.
AhmadJavadiNejad

Để sử dụng trình duyệtwindow.btoa
Henry

1
Phương pháp này là IMO khá chống đạn. Tuy nhiên, khi bạn truy xuất và hủy mã hóa chuỗi base64, bạn đã tuần tự hóa JSON. Vì vậy, bạn cần touse JSON.parsetrước khi bạn có thể sử dụng kết quả như một đối tượng.
Henry

13

Đối với tôi nó hoạt động như vậy, vì tôi cần lưu trữ nó trong mẫu ...

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

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

1
cảm ơn vì đã chia sẻ..chính xác những gì tôi đang tìm kiếm ... tiếp tục nhận được [Đối tượng] khi cố gắng phân tích câu trả lời được chấp nhận.
lớn hơn

@greaterKing bạn không phân tích cú pháp JSON từ câu trả lời được chấp nhận, bạn chỉ cần truy cập vào nó thông qua phím mà là giống như tên dữ liệu vì vậy nếu bạn có ví dụ $('body').data('myData', { h: "hello", w: "world" })_____________________________________________________________________________________________ bạn sẽ nhận được đối tượng JSON của bạn bằng cách$('body').data().myData
jave.web

Để đơn giản hóa, bạn có thể làm '<div data-dataObj=\''+ JSON.stringify(dataObj) +'\'></div>'. Đó là tất cả các trích dẫn duy nhất, bắt đầu và kết thúc chỉ được thoát, vì vậy nó sẽ giống như có'{"some":"thing"}'
IamFace

1
@IamFace - replace()giải quyết khả năng trích dẫn đơn xuất hiện trong dữ liệu json, điều này là hoàn toàn có thể.
billynoah

3

Mẹo cho tôi là thêm dấu ngoặc kép quanh các khóa và giá trị . Nếu bạn sử dụng một hàm PHP như thế json_encodesẽ cung cấp cho bạn một chuỗi được mã hóa JSON và một ý tưởng về cách mã hóa chính xác của bạn.

jQuery('#elm-id').data('datakey') sẽ trả về một đối tượng của chuỗi, nếu chuỗi được mã hóa chính xác là json.

Theo tài liệu jQuery: ( http://api.jquery.com/jquery.parsejson/ )

Truyền vào chuỗi JSON không đúng định dạng dẫn đến ngoại lệ JavaScript bị ném. Ví dụ: sau đây là tất cả các chuỗi JSON không hợp lệ:

  1. "{test: 1}"( testkhông có dấu ngoặc kép xung quanh nó).
  2. "{'test': 1}"( 'test'đang sử dụng dấu ngoặc đơn thay vì dấu ngoặc kép).
  3. "'test'"( 'test'đang sử dụng dấu ngoặc đơn thay vì dấu ngoặc kép).
  4. ".1"(một số phải bắt đầu bằng một chữ số; "0.1"sẽ hợp lệ).
  5. "undefined"( undefinedkhông thể được biểu diễn trong một chuỗi JSON; nulltuy nhiên, có thể).
  6. "NaN"( NaNkhông thể được biểu diễn trong chuỗi JSON; biểu diễn trực tiếp của Infinity cũng là n

2

Kết hợp việc sử dụng window.btoawindow.atobcùng với JSON.stringifyJSON.parse.

- Điều này hoạt động cho các chuỗi chứa dấu ngoặc đơn

Mã hóa dữ liệu:

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

Giải mã dữ liệu:

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

Dưới đây là một ví dụ về cách dữ liệu được xây dựng và giải mã sau đó với sự kiện nhấp chuột.

Xây dựng html và mã hóa dữ liệu:

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

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

Giải mã dữ liệu trong trình xử lý sự kiện nhấp:

$("#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

Sử dụng cú pháp jquery .data (obj) được ghi lại cho phép bạn lưu trữ một đối tượng trên phần tử DOM. Kiểm tra phần tử sẽ không hiển thị data-thuộc tính vì không có khóa được chỉ định cho giá trị của đối tượng. Tuy nhiên, dữ liệu trong đối tượng có thể được tham chiếu bằng khóa với .data("foo")hoặc toàn bộ đối tượng có thể được trả về .data().

Vì vậy, giả sử bạn thiết lập một vòng lặp và 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

Vì một số lý do, câu trả lời được chấp nhận chỉ có tác dụng với tôi nếu được sử dụng một lần trên trang, nhưng trong trường hợp của tôi, tôi đã cố lưu dữ liệu trên nhiều yếu tố trên trang và dữ liệu bị mất bằng cách nào đó ngoại trừ yếu tố đầu tiên.

Thay vào đó, tôi đã kết thúc việc viết dữ liệu ra dom và phân tích lại khi cần. Có lẽ nó kém hiệu quả hơn, nhưng hoạt động tốt cho mục đích của tôi bởi vì tôi thực sự tạo mẫu dữ liệu và không viết dữ liệu này cho sản xuất.

Để lưu dữ liệu tôi đã sử dụng:

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

Để sau đó đọc dữ liệu trở lại giống như câu trả lời được chấp nhận, cụ thể là:

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

Làm theo cách này cũng làm cho dữ liệu xuất hiện trong dom nếu tôi kiểm tra phần tử bằng trình gỡ lỗi của Chrome.


0

.data()hoạt động hoàn hảo cho hầu hết các trường hợp. Lần duy nhất tôi gặp vấn đề là khi chính chuỗi JSON có một trích dẫn. Tôi không thể tìm thấy bất kỳ cách dễ dàng nào để vượt qua điều này vì vậy đã sử dụng phương pháp này (đang sử dụng Coldfusion làm ngôn ngữ máy chủ):

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

Đối với hồ sơ, tôi tìm thấy các mã sau hoạt động. Nó cho phép bạn truy xuất mảng từ thẻ dữ liệu, đẩy một phần tử mới và lưu nó trở lại trong thẻ dữ liệu theo định dạng JSON chính xác. Do đó, cùng một mã có thể được sử dụng để thêm các phần tử nữa vào mảng nếu muốn. Tôi thấy rằng $('#my-data-div').attr('data-namesarray', names_string);lưu trữ chính xác các mảng, nhưng $('#my-data-div').data('namesarray', names_string);không hoạt động.

<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

Mã này đang làm việc tốt cho tôi.

Mã hóa dữ liệu với btoa

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

Và sau đó giải mã nó với atob

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

Thật không may, boot có vấn đề Unicode và không phù hợp với tất cả các ngôn ngữ.
AhmadJavadiNejad
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.