Un pequeño problema al borrar el historial de JavaScript
(JavaScript es un asistente poco confiable)
Una de las características más importantes de JavaScript, que puede que no sea una sorpresa, es que debes deja de hacer suposiciones:
*No asumas que JavaScript está disponible; es mejor asumir que probablemente no esté disponible que confiar en él directamente.
*No asuma que el navegador admite ciertos métodos y propiedades hasta que los haya probado y haya confirmado que funcionan.
*No asumas que el código HTML es tan correcto como crees, compruébalo cada vez y no hagas nada si no es así.
* Haga que las funciones de JavaScript sean independientes de los dispositivos de entrada.
*Tenga en cuenta 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.
Lo primero que debe considerar antes de comenzar a diseñar su secuencia de comandos es examinar el código HTML que desea crear y ver cuáles le ayudarán a lograr sus objetivos.
2. Descubra la relación entre ganchos y nodos
(HTML es la piedra angular de los scripts)
Antes de comenzar a escribir scripts, primero eche un vistazo a lo que quieres hacer Está escrito en JavaScript como HTML. 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 demasiadas etiquetas en JavaScript o que la aplicación dependa demasiado de JavaScript.
Hay algunas cosas que deben considerarse en HTML, que es la relación entre ganchos y nodos.
<1>. Ganchos HTML
El primer y más importante gancho HTML es el ID, al que se puede acceder 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 con los nombres y los ID en IE, pero algunas buenas bibliotecas han resuelto este problema), entonces usar ID es seguro, confiable y fácil de probar.
Otros ganchos son elementos HTML y clases CSS. Se puede acceder a los elementos 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 brindan acceso a nombres de clases CSS (similar a getElementsByClassName).
& lt2 & gt. Relaciones de nodos HTML
Otro aspecto interesante de HTML es la relación entre etiquetas. Considere las siguientes preguntas:
*¿Cómo podemos llegar al nodo objetivo más fácilmente y con la menor cantidad de recorrido DOM?
*¿Qué etiquetas se pueden modificar para acceder a tantos nodos secundarios como sea posible?
*¿Qué atributos o información puede utilizar un determinado elemento para llegar a otro elemento?
Atravesar el DOM consume muchos recursos y es lento, por lo que deberíamos intentar hacerlo utilizando técnicas que ya se utilizan en los navegadores.
3. Deja el recorrido en manos de los expertos.
(CSS, recorrido DOM más rápido)
Curiosamente, muchas personas parecen estar confundidas acerca de los scripts DOM y los métodos o propiedades utilizados para atravesar el DOM (getelementsbytagname, siguiente hermano, hermano anterior). , nodo principal, etc.) están confundidos. Curiosamente, ya hacemos estas cosas con otra tecnología: CSS.
CSS es una tecnología que utiliza selectores de CSS para acceder a elementos de destino y cambiar sus propiedades visuales atravesando el DOM. El JavaScript complejo que utiliza DOM se puede reemplazar con selectores de CSS:
Código Java var n = documento.
getelementbyid(' nav '); if (n) { var as = n . getelementsbytagname(' a '); if (as . length > 0) { for (var i = 0; as [i]; i++) { as [I]. style . color = ' # 369 '; as[I]. text decor = ' none }}}/*El siguiente código tiene la misma función que el anterior*/# nav a { color: # 369; decoración de texto: ninguna; } var n = document . getelementbyid(' nav '); if (n) { var as = n . (var I = 0;as[i];i++){ as[I].style.color='#369';as[I].style.text decoracion='none';}}}/*El código siguiente Misma función que la anterior */# nav a { color: # 369; text-decoration: none }
Esta es una habilidad poderosa que se puede aprovechar. Puede hacer esto agregando dinámicamente una clase o cambiando el ID del elemento a un elemento de alto nivel en el DOM. Los diseñadores pueden definir fácilmente versiones estáticas y dinámicas de un documento si usan DOM para agregar clases CSS al cuerpo del documento.
Código Java JavaScript: var clase dinámica = ' js '; var b = document.bodyclassName = b.className? b. nombre de clase+' js ':" js "; CSS: /*versión estática*/# nav {...}/*versión dinámica*/body.js # nav {...} JavaScript:var clase dinámica = ' js ';var b = document.bodyclassName = b.className? b. nombre de clase+' js ':" js "; CSS: /*versión estática*/# nav {...}/*versión dinámica*/body.js # nav {...}
4. Comprenda los navegadores y los usuarios
(Cree lo que necesita en función de los patrones de uso existentes)
Una parte importante de JavaScript discreto es comprender cómo funcionan los navegadores (especialmente cómo fallan) y qué los usuarios esperan. No importa qué navegador utilice, puede crear fácilmente interfaces completamente diferentes utilizando JavaScript. Con JavaScript se pueden crear interfaces de arrastrar y soltar, áreas plegables, barras de desplazamiento y controles deslizantes, pero el problema no es simplemente técnico. Debes considerar 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 (¿puedo cambiar directamente entre menús de varios niveles con el mouse? ¿O necesito usar la tecla de tabulación?)
*¿Qué funcionalidad necesito proporcionar que dependa de JavaScript?
La última pregunta no es realmente un problema, ya que el DOM se puede utilizar para crear HTML de la nada si es necesario. Los enlaces "Imprimir" son un ejemplo, porque los navegadores no proporcionan funciones distintas de JavaScript para imprimir documentos, por lo que es necesario utilizar el DOM para crear dichos enlaces. Este también es el caso de las barras de título en las que se puede hacer clic y que permiten que los módulos de contenido se expandan y contraigan. El teclado no puede activar la barra de título, pero los enlaces sí.
Entonces, para crear una barra de título en la que se puede hacer clic, debe usar JavaScript para agregar el enlace y luego todos los usuarios con un teclado pueden reducir y expandir el módulo de contenido.
Un excelente recurso para resolver este tipo de problemas es la Biblioteca de patrones de diseño. En cuanto a saber qué es independiente de los dispositivos de entrada en el navegador, depende de la acumulación de experiencia. Lo primero que debe comprender es el mecanismo de manejo de eventos.
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 en línea, sino comprender que el manejo de eventos se puede desacoplar por completo. Hemos separado HTML, CSS y JavaScript, pero no hemos avanzado mucho en la separación del manejo de eventos.
El controlador de eventos escuchará los cambios en los elementos del documento. Si hay un evento, el controlador encontrará un objeto mágico (generalmente un parámetro llamado e) que le dirá al elemento qué sucedió y qué se puede hacer con él.
Lo realmente interesante de la mayor parte del manejo de eventos es que ocurre no solo en el elemento al que desea acceder, sino en todos los elementos de nivel superior en el DOM (pero no en todos. Esto es cierto para los eventos, excepto el foco). y desenfocar eventos). Por ejemplo, al utilizar esta función, puede simplemente agregar un controlador de eventos a la 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 existe un elemento, pero no necesita verificar todos los elementos.
*Puedes agregar o eliminar nodos secundarios dinámicamente sin eliminar los controladores de eventos correspondientes.
*Puedes responder al mismo evento en diferentes elementos.
Otra cosa que debes recordar es que puedes detener un evento cuando se propaga a un elemento principal y puedes anular el comportamiento predeterminado de elementos HTML como los enlaces. Sin embargo, a veces esto no es una buena idea porque los navegadores dan estos comportamientos a los elementos HTML por una razón. Por ejemplo, los enlaces pueden apuntar a un destino en la página y dejarlos sin modificar garantiza que los usuarios puedan marcar el estado actual del script de la página.
Sea considerado
(espacios de nombres, ámbitos y esquemas)
Su código rara vez es el único código de secuencia de comandos en su documento. Por lo tanto, es especialmente importante asegurarse de que no haya funciones globales o variables globales en su código que puedan ser anuladas por otros scripts. Existen algunos patrones para evitar este problema. Lo más básico es inicializar todas las variables usando la palabra clave var. Supongamos que escribimos el siguiente script:
Código Java varnav = documento. getelementbyid('nav'); función init(){//hacer cosas} función show(){//hacer cosas} función reset(){//hacer cosas} var nav = document . init(){//hacer cosas} función show(){//hacer cosas} función reset(){//hacer cosas}
El código anterior contiene una variable global llamada nav y tres funciones llamadas init , mostrar y restablecer respectivamente. Estas funciones pueden acceder a la variable nav y pueden acceder entre sí a través del nombre de la función:
Código Java varnav = documento.
getelementbyid('nav'); function init(){ show(); if(nav . nombre de clase = = = ' show '){ reset() } // hacer cosas } function show(){ var c = nav . nombre de clase; // hacer cosas } función reset() { // hacer cosas } var nav = document . getelementbyid(' nav '); '){ reset();} // hacer cosas } función show(){ var c = nav nombre de clase; // hacer cosas } función reset(){ // hacer cosas }
Encapsulando. El código en objetos puede evitar la codificación global, de modo que las funciones se pueden convertir en métodos en el objeto y las variables globales se pueden convertir en propiedades en el objeto. Debe utilizar "nombre + dos puntos" para definir métodos y propiedades, y debe agregar una coma como separador después de cada propiedad o método.
Código Java varmyscript = { nav:document . getelementbyid(' nav '), init: function () {//dostuff}, show: function () {//dostuff}, reset:function() { // hacer cosas } } var myScript = { nav:document . getelementbyid(' nav '), init:function(){ // hacer cosas }, show:function(){ // hacer cosas }, reset:function( ){//hacer cosas } }
Se puede acceder a todos los métodos y propiedades externa e internamente a través del "nombre de clase + operador de punto".
Código Java varmyscript = { nav:document . getelementbyid(' nav '), init: function () { myscript . show (); if (myscript . nav . nombre de clase = = = ' show ') { myscript . reset(); } // hacer cosas }, show: function () { var c = myscript } var myScript = { nav:document . getelementbyid('nav '), init:function(){ myScript . show(); if(myscript . nav . nombre de clase = = = ' show '){ myscript } // hacer cosas }, show:function(){ var c = myscript . nav . // hacer cosas }, reset:function(){ // hacer cosas } }
Desventajas de este patrón Sí , cada vez que accede a otros métodos o propiedades desde un método, debe precederlo con el nombre del objeto, y todo lo que hay en el objeto es accesible externamente.
Si solo desea que parte del código sea accesible para otros scripts en el documento, considere el siguiente patrón de módulo:
Código Java var myScript = function(){ //Estos son métodos y propiedades privados varnav = documento. getelementbyid(' nav '); función init(){//hacer cosas } función show(){//hacer cosas } función reset(){//hacer cosas }//Los métodos y propiedades públicos están incluidos en declaraciones de devolución usando el objeto sintaxis en: return {public: function () {}, foo: ' bar ' }(); Var myScript = function(){ //Estos son métodos y propiedades privados Varnav = document. getElementByid(' nav '); Función init(){//hacer cosas } Función show(){//hacer cosas } Función reset(){//hacer cosas }/Los métodos y propiedades públicos están incluidos en la declaración de devolución usando el objeto syntax , return {public: function () {}, foo:' bar ' } }();
Puedes acceder a las propiedades y métodos públicos devueltos como en el código anterior, en este caso: myScript. public() y myScript.foo Pero aquí hay una pequeña incomodidad: cuando desea acceder a un método público desde el exterior o a un método privado desde el interior, aún debe escribir un nombre largo (el nombre del objeto puede ser). ser muy largo). Para evitar esto, debe definirlos como privados y devolver solo un alias en la declaración de devolución:
Código Java var myScript = function(){ //Estos son métodos y propiedades privados varnav = document. getelementbyid('nav'); function init(){ // hacer cosas } function show(){ // hacer cosas // hacer cosas } function reset(){//hacer cosas } var foo = ' bar '; (){ } var myscript = function(){//Estos son métodos y propiedades privados var nav = document. getelementbyid('nav'); function init(){ // hacer cosas } function show(){ // hacer cosas // hacer cosas } function reset(){//hacer cosas } var foo = ' bar '; (){ }
//Devuelve solo punteros a los métodos y propiedades privados a los que se accederá.
El código Java devuelve {public:public, foo:foo } }(); return { public:public, foo:foo } }()
Esto asegura que el estilo del código. es consistente Consistencia y puede 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:
Código Java (función(){//Estos son métodos y propiedades privados var nav = document.
getelementbyid(' nav '); función init() {//hacer cosas show(); // prefijo de nombre de clase} función show () {//dostuff} función reset () {//dostuff}}) () no aquí Requerido; (function(){ //Estos son métodos y propiedades privados var nav = document. getelementbyid('nav'); function init(){//hacer cosas show(); // prefijo de nombre de clase} function show () {//dostuff} la función reset () {//dostuff}})() no es necesaria aquí;
Este modo es muy adecuado para módulos de código que solo se ejecutan una vez y no dependen de otras funciones. .
Al seguir las reglas anteriores, su código puede servir mejor a los usuarios, funcionar mejor en la máquina y llevarse mejor con los códigos de otros desarrolladores. Sin embargo, hay otro grupo a considerar.
7. Piense en los desarrolladores que asumen el control.
(Facilita el mantenimiento)
El paso final para que su secuencia de comandos sea realmente discreta es volver a verificar su código después de haberlo escrito y ocuparse de lo que se hará cargo. una vez que su secuencia de comandos esté activa, desarrollador de código. Considere las siguientes preguntas:
*¿Son todos los nombres de variables y funciones razonables y comprensibles?
*¿Está bien organizado el código? ¿Fue fluido de principio a fin?
*¿Son obvias todas las dependencias?
*¿Están comentados aquellos lugares que pueden causar confusión?
Lo más importante a tener en cuenta es que es más probable que se cambie el código HTML y CSS del documento que el JavaScript (porque son responsables de los efectos visuales). Por lo tanto, no incluya clases ni ID en el código del script que el usuario final pueda ver, manténgalos separados y colóquelos en un objeto que almacene la información de configuración.
Código Java myscript = function(){ varconfig = { id de navegación:' nav ', Clase visible: ' show ' }; { show(); if(nav . nombre de clase = = = config . clase visible) { reset() }; // hacer cosas }; ;Función reset(){//hacer cosas };}();myscript = function(){ var config = { id de navegación:' nav ', clase visible: ' show ' }; var nav = document . ID de navegación); función init(){ show(); if(nav. nombre de clase = = = config. clase visible){ reset() };//hacer cosas }; nombre de clase; // hacer cosas }; función reset() { // hacer cosas };
De esta manera, los mantenedores saben dónde modificar estas propiedades sin tener que cambiar otro código.