javascript - tipos - Atributos personalizados-Sí o no?
que es data reactid (14)
Recientemente, he estado leyendo más y más sobre personas que usan atributos personalizados en sus etiquetas HTML, principalmente con el propósito de integrar algunos bits adicionales de datos para usar en código javascript.
Esperaba obtener alguna información sobre si el uso de atributos personalizados es una buena práctica, y también cuáles son algunas alternativas.
Parece que realmente puede simplificar tanto el lado del servidor como el del lado del cliente, pero tampoco es compatible con W3C.
¿Deberíamos utilizar atributos HTML personalizados en nuestras aplicaciones web? ¿Por qué o por qué no?
Para aquellos que piensan que los atributos personalizados son una buena cosa: ¿cuáles son algunas cosas que se deben tener en cuenta al usarlos?
Para aquellos que piensan que los atributos personalizados son malos: ¿qué alternativas utiliza para lograr algo similar?
Actualización: Estoy más interesado en el razonamiento detrás de los diversos métodos, así como en los puntos de por qué un método es mejor que otro. Creo que todos podemos encontrar 4-5 formas diferentes de lograr lo mismo. (elementos ocultos, scripts en línea, clases adicionales, análisis de información de ID, etc.).
Actualización 2: Parece que la característica de atributos de data-
HTML 5 tiene mucho soporte aquí (y tiendo a estar de acuerdo, parece una opción sólida). Hasta ahora no he visto muchas refutaciones para esta sugerencia. ¿Hay algún problema / inconveniente que deba preocuparse por el uso de este enfoque? ¿O es simplemente una invalidación ''inofensiva'' de las especificaciones actuales de W3C?
Aquí hay una técnica que he estado usando recientemente:
<div id="someelement">
<!-- {
someRandomData: {a:1,b:2},
someString: "Foo"
} -->
<div>... other regular content...</div>
</div>
El comentario-objeto se enlaza con el elemento padre (es decir, #someelement).
Aquí está el analizador: http://pastie.org/511358
Para obtener los datos de cualquier elemento en particular, simplemente llame a parseData
con una referencia a ese elemento pasado como único argumento:
var myElem = document.getElementById(''someelement'');
var data = parseData( myElem );
data.someRandomData.a; // <= Access the object staight away
Puede ser más sucinto que eso:
<li id="foo">
<!--{specialID:245}-->
... content ...
</li>
Acceder a él:
parseData( document.getElementById(''foo'') ).specialID; // <= 245
La única desventaja de usar esto es que no se puede usar con elementos de cierre automático (por ejemplo, <img/>
), ya que los comentarios deben estar dentro del elemento para que se consideren como los datos de ese elemento.
EDITAR :
Notables beneficios de esta técnica:
- Fácil de implementar
- No invalida HTML / XHTML
- Fácil de usar / entender (notación JSON básica)
- Discreta y semánticamente más limpia que la mayoría de las alternativas
Aquí está el código del analizador (copiado desde el hipervínculo http://pastie.org/511358 anterior, en caso de que alguna vez no esté disponible en 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;
};
})();
Espec .: Cree un control TextBox de ASP.NET que automáticamente formatea automáticamente su texto como un número, de acuerdo con las propiedades "DecimalSeparator" y "ThousandsSeparator", usando JavaScript.
Una forma de transferir estas propiedades del control a JavaScript es hacer que el control muestre las propiedades personalizadas:
<input type="text" id="" decimalseparator="." thousandsseparator="," />
Las propiedades personalizadas son fácilmente accesibles por JavaScript. Y mientras una página que utiliza elementos con propiedades personalizadas no se validate , la representación de esa página no se verá afectada.
Solo utilizo este enfoque cuando quiero asociar tipos simples como cadenas y enteros a elementos HTML para usar con JavaScript. Si quiero que los elementos HTML sean más fáciles de identificar, haré uso de las propiedades class e id .
HTML 5 permite explícitamente atributos personalizados que comienzan con data
. Entonces, por ejemplo, <p data-date-changed="Jan 24 5:23 pm">Hello</p>
es válido. Ya que está oficialmente soportado por un estándar, creo que esta es la mejor opción para atributos personalizados. Y no requiere que sobrecargues otros atributos con hacks, por lo que tu HTML puede permanecer semántico.
Fuente: http://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes
Hemos creado un editor basado en web que comprende un subconjunto de HTML, un subconjunto muy estricto (que los clientes de correo lo entienden casi universalmente). Necesitamos expresar cosas como <td width="@INSWIDTH_42@">
en la base de datos, pero no podemos tener eso en el DOM, de lo contrario, el navegador donde se ejecuta el editor, se vuelve loco (o es más probable que se vuelva loco) es probable que se asuste con los atributos personalizados). Queríamos arrastrar y soltar, por lo que ponerlo en forma pura en el DOM estaba fuera, al igual que lo era jquery .data()
(los datos adicionales no se copiaron correctamente). Probablemente también necesitábamos los datos adicionales para el recorrido en .html()
. Al final, decidimos utilizar <td width="1234" rs-width="@INSWIDTH_42@">
durante el proceso de edición, y luego cuando publicamos todo, eliminamos el width
y realizamos una búsqueda y destrucción de <td width="1234" rs-width="@INSWIDTH_42@">
s/rs-width=/width=/g
.
Al principio, el tipo que escribió la mayor parte de esto fue la validación-nazi sobre este tema y trató todo para evitar nuestro atributo personalizado, pero al final aceptó cuando nada más parecía funcionar para TODOS nuestros requisitos. Le ayudó cuando se dio cuenta de que el atributo personalizado nunca aparecería en un correo electrónico. Consideramos la posibilidad de codificar nuestros datos adicionales en class
, pero decidió que sería el mayor de los dos males.
Personalmente, prefiero tener las cosas limpias y aprobar validadores, etc., pero como empleado de la empresa debo recordar que mi responsabilidad principal es promover la causa de la empresa (ganar tanto dinero lo más rápido posible), no la de mi deseo egoísta de pureza tecnica Las herramientas deberían funcionar para nosotros; No nosotros por ellos.
Incruste los datos en el dom y use metadata para jQuery .
Todos los buenos complementos son compatibles con el complemento de metadatos (permitiendo las opciones por etiqueta).
También permite estructuras de datos / datos infinitamente complejas, así como pares clave-valor.
<li class="someclass {''some'': ''random,''json'':''data''} anotherclass">...</li>
O
<li class="someclass" data="{''some'':''random'', ''json'': ''data''}">...</li>
O
<li class="someclass"><script type="data">{"some":"random","json":"data"}</script> ...</li>
A continuación, obtener los datos como tal:
var data = $(''li.someclass'').metadata();
if ( data.some && data.some == ''random'' )
alert(''It Worked!'');
La forma más fácil de evitar el uso de atributos personalizados es usar los atributos existentes.
usar nombres de clase significativos y relevantes.
Por ejemplo, haga algo como: type=''book''
y type=''cd''
, para representar libros y cds. Las clases son mucho mejores para representar lo que ES algo.
por ejemplo, class=''book''
He usado atributos personalizados en el pasado, pero honestamente, realmente no hay necesidad de usarlos si hace uso de los atributos existentes de una manera semánticamente significativa.
Para dar un ejemplo más concreto, supongamos que tiene un sitio que ofrece enlaces a diferentes tipos de tiendas. Podrías usar lo siguiente:
<a href=''wherever.html'' id=''bookstore12'' class=''book store''>Molly''s books</a>
<a href=''whereverelse.html'' id=''cdstore3'' class=''cd store''>James'' Music</a>
El estilo css podría usar clases como:
.store { }
.cd.store { }
.book.store { }
En el ejemplo anterior, vemos que ambos son enlaces a tiendas (a diferencia de otros enlaces no relacionados en el sitio) y uno es una tienda de cd, y el otro es una librería.
Los atributos personalizados, en mi humilde opinión, no deberían usarse ya que no se validan. Alternativo a eso, puedes definir muchas clases para un solo elemento como:
<div class=''class1 class2 class3''>
Lorem ipsum
</div>
No estoy usando atributos personalizados, porque estoy generando XHTML, porque quiero que los datos sean legibles por la máquina por un software de terceros (aunque podría extender el esquema XHTML si quisiera).
Como alternativa a los atributos personalizados, la mayoría de las veces encuentro suficientes los atributos id y class (por ejemplo, como se menciona en otras respuestas).
También, considere esto:
Si los datos adicionales deben ser legibles para los humanos, así como legibles por la máquina, deben codificarse utilizando etiquetas y texto HTML (visibles) en lugar de atributos personalizados.
Si no necesita ser legible por humanos, entonces puede codificarse usando etiquetas y texto HTML invisibles .
Algunas personas hacen una excepción: permiten atributos personalizados, agregados al DOM por Javascript en el lado del cliente en tiempo de ejecución. Consideran que esto está bien: como los atributos personalizados solo se agregan al DOM en tiempo de ejecución, el HTML no contiene atributos personalizados.
No veo ningún problema en el uso de las funciones XHTML existentes sin romper nada o ampliar su espacio de nombres. Echemos un vistazo a un pequeño ejemplo:
<div id="some_content">
<p>Hi!</p>
</div>
¿Cómo agregar información adicional a some_content sin atributos adicionales? ¿Qué hay de agregar otra etiqueta como la siguiente?
<div id="some_content">
<div id="some_content_extended" class="hidden"><p>Some alternative content.</p></div>
<p>Hi!</p>
</div>
Mantiene la relación a través de una id / extensión bien definida "_extendido" de su elección y por su posición en la jerarquía. A menudo utilizo este enfoque junto con jQuery y sin utilizar realmente las técnicas similares a Ajax.
No. Intenta algo como esto en su lugar:
<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>
Para aplicaciones web complejas, coloco atributos personalizados en todo el lugar.
Para más páginas de cara al público, uso el atributo "rel" y vuelco todos mis datos allí en JSON y luego los descifro con MooTools o jQuery:
<a rel="{color:red, awesome:true, food: tacos}">blah</a>
Estoy tratando de mantener el atributo de datos HTML 5 últimamente solo para "preparar", pero aún no es natural.
Puede crear cualquier atributo si especifica un esquema para su página.
Por ejemplo:
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:addthis="http://www.addthis.com/help/api-spec">
...
<a addthis:title="" addthis:url="" ...>
Facebook (incluso etiquetas)
<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"/>
Sé que la gente está en contra, pero se me ocurrió una solución súper corta para esto. Si desea utilizar un atributo personalizado como "mío", por ejemplo:
<a href="test.html" mine-one="great" mine-two="awesome">Test</a>
Luego, puede ejecutar este código para recuperar un objeto tal como lo hace 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;
});
Uso campos personalizados todo el tiempo, por ejemplo, <ai = "" .... Luego, haga referencia a i con jquery. HTML no válido, sí. Funciona bien, sí.