Texto original en inglés: Las siete reglas del JavaScript discreto
Dirección original: http://icant.co.uk/articles/seven-rules-of-unobtrusive-javascript/
Autor original: Chris Heilmann
Dirección de traducción: http://www.zhuoqun.net/html/y2008/1103.html
Escrito al frente: Cuando Kejun nos estaba entrenando JavaScript hace algún tiempo, recomendó muchos artículos clásicos en las diapositivas, incluido este Un artículo. Me siento muy bien después de leerlo, pero a menudo no entiendo profundamente los artículos. Dio la casualidad de que no encontré una versión china de este artículo, así que se me ocurrió la idea de traducirlo. que pueda compartirlo y profundizar mi comprensión. El autor de este artículo, Chris Heilmann, es un ingeniero británico de Yahoo! (una figura de "padrino" según Kejun), y la traducción de este artículo también fue aprobada por él.
Una cosa más aquí, he traducido muchas cosas antes, pero en ese momento traducía más por traducir y no entendía muchos artículos técnicos, así que sigo siendo traductor hasta ahora. Continuaré traduciendo algunos artículos en el futuro, pero solo debería traducir artículos clásicos que deban entenderse con atención. Si tienes tiempo, aún deberías escribir más código. La práctica es el camino a seguir.
Traducción de terminología: con respecto al término "JavaScript discreto", no se me ocurre una traducción particularmente apropiada. Después de buscar en Internet, descubrí que algunos se tradujeron como "JavaScript discreto", algunos se tradujeron como "JavaScript no intrusivo" y algunos en Taiwán se tradujeron como "JavaScript no intrusivo"... Después de muchas investigaciones, Decidí usar "JavaScript no intrusivo". Esta traducción es "JavaScript intrusivo" (aunque todavía no me conviene), consulte este artículo para obtener más detalles. De hecho, "JavaScript discreto" contiene muchos significados y es difícil resumirlo en una palabra. Si está interesado, puede consultar la explicación de "JavaScript discreto" en Wikipedia. Además, creo que la traducción es para expresar el significado del autor y no necesariamente tiene que traducirse palabra por palabra, por lo que para facilitar la comprensión de los lectores, eliminé algunas y agregué otras en el artículo, pero estas son. sin perjudicar el sentido del texto original realizado sobre una base.
Hay otro punto a tener en cuenta, es decir, mis habilidades de traducción son muy amateur, por lo que es probable que haya errores en la traducción, así que corríjame.
Después de años de desarrollar, enseñar y escribir JavaScript discreto, descubrí las siguientes pautas. Espero que te ayuden a comprender un poco por qué es mejor diseñar y ejecutar JavaScript de esta manera. Estas reglas me han ayudado a entregar productos más rápido, con mayor calidad y más fáciles de mantener.
1. No hagas suposiciones (JavaScript es un asistente poco confiable)
Quizás la característica más importante del JavaScript discreto es que debes dejar de hacer suposiciones:
no asumas que JavaScript está disponible, será mejor que pienses que es posible. no está disponible en lugar de depender de él directamente.
No asuma que el navegador admite métodos y propiedades hasta que los haya probado y haya confirmado que funcionan.
No asuma que el código HTML es tan correcto como cree, verifíquelo cada vez y no haga nada si no está disponible.
Haga que JavaScript funcione de forma independiente de los dispositivos de entrada. Recuerde que otros scripts pueden afectar la funcionalidad de su JavaScript, así que asegúrese de que sus scripts tengan un alcance lo más seguro posible.
Antes de comenzar a diseñar tu script, lo primero que debes considerar es verificar el código HTML para el cual vas a escribir el script y ver si hay algo que pueda ayudarte a lograr tu objetivo.
2. Encuentre enlaces y relaciones de nodos (HTML es la piedra angular de las secuencias de comandos)
Antes de comenzar a escribir secuencias de comandos, eche un vistazo al HTML para el que desea escribir JavaScript. Si el HTML no está organizado o es desconocido, es casi imposible tener una buena solución de secuencias de comandos; es probable que cree demasiado marcado en JavaScript o que la aplicación dependa demasiado de JavaScript.
Hay algunas cosas a considerar en HTML, y son los enlaces y las relaciones de nodos.
<1>.Hook .HTML
El gancho original y más importante de HTML es ID, y se puede acceder a ID a través del método DOM más rápido: getElementById. Si todos los ID en un documento HTML válido son únicos (hay un error en IE con respecto al nombre y el ID, pero algunas buenas bibliotecas resuelven este problema), usar ID es seguro, confiable y fácil de probar.
Algunos otros enlaces son elementos HTML y se puede acceder a las clases HTML a través del método getElementsByTagName, pero no se puede acceder a las clases CSS a través de métodos DOM nativos en la mayoría de los navegadores. Sin embargo, existen muchas bibliotecas de clases externas que proporcionan métodos que pueden acceder a nombres de clases CSS (similar a getElementsByClassName).
<2>Relación de nodo .HTML
Otro punto interesante sobre HTML es la relación entre etiquetas. Piense en la siguiente pregunta:
¿Cómo podemos llegar al nodo de destino más fácilmente y con la menor cantidad de recorrido DOM?
¿Al modificar qué marca podemos acceder a tantos nodos secundarios como sea posible que deban modificarse?
¿Qué atributos o información tiene un elemento determinado que puede usarse para llegar a otro elemento?
Atravesar el DOM requiere muchos recursos y es lento, por lo que debes intentar utilizar técnicas que ya se utilizan en los navegadores para hacerlo.
3. Deje el recorrido en manos de los expertos (CSS, recorra el DOM más rápido).
Crear scripts en el DOM y usar métodos o propiedades (getElementsByTagName, nextSibling, anteriorSibling, parentNode y otros) para recorrer el DOM parece confundir a muchas personas. . interesante. Lo interesante es que ya hemos hecho estas cosas a través de otra tecnología: CSS.
CSS es una técnica que utiliza selectores de CSS para acceder a elementos de destino y cambiar sus propiedades visuales atravesando el DOM. Una pieza compleja de JavaScript que utiliza DOM se puede reemplazar con un selector de CSS:
var n = document.getElementById('nav');
si(n){
var as = n.getElementsByTagName('a');
si(como.longitud > 0){
para(var i=0;como[i];i++){
as[i].style.color = '#369′;
as[i].style.textDecoration = 'ninguno';
}
}
}
/* El siguiente código tiene la misma función que el anterior*/
#nav a{
color:#369;
decoración de texto: ninguna;
}
Esta es una técnica muy poderosa que se puede aprovechar. Puede lograr esto agregando dinámicamente clases a elementos de alto nivel en el DOM o cambiando el ID del elemento. Si usa DOM para agregar una clase CSS al cuerpo del documento, los diseñadores pueden definir fácilmente versiones estáticas y dinámicas del documento.
JavaScript:
vardynamicClass = 'js';
var b = documento.cuerpo;
b.nombredeclase = b.nombredeclase? b.nombredeclase + 'js': 'js';
CSS:
/* Versión estática*/
#nav {
....
}
/* Versión dinámica*/
body.js #nav {
....
}
4. Comprenda los navegadores y los usuarios (y cree lo que necesita en función de los patrones de uso existentes)
Una gran parte de JavaScript discreto es comprender cómo funcionan los navegadores (especialmente cómo fallan) y qué esperan los usuarios. Independientemente del navegador, puedes crear fácilmente una interfaz completamente diferente usando JavaScript. Se pueden crear interfaces de arrastrar y soltar, áreas de plegado, barras de desplazamiento y controles deslizantes usando JavaScript, pero este problema no es una simple cuestión técnica. Debe pensar en las siguientes preguntas: ¿
Puede esta nueva interfaz ser independiente de los dispositivos de entrada? Si no, ¿en qué puedes confiar?
¿La nueva interfaz que creo sigue las pautas de un navegador u otra interfaz rica (¿puedes cambiar entre menús de varios niveles directamente con el mouse? ¿O necesitas usar la tecla de tabulación?)
¿Qué funcionalidad necesito proporcionar que dependa de JavaScript?
La última pregunta no es realmente un problema porque puedes usar DOM para crear HTML de la nada si es necesario. Un ejemplo de esto es un enlace "imprimir". Dado que los navegadores no proporcionan una funcionalidad que no sea JavaScript para imprimir un documento, es necesario utilizar el DOM para crear dichos enlaces. Lo mismo ocurre con una barra de título en la que se puede hacer clic y que implementa módulos para expandir y contraer contenido. La barra de título no se puede activar con el teclado, pero los enlaces sí. Entonces, para crear una barra de título en la que se puede hacer clic, debe agregar el enlace usando JavaScript y luego todos los usuarios con un teclado pueden contraer y expandir el módulo de contenido.
Un recurso excelente para resolver este tipo de problemas es la Biblioteca de patrones de diseño. En cuanto a saber qué cosas en el navegador son independientes de los dispositivos de entrada, depende de la acumulación de experiencia. Lo primero que debe comprender es el mecanismo de manejo de eventos.
5. Comprender los eventos (el manejo de eventos provoca cambios)
El manejo de eventos es el segundo paso hacia un JavaScript discreto. El punto no es hacer que todo se pueda arrastrar, hacer clic o agregarles manejo en línea, sino comprender que el manejo de eventos es algo que se puede separar por completo. Hemos separado HTML, CSS y JavaScript, pero no hemos ido muy lejos en la separación del manejo de eventos.
El controlador de eventos monitoreará los cambios que ocurren en los elementos del documento. Si ocurre un evento, el controlador encontrará un objeto maravilloso (generalmente un parámetro llamado e. Este objeto le dirá al elemento qué sucedió y qué se puede hacer con él). .
Lo realmente interesante de la mayoría del manejo de eventos es que no ocurre solo en el elemento al que desea acceder, sino en todos los elementos superiores en el DOM (pero no todos los eventos son así, enfoque y la excepción es el evento de desenfoque). . Por ejemplo, puede usar esta función para agregar solo un controlador de eventos a una lista de navegación y usar el método del controlador de eventos para obtener el elemento que realmente desencadenó el evento. Esta técnica se llama delegación de eventos y tiene varias ventajas:
solo necesita verificar si un elemento existe, en lugar de verificar cada elemento. Puede agregar o eliminar dinámicamente nodos secundarios sin eliminar el controlador de eventos correspondiente. Puede recordar otra cosa. al responder al mismo evento en diferentes elementos es que puede detener la propagación del evento al elemento principal y puede anular el comportamiento predeterminado de los elementos HTML (como los enlaces). Sin embargo, a veces esto no es una buena idea porque los navegadores dan a los elementos HTML el comportamiento que tienen por una razón. Por ejemplo, los enlaces pueden apuntar a un destino dentro de la página y dejarlos sin modificar garantiza que el usuario también pueda marcar el estado actual del script de la página.
6. Piense en otros (espacios de nombres, ámbitos y esquemas).
Su código casi nunca será el único código de script en un documento. Por lo tanto, es particularmente importante asegurarse de que no haya funciones globales o variables globales en su código que otros scripts puedan anular. Hay varios patrones disponibles para evitar este problema, el más básico de los cuales es usar la palabra clave var para inicializar todas las variables. Supongamos que escribimos el siguiente script:
var nav = document.getElementById('nav');
función inicio(){
// hacer cosas
}
función mostrar(){
// hacer cosas
}
función restablecer(){
// hacer cosas
}
El código anterior contiene una variable global llamada nav y tres funciones llamadas init, show y reset. Estas funciones pueden acceder a la variable de navegación y pueden acceder entre sí a través del nombre de la función:
var nav = document.getElementById('nav');
función inicio(){
espectáculo();
if(nav.className === 'mostrar'){
reiniciar();
}
// hacer cosas
}
función mostrar(){
var c = nav.className;
// hacer cosas
}
función restablecer(){
// hacer cosas
}
Puede evitar la codificación global anterior encapsulando el código en un objeto, de modo que las funciones se puedan convertir en métodos en el objeto y las variables globales se puedan convertir en propiedades en el objeto. Debe utilizar el método "nombre + dos puntos" para definir métodos y propiedades, y debe agregar una coma como separador después de cada propiedad o método.
var miScript = {
navegación:document.getElementById('nav'),
inicio:función(){
// hacer cosas
},
mostrar:función(){
// hacer cosas
},
restablecer:función(){
// hacer cosas
}
}
Se puede acceder a todos los métodos y propiedades de forma externa e interna utilizando el "nombre de clase + operador de punto".
var miScript = {
navegación:document.getElementById('nav'),
inicio:función(){
myScript.show();
if(myScript.nav.className === 'mostrar'){
myScript.reset();
}
// hacer cosas
},
mostrar:función(){
var c = myScript.nav.className;
// hacer cosas
},
restablecer:función(){
// hacer cosas
}
}
La desventaja de este modelo es que cada vez que accede a otros métodos o propiedades desde un método, debe agregar el nombre del objeto al frente y se puede acceder a todo lo que hay en el objeto desde el exterior. Si solo desea que otros scripts del documento puedan acceder a algún código, considere el siguiente patrón de módulo:
var miScript = función(){
//Estos son métodos y propiedades privados.
var navegación = document.getElementById('nav');
función inicio(){
// hacer cosas
}
función mostrar(){
// hacer cosas
}
función restablecer(){
// hacer cosas
}
//Los métodos y propiedades públicos están incluidos en la declaración de retorno usando la sintaxis de objeto
devolver {
público: función(){
},
foo:'barra'
}
}();
Puede acceder a las propiedades y métodos públicos devueltos de la misma manera que en el código anterior, en este caso: myScript.public() y myScript.foo. Pero aquí hay otro punto incómodo: cuando quieres acceder a un método público desde fuera o desde un método privado dentro, todavía tienes que escribir un nombre largo (el nombre del objeto puede ser muy largo). Para evitar esto, debes definirlos como privados y solo devolver un alias en la declaración de devolución:
var miScript = función(){
// Estos son métodos y propiedades privados.
var navegación = document.getElementById('nav');
función inicio(){
// hacer cosas
}
función mostrar(){
// hacer cosas
// hacer cosas
}
función restablecer(){
// hacer cosas
}
var foo = 'barra';
function public(){
}
// Devuelve solo punteros a aquellos métodos y propiedades privados a los que desea acceder
devolver {
público: público,
foo:foo
}
}();
Esto garantiza un estilo de código coherente y le permite utilizar alias más cortos para acceder a métodos o propiedades.
Si no desea exponer ningún método o propiedad al mundo exterior, puede encapsular todo el código en un método anónimo y ejecutarlo inmediatamente después de su definición:
(función(){
// todos estos son métodos y propiedades privados
var navegación = document.getElementById('nav');
función inicio(){
// hacer cosas
show(); // Aquí no se requiere ningún prefijo de nombre de clase
}
función mostrar(){
// hacer cosas
}
función restablecer(){
// hacer cosas
}
})();
Este patrón es excelente para módulos de código que se ejecutan solo una vez y no dependen de otras funciones.
Si sigue las reglas anteriores, su código funcionará mejor para los usuarios, se ejecutará mejor en las máquinas y se llevará mejor con el código de otros desarrolladores. Sin embargo, hay un grupo que es necesario tener en cuenta.
7. Considere a los desarrolladores que se harán cargo de su código (facilita el mantenimiento)
El último paso para hacer que su script sea verdaderamente discreto es verificarlo dos veces después de escribirlo y ocuparse de los desarrolladores que se harán cargo de su código una vez que el guión se pone en marcha. Considere las siguientes preguntas:
¿Son todos los nombres de variables y funciones sensatos y fáciles de entender?
¿Está el código correctamente organizado? ¿Fluye sin problemas de principio a fin?
¿Son todas las dependencias obvias?
¿Se han agregado comentarios donde sea posible que puedan causar confusión?
Lo más importante a tener en cuenta es: tenga en cuenta que es más probable que se modifiquen el código HTML y CSS del documento que el JavaScript (porque son responsables del efecto visual). Por lo tanto, no incluya clases ni ID que puedan ver los usuarios finales en el código del script, sino sepárelos en un objeto que contenga información de configuración.
miscript = función(){
configuración var = {
ID de navegación: 'nav',
clase visible: 'mostrar'
};
var nav = document.getElementById(config.navigationID);
función inicio(){
espectáculo();
if(nav.className === config.visibleClass){
reiniciar();
};
// hacer cosas
};
función mostrar(){
var c = nav.className;
// hacer cosas
};
función restablecer(){
// hacer cosas
};
}();
De esta manera el mantenedor sabe dónde modificar estas propiedades sin tener que cambiar otro código.
Más información
Estas son las siete pautas que descubrí. Si desea obtener más información sobre los temas tratados anteriormente, consulte los siguientes enlaces: