将JSON对象存储在HTML jQuery的data属性中


134

我使用这种data-方法在HTML标记中存储数据,如下所示:

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

然后,我在这样的回调中检索数据:

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

很好 我所坚持的是尝试保存对象,而不仅仅是保存其属性之一。我试图这样做:

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

然后,我尝试像这样访问name属性:

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

日志告诉我undefined。所以看起来我可以在data-属性中存储简单的字符串,但不能存储JSON对象...

我也尝试过使用这种语法的孩子,但运气不好:

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

关于使用该data-方法如何在HTML标签中存储实际对象的任何想法?

Answers:


140

而不是将其嵌入文本中,只需使用 $('#myElement').data('key',jsonObject);

它实际上不会存储在html中,但是如果您使用的是jquery.data,则无论如何都是抽象的。

要获取JSON,请不要解析它,只需调用:

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

如果您获取的[Object Object]不是直接JSON,请通过数据键访问JSON:

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

1
因此,使用数据方法可以让我存储表中的每个删除按钮(每个按钮获取一个不同的json对象...)的值,方法是像上面显示的那样放入hmtl标签。您是在建议我允许将每个对象与相应的删除按钮相关联吗?我将如何使用$('#myElement')。以同样的方式?抱歉,我对此没有经验。谢谢
zumzum 2011年

因此,我最终为每个html按钮分配了一个索引:<td> <button class ='delete'data-index ='“ + i +”'> Delete </ button> </ td>,并存储一个JSON对象数组在$ objects变量中。然后,当单击按钮时,我通过执行以下操作来查看按钮索引:var buttonIndex = $(this).data('index'); 然后从以前这样保存的对象中获取相应的对象:$ objects [buttonIndex]。效果很好,不确定是否是正确的方法。感谢您的反馈意见!
zumzum 2011年

如果该字段包含来自PHP编码的JSON,则您可能只想这样做:(htmlspecialchars(json_encode($e))来自Nicolas的想法回答评论)。
CPHPython

在第一个示例中,是否jsonObject需要进行字符串化?编辑:万一它对其他人有帮助,我只是在这里找到了该问题的答案: stackoverflow.com/a/42864472 "You don't need to stringify objects to store them using jQuery.data()"
user1063287

154

实际上,您的最后一个示例:

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

似乎运行良好(请参阅http://jsfiddle.net/GlauberRocha/Q6kKU/)。

令人高兴的是,data-属性中的字符串会自动转换为JavaScript对象。相反,我认为这种方法没有任何缺点!一个属性足以存储整套数据,可以通过对象属性在JavaScript中使用。

(注意:要为data-attribute属性自动赋予Object类型而不是String类型,您必须小心地编写有效的JSON,尤其是将键名括在双引号中)。


20
如果对任何人有帮助,请按以下步骤访问上述内容:$('div').data('foobar').fooapi.jquery.com/data
加里

5
@GlauberRocha,如果数据包含单引号怎么办?'当我echo json_encode($array)从php 时不为我工作。因为它将用单引号终止属性值。除了从数组中手动​​转义单引号之外,还有其他建议吗?
拉维·多里亚

1
@ Log1cツ一个想法:尝试将您的'编码为&amp;quot;(两次转义的HTML实体),以使其在您的源中呈现为“。但是,当您说“手动转义单引号”时,这可能就是您想要避免的事情……
Nicolas Le Thierry d'Ennequin 2014年

2
@GlauberRocha感谢您的回复。我使用相同的技巧解决了它。我使用了htmlspecialchars()[ php.net/manual/en/function.htmlspecialchars.php]。解决了 :)
拉维·多里亚

1
当对象属性之一是包含单引号的字符串时,使用此方法遇到麻烦。data属性以遇到的第一个单引号结束,并且由于它不是有效的JSON,因此将其解释为字符串。可能可以对字符串进行编码,但是我发现最简单的解决方案是仅使用多个数据属性。
乔恩·赫尔卡

43

这就是它为我工作的方式。

目的

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

使用encodeURIComponent()对字符串化的对象进行编码,并将其设置为属性:

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

得到

要将值作为对象获取,请使用属性值decodeURIComponent()解析解码后的内容:

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

14

序列化的字符串转换为base64可以解决许多存储序列化数据的问题。

base64字符串几乎可以在任何地方接受而不必大惊小怪。

看一眼:

WindowOrWorkerGlobalScope.btoa()方法从String对象创建一个base-64编码的ASCII字符串,该字符串对象中的每个字符都被视为二进制数据的字节。

WindowOrWorkerGlobalScope.atob()函数对已使用base-64编码进行编码的数据字符串进行解码

根据需要转换。


这对于将复杂的对象传递到属性中非常有效。
baacke

不幸的是,启动存在Unicode问题,并不适合所有语言。
AhmadJavadiNejad

供浏览器使用window.btoa
亨利

1
这种方法是非常防弹的IMO。但是,一旦检索并取消对base64字符串进行编码,就可以序列化JSON。因此,您需要JSON.parse先使用,然后才能将结果用作对象。
亨利

13

对我来说,它就像那样工作,因为我需要将其存储在模板中

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

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

1
感谢您的分享。正是我所寻找的...试图解析接受的答案时,得到了[Object Object]。
国王

@greaterKing你不从接受的答案解析JSON,你只要通过这相同的数据名称的键访问它,所以如果你有如$('body').data('myData', { h: "hello", w: "world" })_____________________________________________________________________________________________则可以通过将让你的JSON对象$('body').data().myData
jave.web

为简化起见,您可以这样做'<div data-dataObj=\''+ JSON.stringify(dataObj) +'\'></div>'。这些都是单引号,只是开始和结尾都被'{"some":"thing"}'
忽略

1
@IamFace- replace()解决了在json数据中出现单引号的可能性,这是完全可能的。
Billynoah

3

对我来说,技巧是在键和值周围添加双引号。如果您使用类似PHP的函数json_encode将为您提供JSON编码的字符串以及如何正确编码的想法。

jQuery('#elm-id').data('datakey') 如果字符串正确编码为json,则将返回字符串的对象。

根据jQuery文档:(http://api.jquery.com/jquery.parsejson/

传递格式错误的JSON字符串会导致引发JavaScript异常。例如,以下都是无效的JSON字符串:

  1. "{test: 1}"test它周围没有双引号)。
  2. "{'test': 1}"'test'正在使用单引号而不是双引号)。
  3. "'test'"'test'正在使用单引号而不是双引号)。
  4. ".1"(数字必须以数字开头;"0.1"将是有效的)。
  5. "undefined"undefined不能用JSON字符串表示;null但是可以)。
  6. "NaN"NaN不能用JSON字符串表示; Infinity的直接表示也为n

2

结合使用的window.btoa,并window.atob一起 JSON.stringifyJSON.parse

-这适用于包含单引号的字符串

编码数据:

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

解码数据:

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

这是一个有关如何在稍后使用click事件构造和解码数据的示例。

构造html并对数据进行编码:

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

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

在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

使用记录的jquery .data(obj)语法,可以将对象存储在DOM元素上。检查元素将不会显示data-属性,因为没有为对象的值指定键。但是,可以使用键来引用对象中的数据,也.data("foo")可以使用来返回整个对象。.data()

因此,假设您设置了一个循环并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

由于某种原因,仅当在页面上使用一次时,可接受的答案才对我有用,但就我而言,我试图将数据保存在页面上的许多元素上,并且除第一个元素之外,所有这些数据都丢失了。

作为替代方案,我最终将数据写到dom并在需要时将其解析回。也许它的效率较低,但是可以很好地达到我的目的,因为我实际上是在对数据进行原型设计,而不是将其编写用于生产。

保存我使用的数据:

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

然后读回数据与接受的答案相同,即:

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

如果我要使用Chrome的调试器检查元素,以这种方式进行操作也会使数据显示在dom中。


0

.data()在大多数情况下都能正常工作。我唯一的问题是JSON字符串本身有一个单引号。我找不到任何简单的方法来克服这个问题,所以诉诸这种方法(我使用Coldfusion作为服务器语言):

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

作为记录,我发现以下代码有效。它使您能够从数据标签中检索数组,将新元素压入,然后以正确的JSON格式将其存储回数据标签中。因此,如果需要,可以再次使用相同的代码将其他元素添加到数组中。我发现$('#my-data-div').attr('data-namesarray', names_string);正确存储了数组,但是$('#my-data-div').data('namesarray', names_string);不起作用。

<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

这段代码对我来说很好用。

使用btoa编码数据

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

然后用atob解码

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

不幸的是,启动存在Unicode问题,并不适合所有语言。
AhmadJavadiNejad
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.