จัดเก็บออบเจ็กต์ JSON ในแอตทริบิวต์ข้อมูลใน HTML jQuery


139

ฉันกำลังจัดเก็บข้อมูลโดยใช้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>

จากนั้นฉันพยายามเข้าถึงคุณสมบัติชื่อดังนี้:

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

undefinedบันทึกบอกฉัน ดูเหมือนว่าฉันสามารถจัดเก็บสตริงง่ายๆในdata-แอตทริบิวต์ได้ แต่ฉันไม่สามารถจัดเก็บออบเจ็กต์ JSON ได้ ...

ฉันได้ลองใช้ไวยากรณ์ของเด็กคนนี้โดยไม่มีโชค:

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

มีความคิดอย่างไรในการจัดเก็บวัตถุจริงในแท็ก HTML โดยใช้data-วิธีการนี้

คำตอบ:


139

แทนที่จะฝังไว้ในข้อความเพียงแค่ใช้ $('#myElement').data('key',jsonObject);

มันจะไม่ถูกเก็บไว้ใน html แต่ถ้าคุณใช้ jquery.data สิ่งที่เป็นนามธรรม

ในการรับ JSON กลับอย่าแยกวิเคราะห์เพียงโทร:

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

หากคุณได้รับ[Object Object]แทนที่จะเป็น JSON โดยตรงเพียงแค่เข้าถึง JSON ของคุณด้วยคีย์ข้อมูล:

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

1
ดังนั้นการใช้ data-approach ทำให้ฉันสามารถจัดเก็บค่าสำหรับปุ่มลบแต่ละปุ่ม (แต่ละปุ่มได้รับวัตถุ json ที่แตกต่างกัน ... ) ฉันมีในตารางโดยใส่แท็ก hmtl เหมือนที่ฉันแสดงไว้ด้านบน สิ่งที่คุณกำลังแนะนำคืออนุญาตให้ฉันเชื่อมโยงแต่ละวัตถุกับปุ่มลบที่เกี่ยวข้องหรือไม่ ฉันจะทำอย่างไรฉันจะใช้ $ ('# myElement') ได้อย่างไร ในทางเดียวกัน? ขออภัยฉันไม่มีประสบการณ์เกี่ยวกับเรื่องนี้ ขอบคุณ
zumzum

ดังนั้นฉันจึงลงเอยด้วยการกำหนดดัชนีให้กับปุ่ม html แต่ละปุ่ม: <td> <button class = 'delete' data-index = '"+ i +"'> Delete </button> </td> และจัดเก็บอาร์เรย์ของวัตถุ JSON ในตัวแปร $ object จากนั้นเมื่อคลิกปุ่มฉันจะดูดัชนีปุ่มโดยทำ: var buttonIndex = $ (this) .data ('index'); จากนั้นฉันจะได้รับวัตถุที่เกี่ยวข้องจากที่บันทึกไว้ก่อนหน้านี้: $ objects [buttonIndex] วิธีนี้ใช้ได้ดีไม่แน่ใจว่าเป็นวิธีที่ถูกต้องหรือไม่ ขอบคุณสำหรับคำติชม!
zumzum

หากช่องมีการเข้ารหัส JSON จาก PHP คุณอาจต้องการทำสิ่งนี้แทน: 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

158

จริงๆแล้วตัวอย่างสุดท้ายของคุณ:

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

ดูเหมือนว่าจะทำงานได้ดี (ดูhttp://jsfiddle.net/GlauberRocha/Q6kKU/ )

สิ่งที่ดีคือสตริงใน data- แอตทริบิวต์จะถูกแปลงเป็นวัตถุ JavaScript โดยอัตโนมัติ ฉันไม่เห็นข้อเสียใด ๆ ในแนวทางนี้ตรงกันข้าม! แอตทริบิวต์เดียวก็เพียงพอที่จะจัดเก็บข้อมูลทั้งชุดพร้อมใช้งานใน JavaScript ผ่านคุณสมบัติออบเจ็กต์

(หมายเหตุ: สำหรับ data- แอตทริบิวต์ที่จะกำหนดให้โดยอัตโนมัติ type Object แทนที่จะเป็น String คุณต้องระมัดระวังในการเขียน JSON ที่ถูกต้องโดยเฉพาะอย่างยิ่งการใส่ชื่อคีย์ในเครื่องหมายคำพูดคู่)


21
$('div').data('foobar').fooถ้ามันจะช่วยให้ทุกคนที่นี่เป็นวิธีการเข้าถึงข้างต้น: api.jquery.com/data
Gary

5
@GlauberRocha จะเกิดอะไรขึ้นถ้าข้อมูลมีเครื่องหมายคำพูดเดียว 'ใช้งานไม่ได้สำหรับฉันในขณะที่ฉันecho json_encode($array)จาก php เนื่องจากจะยุติค่าแอตทริบิวต์ด้วยเครื่องหมายคำพูดเดียว ข้อเสนอแนะใด ๆ ยกเว้นการหลีกเลี่ยงเครื่องหมายคำพูดเดี่ยวด้วยตนเองจากอาร์เรย์
Ravi Dhoriya ツ

1
@ Log1c ツเพียงแค่แนวคิด: ลองเข้ารหัส "เป็น&amp;quot;(เอนทิตี HTML ที่ใช้ Escape คู่) เพื่อให้แสดงผลในแหล่งที่มาของคุณเป็น & quot; แต่บางทีนั่นอาจเป็นสิ่งที่คุณต้องการหลีกเลี่ยงเมื่อคุณพูดว่า "หนีคำพูดเดี่ยวด้วยตนเอง" ...
Nicolas Le Thierry d'Ennequin

3
@GlauberRocha ขอบคุณสำหรับการตอบกลับ ฉันแก้ไขโดยใช้เคล็ดลับเดียวกัน ผมใช้ htmlspecialchars () [ php.net/manual/en/function.htmlspecialchars.php] มันแก้ไขได้ :)
Ravi Dhoriya ツ

1
ฉันประสบปัญหาในการใช้วิธีนี้เมื่อหนึ่งในคุณสมบัติของวัตถุเป็นสตริงที่มีเครื่องหมายคำพูดเดียว แอตทริบิวต์ข้อมูลสิ้นสุดที่อัญประกาศเดี่ยวแรกที่พบและเนื่องจากไม่ใช่ JSON ที่ถูกต้องจึงถูกตีความเป็นสตริง อาจเป็นไปได้ที่จะเข้ารหัสสตริง แต่ฉันพบวิธีแก้ปัญหาที่ง่ายที่สุดคือใช้แอตทริบิวต์ข้อมูลหลายรายการ
Jon Hulka

46

นี่คือวิธีการทำงานสำหรับฉัน

วัตถุ

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

15

จำนวนมากของปัญหาเกี่ยวกับการจัดเก็บข้อมูลต่อเนื่องจะสามารถแก้ไขได้โดยการแปลงสตริงต่อเนื่องเพื่อbase64

คุณสามารถยอมรับสตริง base64 ได้ทุกที่โดยไม่ต้องยุ่งยาก

ดูที่:

WindowOrWorkerGlobalScope.btoa()วิธีการสร้างสตริง ASCII ฐาน 64 เข้ารหัสจาก String วัตถุที่ตัวละครในสตริงแต่ละคนจะได้รับการปฏิบัติเหมือนไบต์ของข้อมูลไบนารี

WindowOrWorkerGlobalScope.atob()ฟังก์ชั่นถอดรหัสสตริงของข้อมูลที่ได้รับการเข้ารหัสโดยใช้ฐาน 64 เข้ารหัส

แปลงเป็น / จากตามต้องการ


สิ่งนี้ใช้ได้ดีกับการส่งผ่าน Objects ที่ซับซ้อนไปยังแอตทริบิวต์
baacke

น่าเสียดายที่การบูตมีปัญหา Unicodeและไม่เหมาะกับทุกภาษา
jvnd

สำหรับการใช้งานเบราว์เซอร์window.btoa
Henry

2
วิธีนี้เป็น IMO ที่กันกระสุนได้ดี อย่างไรก็ตามเมื่อคุณดึงข้อมูลและยกเลิกการเข้ารหัสสตริง base64 ของคุณคุณจะได้รับอนุกรม JSON ดังนั้นคุณต้องมี touse JSON.parseก่อนจึงจะใช้ผลลัพธ์เป็นวัตถุได้
Henry

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

@greaterKing คุณไม่ได้แยกวิเคราะห์ JSON จากคำตอบที่ยอมรับคุณเพียงแค่เข้าถึงผ่านคีย์ซึ่งเหมือนกับชื่อข้อมูลดังนั้นหากคุณมีเช่น$('body').data('myData', { h: "hello", w: "world" })_____________________________________________________________________________________________ คุณจะได้รับวัตถุ JSON ภายใน$('body').data().myData
jave.web

'<div data-dataObj=\''+ JSON.stringify(dataObj) +'\'></div>'เพื่อให้ง่ายที่คุณสามารถทำได้ ทั้งหมดนี้เป็นเครื่องหมายคำพูดเดี่ยวจุดเริ่มต้นและจุดสิ้นสุดเป็นเพียงการหลีกหนีดังนั้นมันจะเหมือนกับการมี'{"some":"thing"}'
IamFace

1
@IamFace - replace()ระบุถึงความเป็นไปได้ของเครื่องหมายคำพูดเดี่ยวที่ปรากฏในข้อมูล json ซึ่งเป็นไปได้ทั้งหมด
billynoah

4

เครื่องใช้window.btoaและwindow.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"] 
}

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 การแทนค่าอินฟินิตี้โดยตรงยังเป็น n

1

มีวิธีที่ดีกว่าในการจัดเก็บ JSON ใน HTML:

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

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

ด้วยเหตุผลบางประการคำตอบที่ได้รับการยอมรับจะใช้ได้ผลกับฉันก็ต่อเมื่อมีการใช้งานเพียงครั้งเดียวบนเพจ แต่ในกรณีของฉันฉันพยายามบันทึกข้อมูลในหลายองค์ประกอบบนหน้าเว็บและข้อมูลก็หายไปในทุกส่วนยกเว้นองค์ประกอบแรก

อีกทางเลือกหนึ่งคือฉันลงเอยด้วยการเขียนข้อมูลไปยังโดมและแยกวิเคราะห์กลับเมื่อจำเป็น บางทีมันอาจจะมีประสิทธิภาพน้อยกว่า แต่ก็ทำงานได้ดีสำหรับจุดประสงค์ของฉันเพราะฉันกำลังสร้างต้นแบบข้อมูลจริงๆและไม่ได้เขียนสิ่งนี้เพื่อการผลิต

ในการบันทึกข้อมูลที่ฉันใช้:

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

ในการอ่านข้อมูลย้อนกลับจะเหมือนกับคำตอบที่ยอมรับกล่าวคือ:

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

การทำเช่นนี้ยังทำให้ข้อมูลปรากฏในโดมหากฉันตรวจสอบองค์ประกอบด้วยตัวแก้ไขข้อบกพร่องของ Chrome


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และไม่เหมาะกับทุกภาษา
jvnd
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.