Как хранить произвольные данные для некоторых тегов HTML

338

Я делаю страницу, которая имеет некоторое взаимодействие, предоставляемое JavaScript. Просто в качестве примера: ссылки, которые отправляют запрос AJAX для получения содержимого статей, а затем отображают эти данные в div. Очевидно, что в этом примере мне нужна каждая ссылка для хранения дополнительной информации: идентификатора статьи. То, как я справлялся с этим, заключалось в том, чтобы поместить эту информацию в ссылку href:

<a class="article" href="#5">

Затем я использую jQuery, чтобы найти элементы a.article и присоединить соответствующий обработчик событий. (не зацикливайтесь на юзабилити или семантике, это всего лишь пример)

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

Сразу очевидным ответом было использование атрибутов элемента. Я имею в виду, для этого они и нужны, верно? (Вид).

<a articleid="5" href="link/for/non-js-users.html">

В своем недавнем вопросе я спросил, был ли этот метод действительным, и оказалось, что если не считать моего собственного DTD (я не знаю), то нет, он недействителен или надежен. Обычным ответом было поместить данные в classатрибут (хотя это могло быть из-за моего неудачно выбранного примера), но для меня это пахнет еще больше. Да, это технически правильно, но это не очень хорошее решение.

Другой метод, который я использовал в прошлом, состоял в том, чтобы фактически сгенерировать JS и вставить его на страницу в <script>теге, создав структуру, которая будет ассоциироваться с объектом.

var myData = {
    link0 : {
        articleId : 5,
        target : '#showMessage'
        // etc...
    },
    link1 : {
        articleId : 13
    }
};

<a href="..." id="link0">

Но это может быть реальная боль в поддержании и обычно просто очень грязно.

Итак, чтобы перейти к вопросу, как хранить произвольные фрагменты информации для тегов HTML ?

nickf
источник
2
Похожий вопрос: stackoverflow.com/questions/209428/…
Тамас Чинеге

Ответы:

361

Какую версию HTML вы используете?

В HTML 5 полностью допустимо иметь пользовательские атрибуты с префиксом data- , например

<div data-internalid="1337"></div>

В XHTML это не совсем верно. Если вы находитесь в режиме XHTML 1.1, браузер, вероятно, будет жаловаться на это, но в режиме 1.0 большинство браузеров просто игнорируют его.

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

Тамас Чинеге
источник
5
@Tchalvak: Да, но этот бит будет работать в большинстве браузеров, тем не менее.
Тамас Чинеге
2
Другие утверждают, что нет никакой причины ждать поддержки, так как единственная проблема, которую это вызывает, - неспособность проверить, и это не нарушает IE. См. Ответ TJ Crowler здесь: stackoverflow.com/questions/1923278/…
Крис,
42
Если вы используете атрибуты data-xxx и хотите получить их, вы можете просто использовать «domElement.getAttribute ('data-what')" без какой-либо сторонней среды.
Охад Кравчик
5
Имейте в виду производительность! jsperf.com/jquery-data-vs-jqueryselection-data/19
FilmJ
19
Напоминание: для получения данных 1337 с помощью jquery обязательно удалите «данные» из имени переменной. Например, используйте: $(this).data('internalid'); вместо:$(this).data('data-internalid');
Гедеон Розенталь
134

Если вы уже используете jQuery, вам следует использовать метод «data», который является рекомендуемым методом для хранения произвольных данных в элементе dom с помощью jQuery.

Чтобы что-то хранить:

$('#myElId').data('nameYourData', { foo: 'bar' });

Чтобы получить данные:

var myData = $('#myElId').data('nameYourData');

Это все, что нужно сделать, но посмотрите документацию jQuery для получения дополнительной информации / примеров.

Prestaul
источник
20

Просто я бы не стал использовать это, но это работает (убедитесь, что ваш JSON действителен, потому что eval () опасен).

<a class="article" href="link/for/non-js-users.html">
    <span style="display: none;">{"id": 1, "title":"Something"}</span>
    Text of Link
</a>

// javascript
var article = document.getElementsByClassName("article")[0];
var data = eval(article.childNodes[0].innerHTML);
Лука Маттеис
источник
1
+1 для латерального мышления. Я согласен, что я, вероятно, не хотел бы использовать этот метод, но это неопределенно жизнеспособный вариант!
Ник
9
@nickf Вы можете избавиться от evalиспользования JSON.parseвместо jsfiddle.net/EAXmY
Саймон
12

Произвольные атрибуты недопустимы, но они абсолютно надежны в современных браузерах. Если вы устанавливаете свойства через javascript, вам не нужно беспокоиться о проверке.

Альтернативой является установка атрибутов в JavaScript. JQuery имеет хороший метод для этой цели, или вы можете использовать свой собственный.

Эран Гальперин
источник
3
Почему бы не использовать data-атрибуты вместо этого?
Flimm
10

Хак, который будет работать практически со всеми возможными браузерами, заключается в использовании открытых классов, таких как: <a class='data\_articleid\_5' href="link/for/non-js-users.html>;

Это не так уж и элегантно для пуристов, но универсально поддерживается, соответствует стандартам и очень легко манипулируется. Это действительно кажется наилучшим из возможных методов. Если вы serialize, изменять , копировать ваши тег, или делать почти все остальное, dataбудет оставаться прилагается, скопирован и т.д.

Единственная проблема заключается в том, что вы не можете хранить несериализуемые объекты таким образом , и могут быть ограничения, если вы поместите туда что-то действительно огромное.

Второй способ - использовать поддельные атрибуты, такие как:<a articleid='5' href="link/for/non-js-users.html">

Это более элегантно, но нарушает стандарт, и я не уверен на 100% о поддержке. Многие браузеры поддерживают его полностью, я думаю, что IE6 поддерживает JSдоступ к нему, но неCSS selectors (что на самом деле не имеет значения), возможно, некоторые браузеры будут полностью сбиты с толку, вам нужно проверить это.

Делать такие забавные вещи, как сериализация и десериализация, было бы еще опаснее.

Использование idsчистого JSхэша в основном работает, за исключением случаев, когда вы пытаетесь скопировать ваши теги. Если у вас есть tag <a href="..." id="link0">, скопируйте его стандартными JSметодами, а затем попытайтесь изменить dataприкрепленный только к одной копии, другая копия будет изменена.

Это не проблема, если вы не копируете tags или используете данные только для чтения . Если вы скопируете tags и они изменятся, вам нужно будет обработать это вручную.

выделывать кожу без дубления
источник
хранение вальса на уроке
круто
10

Используя jquery,

хранить: $('#element_id').data('extra_tag', 'extra_info');

извлечь: $('#element_id').data('extra_tag');

user2458978
источник
6

Я знаю, что вы в настоящее время используете jQuery, но что, если вы определили встроенный обработчик onclick. Тогда вы могли бы сделать:

 <a href='/link/for/non-js-users.htm' onclick='loadContent(5);return false;'>
     Article 5</a>
tvanfosson
источник
6

Вы можете использовать скрытые теги ввода. Я не получаю ошибок проверки на w3.org с этим:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang='en' xml:lang='en' xmlns='http://www.w3.org/1999/xhtml'>
  <head>
    <meta content="text/html;charset=UTF-8" http-equiv="content-type" />
    <title>Hello</title>
  </head>
  <body>
    <div>
      <a class="article" href="link/for/non-js-users.html">
        <input style="display: none" name="articleid" type="hidden" value="5" />
      </a>
    </div>
  </body>
</html>

С jQuery вы получите идентификатор статьи с чем-то вроде (не проверено):

$('.article input[name=articleid]').val();

Но я бы порекомендовал HTML5, если это вариант.

phylae
источник
13
Я на самом деле не думаю, что style="display: none"это необходимо для скрытых полей ввода.
Фила
1
Хороший подход, полностью действительный во всех версиях HTML. Я категорически не одобряю кодирование, предполагая, что у всех ваших пользователей будет полностью браузер с жалобами HTML5. И отображение: ничего не нужно для скрытых полей.
andreszs
Очень хорошо. Это лучшее решение, которое я нашел для XHTML, где атрибуты данных недопустимы. IMO не использует теги / атрибуты непреднамеренным образом, почти не имеет «запаха». И, как говорили другие: display: на самом деле ничего не нужно.
Арахман
4

Почему бы не использовать значимые данные, которые уже есть, вместо добавления произвольных данных?

т.е. использовать <a href="https://stackoverflow.com/articles/5/page-title" class="article-link">, а затем вы можете программно получить все ссылки на статьи на странице (через имя класса) и идентификатор статьи (сопоставляя регулярное выражение /articles\/(\d+)/с this.href).


источник
2
Проблема в том, что он не очень расширяемый
ehdv
4

Как пользователь jQuery я бы использовал плагин Metadata . HTML-код выглядит чистым, он проверяет правильность, и вы можете встраивать все, что можно описать с помощью нотации JSON.

Робин Смидсред
источник
3

Таким образом, для этого должно быть четыре варианта:

  1. Поместите данные в атрибут id.
  2. Поместите данные в произвольный атрибут
  3. Поместите данные в атрибут класса
  4. Поместите ваши данные в другой тег

http://www.shanison.com/?p=321

Shanison
источник
@ h4ck3rm1k3 ... не в атрибуте id, потому что он должен быть уникальным для документа, и его необходимо повторить, если необходимо, на боковой панели или что-то в этом роде ... Это старый вопрос, но он все еще действителен
miguel-svq
2

Я защищаю использование атрибута "rel". XHTML проверяет, сам атрибут редко используется, и данные эффективно извлекаются.

demonkoryu
источник
не могу сделать этот идентификатор сломать атрибут nofollow на ссылки
Картер Коул
2

Это хороший совет. Благодаря @Prestaul

Если вы уже используете jQuery, вам следует использовать метод «data», который является рекомендуемым методом для хранения произвольных данных в элементе dom с помощью jQuery.

Совершенно верно, но что, если вы хотите хранить произвольные данные в обычном HTML? Вот еще одна альтернатива ...

<input type="hidden" name="whatever" value="foobar"/>

Поместите ваши данные в атрибуты name и value скрытого элемента ввода. Это может быть полезно, если сервер генерирует HTML (то есть скрипт PHP или что-то еще), и ваш код JavaScript будет использовать эту информацию позже.

Правда, не самый чистый, но это альтернатива. Он совместим со всеми браузерами и является действительным XHTML. Вы НЕ должны использовать пользовательские атрибуты, а также не должны использовать атрибуты с префиксом data-, так как он может работать не во всех браузерах. И, кроме того, ваш документ не пройдет проверку W3C.

BMiner
источник
точно не уверен, но некоторые браузеры могут жаловаться, если вы используете пользовательские атрибуты со "строгим" типом документа. В любом случае, это не правильный XHTML.
BMiner
2

Вы можете использовать префикс данных вашего собственного атрибута made для случайного элемента ( <span data-randomname="Data goes here..."></span>), но это допустимо только в HTML5. Таким образом, браузеры могут жаловаться на достоверность.

Вы также можете использовать <span style="display: none;">Data goes here...</span>тег. Но таким образом вы не можете использовать функции атрибутов, и если css и js отключены, это тоже не очень удачное решение.

Но лично я предпочитаю следующее:

<input type="hidden" title="Your key..." value="Your value..." />

Входные данные во всех случаях будут скрыты, атрибуты полностью действительны, и они не будут отправлены, если они находятся внутри <form>тега, поскольку у него нет имени, верно? Прежде всего, атрибуты действительно легко запомнить, а код выглядит красиво и легко для понимания. Вы можете даже добавить в него ID-атрибут, чтобы вы могли легко получить к нему доступ и с помощью JavaScript, а также получить доступ к паре ключ-значение input.title; input.value.

Йети
источник
Я уверен, что вы не работали с таблицами HTML и выбора достаточно. Вы будете использовать атрибут data чаще, чтобы сохранить работу.
1
Я действительно часто использую атрибут data-. Но это зависит от ваших требований. Например, с <input /> вы можете иметь любую клавишу, тогда как для «data-» это ограничено предпочтительно строчной строкой без каких-либо буквенно-цифровых символов.
Йети
1

Одна возможность может быть:

  • Создайте новый div для хранения всех расширенных / произвольных данных.
  • Сделайте что-нибудь, чтобы убедиться, что этот div невидим (например, CSS плюс атрибут класса в div)
  • Поместите расширенные / произвольные данные в теги [X] HTML (например, как текст в ячейках таблицы или что-либо еще, что вам может понравиться) в этом невидимом элементе div
ChrisW
источник
1

Другим подходом может быть сохранение пары ключ: значение в виде простого класса с использованием следующего синтаксиса:

<div id="my_div" class="foo:'bar'">...</div>

Это верно и может быть легко получено с помощью селекторов jQuery или пользовательской функции.

Рафаель
источник
0

У моего предыдущего работодателя мы постоянно использовали пользовательские теги HTML для хранения информации об элементах формы. Подвох: мы знали, что пользователь был вынужден использовать IE.

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

Если вы можете контролировать, какой браузер использует ваш читатель (т. Е. Внутренний веб-апплет для корпорации), то непременно попробуйте его. Что может повредить, верно?

Джерри
источник
0

Вот как я делаю вам AJAX страницы ... это довольно простой метод ...

    function ajax_urls() {
       var objApps= ['ads','user'];
        $("a.ajx").each(function(){
               var url = $(this).attr('href');
               for ( var i=0;i< objApps.length;i++ ) {
                   if (url.indexOf("/"+objApps[i]+"/")>-1) {
                      $(this).attr("href",url.replace("/"+objApps[i]+"/","/"+objApps[i]+"/#p="));
                   }
               }
           });
}

Как это работает, он в основном просматривает все URL-адреса, имеющие класс «ajx», заменяет ключевое слово и добавляет знак #, поэтому, если js отключен, URL-адреса будут действовать так, как обычно ... all » apps "(каждый раздел сайта) имеет свое ключевое слово ... так что все, что мне нужно сделать, это добавить массив js выше, чтобы добавить больше страниц ...

Так, например, мои текущие настройки установлены на:

 var objApps= ['ads','user'];

Так что, если у меня есть URL-адрес, такой как:

www.domain.com/ads/3923/bla/dada/bla

js-скрипт заменит / ads / part, так что мой URL окажется

www.domain.com/ads/#p=3923/bla/dada/bla

Тогда я использую плагин BBQ jquery, чтобы загрузить страницу соответственно ...

http://benalman.com/projects/jquery-bbq-plugin/

Ясон
источник
0

Я обнаружил, что плагин метаданных является отличным решением проблемы хранения произвольных данных с тегом html таким образом, чтобы его было легко найти и использовать с jQuery.

Важно : фактический размер файла, который вы включаете, составляет всего 5 КБ, а не 37 КБ (это размер полного пакета загрузки)

Вот пример его использования для хранения значений, которые я использую при создании события отслеживания Google Analytics (примечание: data.label и data.value являются необязательными параметрами)

$(function () {
    $.each($(".ga-event"), function (index, value) {
        $(value).click(function () {
            var data = $(value).metadata();
            if (data.label && data.value) {
                _gaq.push(['_trackEvent', data.category, data.action, data.label, data.value]);
            } else if (data.label) {
                _gaq.push(['_trackEvent', data.category, data.action, data.label]);
            } else {
                _gaq.push(['_trackEvent', data.category, data.action]);
            }
        });
    });
});

<input class="ga-event {category:'button', action:'click', label:'test', value:99}" type="button" value="Test"/>
biofractal
источник
0

В html мы можем хранить пользовательские атрибуты с префиксом «data-» перед именем атрибута, например

<p data-animal='dog'>This animal is a dog.</p>, Проверьте документацию

Мы можем использовать это свойство для динамической установки и получения атрибутов, используя jQuery, например: Если у нас есть тег ap, например:

<p id='animal'>This animal is a dog.</p>

Затем, чтобы создать атрибут под названием «breed» для вышеуказанного тега, мы можем написать:

$('#animal').attr('data-breed', 'pug');

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

var breedtype = $('#animal').data('breed');

Акаш Гош
источник
0

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

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

Много лет спустя:

Этот вопрос был опубликован примерно за три года до того, как data-...атрибуты стали верным вариантом с появлением html 5, поэтому правда изменилась, и первоначальный ответ, который я дал, больше не актуален. Теперь я бы предложил вместо этого использовать атрибуты данных .

<a data-articleId="5" href="link/for/non-js-users.html">

<script>
    let anchors = document.getElementsByTagName('a');
    for (let anchor of anchors) {
        let articleId = anchor.dataset.articleId;
    }
</script>
Kris
источник
Как вы должны передать данные в JavaScript?
Ник