Хранить объект JSON в атрибуте данных в HTML jQuery


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>

Любая идея о том, как сохранить фактический объект в теге 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
Таким образом, использование подхода с использованием данных позволяет мне сохранять значение для каждой кнопки удаления (каждая кнопка получает свой объект json ...), который у меня есть в таблице, добавив тег hmtl, как показано выше. То, что вы предлагаете, позволит мне связать каждый объект с соответствующей кнопкой удаления? Как бы я это сделал, как бы использовать $ ('# myElement'). таким же образом? Извините, я не разбираюсь в этом. Спасибо
zumzum

В итоге я назначил каждой кнопке html индекс: <td> <button class = 'delete' data-index = '"+ i +"'> Delete </button> </td> и сохранил массив объектов JSON. в переменной $ objects. Затем, когда нажимается кнопка, я смотрю на индекс кнопки, выполняя: var buttonIndex = $ (this) .data ('index'); а затем я получаю соответствующий объект из ранее сохраненного следующим образом: $ objects [buttonIndex]. Это работает нормально, но не уверен, что это правильный способ. Спасибо за ваш отзыв!
zumzum

Если поле содержит JSON из кодировки PHP, вы можете просто сделать это вместо этого: htmlspecialchars(json_encode($e))(идея из комментариев Николаса ).
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- автоматически получали тип Object, а не String, вы должны быть осторожны при написании действительного JSON, в частности, чтобы заключить имена ключей в двойные кавычки).


20
Если это помогает любому, вот как получить доступ к выше: $('div').data('foobar').foo. api.jquery.com/data
Гэри,

5
@GlauberRocha, а если данные содержат одинарную кавычку? 'у меня не работает, пока я echo json_encode($array)с php. Так как он завершит значение атрибута одинарной кавычкой. Любое предложение, кроме экранирования одинарной кавычки вручную из массива.?
Рави Дхория ツ

1
@ Log1c ツ Просто идея: попробуйте закодировать 'as &amp;quot;(HTML-объект с двойным экранированием), чтобы он отображался в исходном коде как & quot ;. Но, может быть, именно этого вы хотите избежать, когда говорите «экранирование одинарной кавычки вручную» ...
Николя Ле Тьерри д'Эннекен

2
@GlauberRocha спасибо за ответ. Я решил это с помощью того же трюка. Я использовал htmlspecialchars () [ php.net/manual/en/function.htmlspecialchars.php] . Это решено. :)
Ravi Dhoriya ツ

1
У меня возникли проблемы при использовании этого метода, когда одно из свойств объекта было строкой, содержащей одинарные кавычки. Атрибут данных заканчивается первой встреченной одинарной кавычкой, и, поскольку это недопустимый 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()Метод создает базовую 64 кодированный ASCII строку из строкового объекта , в котором каждый символ в строке трактуются как байты двоичных данных.

WindowOrWorkerGlobalScope.atob()Функция декодирует строку данных , которые были закодированы с использованием базовых 64 кодирования.

Конвертировать в / из по мере необходимости.


Это действительно хорошо работает для передачи сложных объектов в атрибуты.
baacke

К сожалению, загрузка имеет проблемы с Unicode и подходит не для всех языков.
AhmadJavadiNejad

Для использования в браузереwindow.btoa
Генри

1
Этот метод довольно пуленепробиваемый, ИМО. Однако как только вы извлечете и раскодируете строку 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], пытаясь разобрать принятый ответ.
greatKing

@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

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.stringifyи JSON.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>"

Расшифруйте данные в обработчике события клика:

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

По какой-то причине принятый ответ работал у меня, только если он использовался один раз на странице, но в моем случае я пытался сохранить данные для многих элементов на странице, и данные каким-то образом были потеряны для всех, кроме первого элемента.

В качестве альтернативы я закончил тем, что записал данные в дом и проанализировал их, когда это было необходимо. Возможно, он менее эффективен, но хорошо сработал для моей цели, потому что я действительно создаю прототипы данных, а не пишу их для производства.

Для сохранения данных я использовал:

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

Чтобы затем прочитать данные обратно, совпадает с принятым ответом, а именно:

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

Это также привело к появлению данных в dom, если бы я проверял элемент с помощью отладчика 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 и подходит не для всех языков.
AhmadJavadiNejad
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.