Пользовательские атрибуты - да или нет?

Недавно я все больше читал о тех, кто использует пользовательские атрибуты в своих тегах HTML, в основном для встраивания некоторых дополнительных бит данных для использования в javascript-коде.

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

Похоже, что он действительно упрощает как серверный, так и клиентский код, но также не совместим с W3C.

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

Для тех, кто считает, что пользовательские атрибуты - это хорошо: какие вещи нужно иметь в виду при их использовании?

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

Обновление: Меня больше интересуют рассуждения о различных методах, а также о том, почему один метод лучше другого. Я думаю, мы все можем придумать 4-5 разных способов сделать то же самое. (скрытые элементы, встроенные скрипты, дополнительные классы, информация синтаксического анализа от идентификаторов и т.д.).

Обновление 2: Кажется, что атрибут атрибута HTML 5 data- имеет здесь большую поддержку (и я склонен согласиться, он выглядит как твердый вариант). До сих пор я не видел много способов опровержения этого предложения. Существуют ли какие-либо проблемы/подводные камни, чтобы беспокоиться об использовании этого подхода? Или это просто "безобидная" недействительность текущих спецификаций W3C?

Ответ 1

HTML 5 явно позволяет настраивать атрибуты, начинающиеся с data. Так, например, <p data-date-changed="Jan 24 5:23 p.m.">Hello</p>. Поскольку он официально поддерживается стандартом, я думаю, что это лучший вариант для пользовательских атрибутов. И вам не нужно перегружать другие атрибуты хаками, поэтому ваш HTML может оставаться семантическим.

Источник: http://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes

Ответ 2

Вот техника, которую я использовал недавно:

<div id="someelement">

    <!-- {
        someRandomData: {a:1,b:2},
        someString: "Foo"
    } -->

    <div>... other regular content...</div>
</div>

Компонент комментария связывается с родительским элементом (т.е. #someelement).

Здесь синтаксический анализатор: http://pastie.org/511358

Чтобы получить данные для любого конкретного элемента, просто вызовите parseData с ссылкой на этот элемент, переданный как единственный аргумент:

var myElem = document.getElementById('someelement');

var data = parseData( myElem );

data.someRandomData.a; // <= Access the object staight away

Это может быть более кратким, чем это:

<li id="foo">
    <!--{specialID:245}-->
    ... content ...
</li>

Доступ к ней:

parseData( document.getElementById('foo') ).specialID; // <= 245

Единственный недостаток использования этого заключается в том, что он не может использоваться с самозакрывающимися элементами (например, <img/>), так как комментарии должны быть внутри элемента, который следует рассматривать как данные этого элемента.


ИЗМЕНИТЬ

Значительные преимущества этой техники:

  • Легко реализовать
  • Не отменяет HTML/XHTML
  • Простота использования/понимания (базовая нотация JSON)
  • Ненавязчивое и семантически более чистое, чем большинство альтернатив.

Здесь код синтаксического анализа (скопированный из гиперссылки http://pastie.org/511358, если она когда-либо становится недоступной pastie.org):

var parseData = (function(){

    var getAllComments = function(context) {

            var ret = [],
                node = context.firstChild;

            if (!node) { return ret; }

            do {
                if (node.nodeType === 8) {
                    ret[ret.length] = node;
                }
                if (node.nodeType === 1) {
                    ret = ret.concat( getAllComments(node) );
                }
            } while( node = node.nextSibling );

            return ret;

        },
        cache = [0],
        expando = 'data' + +new Date(),
        data = function(node) {

            var cacheIndex = node[expando],
                nextCacheIndex = cache.length;

            if(!cacheIndex) {
                cacheIndex = node[expando] = nextCacheIndex;
                cache[cacheIndex] = {};
            }

            return cache[cacheIndex];

        };

    return function(context) {

        context = context || document.documentElement;

        if ( data(context) && data(context).commentJSON ) {
            return data(context).commentJSON;
        }

        var comments = getAllComments(context),
            len = comments.length,
            comment, cData;

        while (len--) {
            comment = comments[len];
            cData = comment.data.replace(/\n|\r\n/g, '');
            if ( /^\s*?\{.+\}\s*?$/.test(cData) ) {
                try {
                    data(comment.parentNode).commentJSON =
                        (new Function('return ' + cData + ';'))();
                } catch(e) {}
            }
        }

        return data(context).commentJSON || true;

    };

})();

Ответ 3

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

Например:

Addthis

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:addthis="http://www.addthis.com/help/api-spec">
...
<a addthis:title="" addthis:url="" ...>

Facebook (даже теги)

<html xmlns:og="http://opengraphprotocol.org/schema/" xmlns:fb="http://www.facebook.com/2008/fbml">
...
<fb:like href="http://developers.facebook.com/" width="450" height="80"/>

Ответ 4

Самый простой способ избежать использования настраиваемых атрибутов - использовать существующие атрибуты.

используйте значащие, соответствующие имена классов.
Например, сделайте что-то вроде: type='book' и type='cd', представлять книги и компакт-диски. Занятия намного лучше для представления того, что что-то есть.

например. class='book'

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

Чтобы дать более конкретный пример, скажем, у вас есть сайт, дающий ссылки на разные виды магазинов. Вы можете использовать следующее:

<a href='wherever.html' id='bookstore12' class='book store'>Molly books</a>
<a href='whereverelse.html' id='cdstore3' class='cd store'>James' Music</a>

css стиль может использовать такие классы, как:

.store { }
.cd.store { }
.book.store { }

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

Ответ 5

Вставить данные в dom и использовать metadata для jQuery.

Все хорошие плагины поддерживают плагин метаданных (позволяя использовать теги).

Он также позволяет бесконечно сложные структуры данных/данных, а также пары ключевых значений.

<li class="someclass {'some': 'random,'json':'data'} anotherclass">...</li>

ИЛИ

<li class="someclass" data="{'some':'random', 'json': 'data'}">...</li>

ИЛИ

<li class="someclass"><script type="data">{"some":"random","json":"data"}</script> ...</li>

Затем получите данные так:

var data = $('li.someclass').metadata();
if ( data.some && data.some == 'random' )
alert('It Worked!');

Ответ 6

Я не вижу проблем с использованием существующих функций XHTML, не нарушая ничего или расширяя пространство имен. Давайте рассмотрим небольшой пример:

<div id="some_content">
 <p>Hi!</p>
</div>

Как добавить дополнительную информацию в some_content без дополнительных атрибутов? Как насчет добавления другого тега, как показано ниже?

<div id="some_content">
 <div id="some_content_extended" class="hidden"><p>Some alternative content.</p></div>
 <p>Hi!</p>
</div>

Он поддерживает отношение через четко определенный идентификатор/расширение "_расширенный" по вашему выбору и по его положению в иерархии. Я часто использую этот подход вместе с jQuery и фактически не использую подобные Ajax методы.

Ответ 7

Я не использую пользовательские атрибуты, потому что я выводил XHTML, потому что я хочу, чтобы данные были машиносчитываемыми сторонним программным обеспечением (хотя я мог бы расширить схему XHTML, если захочу).

В качестве альтернативы пользовательским атрибутам, в основном, я обнаруживаю атрибуты id и class (например, как указано в других ответах).

Также рассмотрим следующее:

  • Если дополнительные данные должны быть удобочитаемыми, а также машиночитаемыми, тогда их необходимо кодировать с использованием (видимых) HTML-тегов и текста вместо пользовательских атрибутов.

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

Некоторые люди делают исключение: они разрешают настраиваемые атрибуты, добавленные в DOM Javascript на стороне клиента во время выполнения. Они считают, что это нормально: поскольку пользовательские атрибуты добавляются только в DOM во время выполнения, HTML не содержит пользовательских атрибутов.

Ответ 8

Най. Попробуйте что-то вроде этого:

<div id="foo"/>

<script type="text/javascript">
  document.getElementById('foo').myProperty = 'W00 H00! I can add JS properties to DOM nodes without using custom attributes!';
</script>

Ответ 9

Мы создали веб-редактор, который понимает подмножество HTML - очень строгий поднабор (который почти повсеместно воспринимается почтовыми клиентами). Нам нужно выразить такие вещи, как <td width="@[email protected]"> в базе данных, но мы не можем иметь этого в DOM, иначе браузер, в котором работает редактор, выйдет из себя (или, скорее всего, будет волноваться, чем может показаться пользовательские атрибуты). Мы хотели перетащить, поэтому его просто в DOM не было, как и jquery .data() (дополнительные данные не были правильно скопированы). Вероятно, нам также понадобились дополнительные данные для поездки в .html(). В конце мы остановились на использовании <td width="1234" rs-width="@[email protected]"> в процессе редактирования, а затем, когда мы все это сделали, удалим width и выполним поиск и уничтожение регулярных выражений s/rs-width=/width=/g.

Сначала парень, пишущий большую часть этого, был валидацией-нацистами по этому вопросу и попробовал все, чтобы избежать нашего пользовательского атрибута, но, в конце концов, согласился, когда больше ничего не работало для ВСЕХ наших требований. Это помогло, когда он понял, что пользовательский атрибут никогда не появится в электронном письме. Мы действительно рассматривали кодирование наших дополнительных данных в class, но решили, что это будет больше из двух зол.

Лично я предпочитаю чистить вещи и пропускать валидаторы и т.д., но, как сотрудник компании, я должен помнить, что моя главная ответственность заключается в том, чтобы продвигать компанию (делая как можно больше денег как можно быстрее), а не моей эгоистическое стремление к технической чистоте. Инструменты должны работать для нас; не мы для них.

Ответ 10

Я знаю, что люди против этого, но я придумал для этого очень короткое решение. Если вы хотите использовать настраиваемый атрибут типа "мой", например, например:

<a href="test.html" mine-one="great" mine-two="awesome">Test</a>

Затем вы можете запустить этот код, чтобы вернуть объект так же, как jquery.data().

var custom_props = {} ;
$.each($(".selector")[0].attributes, function(i,x) {
    if (this.specified && x.name.indexOf("mine-") !== -1) 
        self.new_settings[x.name.replace("modal-","")] = x.value;
});

Ответ 11

Spec: Создайте элемент управления TextBox ASP.NET, который динамически автоматически форматирует его текст как число, в соответствии с свойствами "DecimalSeparator" и "ThousandsSeparator", используя JavaScript.



Один из способов переноса этих свойств из элемента управления в JavaScript состоит в том, чтобы управлять визуализацией пользовательских свойств:

<input type="text" id="" decimalseparator="." thousandsseparator="," />

Пользовательские свойства легко доступны JavaScript. И пока страница, использующая элементы с пользовательскими свойствами, не будет validate, рендеринг этой страницы не будет затронут.



I только использует этот подход, когда я хочу связать простые типы, такие как строки и целые, с элементами HTML для использования с JavaScript. Если я хочу, чтобы элементы HTML легче идентифицировать, я буду использовать свойства класса и id.

Ответ 12

Для сложных веб-приложений я удаляю пользовательские атрибуты повсюду.

Для более публичных страниц я использую атрибут rel и дамп всех моих данных в JSON, а затем декодирую его с помощью MooTools или jQuery:

<a rel="{color:red, awesome:true, food: tacos}">blah</a>

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

Ответ 13

Я использую пользовательские поля все время, например, < a я = "".... Затем ссылку на я с jquery. Недопустимый html, да. Это хорошо работает, да.

Ответ 14

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

<div class='class1 class2 class3'>
    Lorem ipsum
</div>