【问题标题】:Store JSON object in data attribute in HTML jQuery将 JSON 对象存储在 HTML jQuery 的数据属性中
【发布时间】:2012-01-22 11:40:12
【问题描述】:

我使用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 标记中吗?

【问题讨论】:

    标签: jquery html json


    【解决方案1】:

    其实,你的最后一个例子:

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

    似乎运作良好(见http://jsfiddle.net/GlauberRocha/Q6kKU/)。

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

    (注意:要自动赋予数据属性类型 Object 而不是 String,您必须小心编写有效的 JSON,尤其是用双引号将键名括起来)。

    【讨论】:

    • 如果它对任何人有帮助,以下是访问上述内容的方法:$('div').data('foobar').fooapi.jquery.com/data
    • @GlauberRocha,如果数据包含单引号怎么办? ' 对我不起作用,而我来自 php 的 echo json_encode($array)。因为它将通过单引号终止属性值。除了从数组中手动​​转义单引号之外的任何建议。?
    • @Log1c ツ 只是一个想法:尝试将您的 ' 编码为 &amp;amp;quot; (双转义的 HTML 实体),以便它在您的源中呈现为 "。但是,当您说“手动转义单引号”时,也许这就是您要避免的那种事情...
    • @GlauberRocha 感谢您的回复。我用同样的技巧解决了它。我使用了 htmlspecialchars()[php.net/manual/en/function.htmlspecialchars.php] 。它解决了。 :)
    • 当对象属性之一是包含单引号的字符串时,我在使用此方法时遇到了麻烦。 data 属性在遇到的第一个单引号处结束,由于它不是有效的 JSON,它被解释为字符串。可能可以对字符串进行编码,但我发现最简单的解决方案是使用多个数据属性。
    【解决方案2】:

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

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

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

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

    如果您收到的是[Object Object] 而不是直接的 JSON,只需通过数据键访问您的 JSON:

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

    【讨论】:

    • 因此,使用数据方法允许我存储每个删除按钮的值(每个按钮获取不同的 json 对象...)我通过放入 hmtl 标记在表中,就像我展示的那样更多。您的建议是否允许我将每个对象与相应的删除按钮相关联?我将如何做到这一点,我将如何使用 $('#myElement').以同样的方式?抱歉,我没有这方面的经验。谢谢
    • 所以我最终为每个 html 按钮分配了一个索引: , 并将 JSON 对象数组存储在 $objects 变量中。然后,当单击按钮时,我会通过以下方式查看按钮索引: var buttonIndex = $(this).data('index');然后我从以前保存的对象中获取相应的对象,如下所示:$objects[buttonIndex]。这工作正常,不确定它是否是正确的方法。感谢您的反馈!
    • 如果该字段包含来自 PHP 编码的 JSON,您可能只想这样做:htmlspecialchars(json_encode($e))(来自Nicolas answer cmets 的想法)。
    • 在第一个例子中,jsonObject 需要被字符串化吗?编辑:如果它对其他人有帮助,我刚刚在这里找到了该问题的答案:stackoverflow.com/a/42864472"You don't need to stringify objects to store them using jQuery.data()"
    【解决方案3】:

    这对我来说是这样的。

    对象

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

    【讨论】:

    • 非常感谢 JSON.parse(decodeURIComponent(data_str)); :)
    • 在处理和转义引号方面,这似乎比其他选项更强大
    【解决方案4】:

    很多存储序列化数据的问题可以通过将serialized string转换成base64来解决。

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

    看看:

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

    WindowOrWorkerGlobalScope.atob() 函数解码一串数据 已使用 base-64 编码进行编码。

    根据需要转换为/从。

    【讨论】:

    • 这非常适合将复杂的对象传递给属性。
    • 很遗憾,boot 有Unicode problem,并不适合所有语言。
    • 浏览器使用window.btoa
    • 这种方法在 IMO 中是非常防弹的。但是,一旦您检索并取消编码 base64 字符串,您就已经序列化了 JSON。因此,您需要先使用JSON.parse,然后才能将结果用作对象。
    • 这太棒了,我从来不知道这是可能的,非常感谢您的分享!
    【解决方案5】:

    对我来说它就是这样工作的,因为我需要将它存储在模板中...

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

    【讨论】:

    • 感谢分享..正是我要找的...在尝试解析接受的答案时不断得到 [Object Object]。
    • @greaterKing 您不会从接受的答案中解析 JSON,您只需通过与数据名称相同的密钥访问它,因此如果您有例如$('body').data('myData', { h: "hello", w: "world" }) _______________________________________________________________________________ 你会得到你的 JSON 对象 $('body').data().myData
    • 为了简化,您可以使用'&lt;div data-dataObj=\''+ JSON.stringify(dataObj) +'\'&gt;&lt;/div&gt;'。这些都是单引号,开头和结尾只是转义了,所以它与'{"some":"thing"}'相同
    • @IamFace - replace() 解决了 json 数据中出现单引号的可能性,这是完全可能的。
    【解决方案6】:

    结合使用window.btoawindow.atob JSON.stringifyJSON.parse

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

    编码数据:

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

    解码数据:

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

    这是一个稍后如何构造和解码数据的示例 点击事件。

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

    var encodedObject = window.btoa(JSON.stringify(dataObject));
    
    "<td>" + "<a class='eventClass' href='#' data-topic='" + encodedObject + "'>" 
    + "Edit</a></td>"
    

    在点击事件处理程序中解码数据:

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

    【讨论】:

      【解决方案7】:

      在 HTML 中存储 JSON 有更好的方法:

      HTML

      <script id="some-data" type="application/json">{"param_1": "Value 1", "param_2": "Value 2"}</script>
      

      JavaScript

      JSON.parse(document.getElementById('some-data').textContent);
      

      【讨论】:

        【解决方案8】:

        对我来说,诀窍是在键和值周围添加双引号。如果您使用像 json_encode 这样的 PHP 函数,将为您提供 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

        【讨论】:

          【解决方案9】:

          使用documented jquery .data(obj) syntax 允许您在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" }
          

          【讨论】:

            【解决方案10】:

            由于某种原因,只有在页面上使用一次时,接受的答案才对我有用,但在我的情况下,我试图保存页面上许多元素的数据,并且除了第一个元素之外的所有元素都以某种方式丢失了数据.

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

            保存我使用的数据:

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

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

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

            如果我要使用 Chrome 的调试器检查元素,这样做也会使数据出现在 dom 中。

            【讨论】:

              【解决方案11】:

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

              【讨论】:

                【解决方案12】:

                作为记录,我发现以下代码有效。它使您能够从数据标签中检索数组,推送一个新元素,然后以正确的 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);
                

                【讨论】:

                  【解决方案13】:
                  !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...
                  

                  【讨论】:

                    【解决方案14】:

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

                    用 btoa 编码数据

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

                    然后用 atob 解码

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

                    【讨论】:

                    【解决方案15】:

                    我在https://oblik.dev/utilities/config/ 找到了更好的方法 基本上他们所做的是有一个解析器从到类 json 的对象,没有双引号:

                    import { Parser } from 'oblik/utils/config'
                    
                    let parser = new Parser()
                    let result = parser.parse('foo: bar, !baz')
                    console.log(result) // { foo: "bar", baz: false }
                    

                    更多示例:

                    <div ob-foo="text: Hello, num: 42">My Foo component</div>
                    

                    我希望看到这种格式标准化的东西

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2019-10-19
                      • 1970-01-01
                      • 2018-12-25
                      • 2020-11-10
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-11-22
                      相关资源
                      最近更新 更多