validacion - validar formulario javascript onclick




Mejores prácticas comúnmente aceptadas sobre la organización de código en JavaScript (19)

"¿Escribe como loco y solo espero que funcione de la mejor manera?", He visto un proyecto como este que fue desarrollado y mantenido por solo 2 desarrolladores, una gran aplicación con un montón de código javascript. Además de eso, había diferentes accesos directos para cada posible función de jQuery que puedas imaginar. Sugerí que organizaran el código como complementos, ya que es el equivalente de jquery de clase, módulo, espacio de nombres ... y todo el universo. Pero las cosas empeoraron, ahora comenzaron a escribir complementos que reemplazaban cada combinación de 3 líneas de código utilizadas en el proyecto. Personalmente, creo que jQuery es el demonio y no debería usarse en proyectos con muchos javascript porque te anima a ser perezoso ya no pensar en organizar código de ninguna manera. Prefiero leer 100 líneas de javascript que una línea con 40 funciones jQuery encadenadas (no estoy bromeando). Contrariamente a la creencia popular, es muy fácil organizar el código javascript en equivalentes a los espacios de nombres y las clases. Eso es lo que hacen YUI y Dojo. Usted puede rodar fácilmente su propio si lo desea. Encuentro el enfoque de YUI mucho mejor y eficiente. Pero normalmente necesitas un buen editor con soporte para fragmentos para compensar las convenciones de nomenclatura YUI si quieres escribir algo útil.

A medida que los marcos de JavaScript como jQuery hacen que las aplicaciones web del lado del cliente sean más ricas y más funcionales, comencé a notar un problema ...

¿Cómo en el mundo mantienes esto organizado?

  • ¿Poner todos los manejadores en un solo lugar y escribir funciones para todos los eventos?
  • ¿Crear funciones / clases para envolver todas tus funcionalidades?
  • Escribe como un loco y solo espero que funcione para lo mejor?
  • ¿Te rindes y consigues una nueva carrera?

Menciono jQuery, pero en realidad es cualquier código JavaScript en general. Estoy encontrando que a medida que las líneas sobre líneas comienzan a acumularse, se vuelve más difícil administrar los archivos de script o encontrar lo que está buscando. Posiblemente los problemas más grandes que he encontrado es que hay muchas maneras de hacer lo mismo, es difícil saber cuál es la mejor práctica aceptada actualmente.

¿Hay recomendaciones generales sobre la mejor manera de mantener sus archivos .js tan agradables y ordenados como el resto de su aplicación? ¿O es solo una cuestión de IDE? ¿Hay una mejor opción por ahí?

EDITAR

Esta pregunta pretendía ser más sobre la organización del código y no sobre la organización de archivos. Ha habido algunos ejemplos realmente buenos de fusión de archivos o división de contenido.

Mi pregunta es: ¿cuál es la mejor práctica actual comúnmente aceptada para organizar su código real? ¿Cuál es su manera, o incluso una forma recomendada de interactuar con los elementos de la página y crear un código reutilizable que no entre en conflicto?

Algunas personas han enumerado los espacios de nombres, lo que es una buena idea. ¿Cuáles son algunas otras formas, más específicamente tratando con los elementos en la página y manteniendo el código organizado y ordenado?


¡Mi jefe aún habla de los tiempos en que escribieron el código modular (lenguaje C), y se queja de cuán malo es el código hoy en día! Se dice que los programadores pueden escribir ensamblajes en cualquier framework. Siempre hay una estrategia para superar la organización del código. El problema básico es con los chicos que tratan el java script como un juguete y nunca intentan aprenderlo.

En mi caso, escribo archivos js sobre una base de pantalla de aplicación o tema de UI, con un init_screen () adecuado. Al utilizar la convención de nomenclatura de ID adecuada, me aseguro de que no haya conflictos de espacio de nombres en el nivel del elemento raíz. En el window.load () no intrusivo, até las cosas en función del ID de nivel superior.

Uso estrictamente los cierres y patrones de guiones java para ocultar todos los métodos privados. Después de hacer esto, nunca enfrentó un problema de propiedades en conflicto / definiciones de funciones / definiciones de variables. Sin embargo, cuando se trabaja con un equipo, a menudo es difícil imponer el mismo rigor.


Creo que esto se relaciona, quizás, con DDD (Diseño impulsado por dominio). La aplicación en la que estoy trabajando, a pesar de que carece de una API formal, da pistas de este tipo a través del código del lado del servidor (nombres de clase / archivo, etc.). Armado con eso, creé un objeto de nivel superior como un contenedor para todo el dominio del problema; Luego, agregué espacios de nombres donde sea necesario:

var App;
(function()
{
    App = new Domain( 'test' );

    function Domain( id )
    {
        this.id = id;
        this.echo = function echo( s )
        {
            alert( s );
        }
        return this;
    }
})();

// separate file
(function(Domain)
{
    Domain.Console = new Console();

    function Console()
    {
        this.Log = function Log( s )
        {
            console.log( s );
        }
        return this;
    }
})(App);

// implementation
App.Console.Log('foo');

Creo singletons para cada cosa que realmente no necesito para crear instancias varias veces en la pantalla, una clase para todo lo demás. Y todos ellos se ponen en el mismo espacio de nombres en el mismo archivo. Todo está comentado, y diseñado con UML, diagramas de estado. El código de javascript está libre de html, por lo que no hay javascript en línea y tiendo a usar jquery para minimizar los problemas entre navegadores.


Echa un vistazo a JavasciptMVC .

Usted puede :

  • Divide tu código en capas de modelo, vista y controlador.

  • Comprimir todo el código en un solo archivo de producción

  • generar código automáticamente

  • crear y ejecutar pruebas unitarias

  • y mucho mas ...

Lo mejor de todo es que utiliza jQuery, por lo que también puede aprovechar otros complementos de jQuery.


En mi último proyecto -Viajeros.com- he usado una combinación de varias técnicas. No sabría cómo organizar una aplicación web. Viajeros es un sitio de redes sociales para viajeros con secciones bien definidas, por lo que es fácil separar el código de cada área.

Utilizo la simulación de espacio de nombres y la carga lenta de módulos de acuerdo con la sección del sitio. En cada carga de página declaro un objeto "vjr" y siempre le cargué un conjunto de funciones comunes (vjr.base.js). Luego, cada página HTML decide qué módulos necesitan con un simple:

vjr.Required = ["vjr.gallery", "vjr.comments", "vjr.favorites"];

Vjr.base.js obtiene cada uno de los archivos comprimidos desde el servidor y los ejecuta.

vjr.include(vjr.Required);
vjr.include = function(moduleList) {
  if (!moduleList) return false;
  for (var i = 0; i < moduleList.length; i++) {
    if (moduleList[i]) {
      $.ajax({
        type: "GET", url: vjr.module2fileName(moduleList[i]), dataType: "script"
      });
    }
  }
};

Cada "módulo" tiene esta estructura:

vjr.comments = {}

vjr.comments.submitComment = function() { // do stuff }
vjr.comments.validateComment = function() { // do stuff }

// Handlers
vjr.comments.setUpUI = function() {
    // Assign handlers to screen elements
}

vjr.comments.init = function () {
  // initialize stuff
    vjr.comments.setUpUI();
}

$(document).ready(vjr.comments.init);

Dado mi conocimiento limitado de Javascript, sé que debe haber mejores formas de gestionar esto, pero hasta ahora está funcionando muy bien para nosotros.


Inspirado en publicaciones anteriores, hice una copia de los directorios de Rakefile y proveedores distribuidos con WysiHat (un RTE mencionado por changelog) e hice algunas modificaciones para incluir la verificación de JSLint con JSLint y la JSLint con YUI Compressor .

La idea es usar Sprockets (de WysiHat) para combinar varios JavaScripts en un archivo, verificar la sintaxis del archivo combinado con JSLint y minimizarlo con YUI Compressor antes de la distribución.

Prerrequisitos

  • Java Runtime
  • gema de rubí y rastrillo
  • Debes saber cómo poner un JAR en Classpath

Ahora haz

  1. Descarga Rhino y coloca el JAR ("js.jar") en tu classpath
  2. Descarga YUI Compressor y coloca el JAR (build / yuicompressor-xyz.jar) en tu classpath
  3. Descargue WysiHat y copie el directorio "proveedor" en la raíz de su proyecto JavaScript
  4. Descargue JSLint for Rhino y colóquelo en el directorio "proveedor"

Ahora cree un archivo llamado "Rakefile" en el directorio raíz del proyecto JavaScript y agregue el siguiente contenido:

require 'rake'

ROOT            = File.expand_path(File.dirname(__FILE__))
OUTPUT_MERGED   = "final.js"
OUTPUT_MINIFIED = "final.min.js"

task :default => :check

desc "Merges the JavaScript sources."
task :merge do
  require File.join(ROOT, "vendor", "sprockets")

  environment  = Sprockets::Environment.new(".")
  preprocessor = Sprockets::Preprocessor.new(environment)

  %w(main.js).each do |filename|
    pathname = environment.find(filename)
    preprocessor.require(pathname.source_file)
  end

  output = preprocessor.output_file
  File.open(File.join(ROOT, OUTPUT_MERGED), 'w') { |f| f.write(output) }
end

desc "Check the JavaScript source with JSLint."
task :check => [:merge] do
  jslint_path = File.join(ROOT, "vendor", "jslint.js")

  sh 'java', 'org.mozilla.javascript.tools.shell.Main',
    jslint_path, OUTPUT_MERGED
end

desc "Minifies the JavaScript source."
task :minify => [:merge] do
  sh 'java', 'com.yahoo.platform.yui.compressor.Bootstrap', '-v',
    OUTPUT_MERGED, '-o', OUTPUT_MINIFIED
end

Si hizo todo correctamente, debería poder usar los siguientes comandos en su consola:

  • rake merge - para combinar diferentes archivos JavaScript en uno
  • rake check : para verificar la sintaxis de su código (esta es la tarea predeterminada , así que simplemente puede escribir rake )
  • rake minify - para preparar la versión reducida de su código JS

En la fusión de la fuente

Usando Sprockets, el preprocesador de JavaScript puede incluir (o require ) otros archivos JavaScript. Use la siguiente sintaxis para incluir otros scripts del archivo inicial (llamado "main.js", pero puede cambiar eso en el Rakefile):

(function() {
//= require "subdir/jsfile.js"
//= require "anotherfile.js"

    // some code that depends on included files
    // note that all included files can be in the same private scope
})();

Y entonces...

Eche un vistazo a Rakefile proporcionado con WysiHat para configurar la prueba de la unidad automatizada. Lindas cosas :)

Y ahora la respuesta.

Esto no responde muy bien a la pregunta original. Lo sé y lo lamento, pero lo he publicado aquí porque espero que pueda ser útil para alguien más organizar su desorden.

Mi enfoque del problema es hacer todo el modelado orientado a objetos que pueda y separar las implementaciones en diferentes archivos. Entonces los manejadores deben ser lo más cortos posible. El ejemplo con List singleton también es bueno.

Y los espacios de nombres ... bueno, pueden ser imitados por una estructura de objeto más profunda.

if (typeof org === 'undefined') {
    var org = {};
}

if (!org.hasOwnProperty('example')) {
    org.example = {};
}

org.example.AnotherObject = function () {
    // constructor body
};

No soy un gran fanático de las imitaciones, pero esto puede ser útil si tiene muchos objetos que le gustaría salir del ámbito global.


Intento evitar incluir cualquier javascript con el HTML. Todo el código está encapsulado en clases y cada clase está en su propio archivo. Para el desarrollo, tengo etiquetas <script> separadas para incluir cada archivo js, ​​pero se fusionan en un solo paquete más grande para la producción para reducir la sobrecarga de las solicitudes HTTP.

Normalmente, tendré un solo archivo js 'principal' para cada aplicación. Entonces, si estuviera escribiendo una aplicación de "encuesta", tendría un archivo js llamado "survey.js". Esto contendría el punto de entrada en el código jQuery. Creo referencias de jQuery durante la creación de instancias y luego las paso a mis objetos como parámetros. Esto significa que las clases de javascript son "puras" y no contienen ninguna referencia a los identificadores de CSS o los nombres de clase.

// file: survey.js
$(document).ready(function() {
  var jS = $('#surveycontainer');
  var jB = $('#dimscreencontainer');
  var d = new DimScreen({container: jB});
  var s = new Survey({container: jS, DimScreen: d});
  s.show();
});

También me parece que la convención de nombres es importante para la legibilidad. Por ejemplo: antepongo 'j' a todas las instancias de jQuery.

En el ejemplo anterior, hay una clase llamada DimScreen. (Suponga que esto oscurece la pantalla y aparece un cuadro de alerta). Necesita un elemento div que pueda ampliar para cubrir la pantalla, y luego agrega un cuadro de alerta, por lo que paso un objeto jQuery. jQuery tiene un concepto de plug-in, pero parecía limitante (por ejemplo, las instancias no son persistentes y no se puede acceder a ellas) sin una ventaja real. Así que la clase DimScreen sería una clase estándar de javascript que simplemente usa jQuery.

// file: dimscreen.js
function DimScreen(opts) { 
   this.jB = opts.container;
   // ...
}; // need the semi-colon for minimizing!


DimScreen.prototype.draw = function(msg) {
  var me = this;
  me.jB.addClass('fullscreen').append('<div>'+msg+'</div>');
  //...
};

He construido algunas aplicaciones bastante complejas utilizando este enfoque.


Me sorprende que nadie mencione los marcos MVC. He estado usando Backbone.js para modularizar y desacoplar mi código, y ha sido invaluable.

Hay bastantes de estos tipos de marcos por ahí, y la mayoría de ellos también son bastante pequeños. Mi opinión personal es que si va a escribir más que solo un par de líneas de jQuery para cosas llamativas de la interfaz de usuario, o si desea una aplicación rica de Ajax, un marco MVC hará su vida mucho más fácil.


Organizar su código en un modo de espacio de nombres centrado en Jquery puede tener el siguiente aspecto ... y no coincidirá con otras API de Javascript como Prototype, Ext tampoco.

<script src="jquery/1.3.2/jquery.js" type="text/javascript"></script>
<script type="text/javascript">

var AcmeJQ = jQuery.noConflict(true);
var Acme = {fn: function(){}};

(function($){

    Acme.sayHi = function()
    {
        console.log('Hello');
    };

    Acme.sayBye = function()
    {
        console.log('Good Bye');
    };
})(AcmeJQ);

// Usage
//          Acme.sayHi();
// or
// <a href="#" onclick="Acme.sayHi();">Say Hello</a>


</script>

Espero que esto ayude.


Pude aplicar con éxito el patrón del módulo de Javascript a una aplicación Ext JS en mi trabajo anterior. Proporcionó una forma sencilla de crear código bien encapsulado.


Puede dividir sus scripts en archivos separados para el desarrollo, luego crear una versión de "lanzamiento" donde los coloque a todos juntos y ejecute YUI Compressor o algo similar en él.


Sería mucho mejor si javascript tuviera espacios de nombres integrados, pero me parece que organizar cosas como las que Dustin Díaz describe here me ayuda mucho.

var DED = (function() {

    var private_var;

    function private_method()
    {
        // do stuff here
    }

    return {
        method_1 : function()
            {
                // do stuff here
            },
        method_2 : function()
            {
                // do stuff here
            }
    };
})();

Puse diferentes "espacios de nombres" y, a veces, clases individuales en archivos separados. Por lo general, comienzo con un archivo y como una clase o espacio de nombres se vuelve lo suficientemente grande como para justificarlo, lo separo en su propio archivo. Usar una herramienta para combinar todos sus archivos para la producción también es una excelente idea.


Un buen director de OO + MVC definitivamente ayudaría a administrar una aplicación javascript compleja.

Básicamente, estoy organizando mi aplicación y javascript para el siguiente diseño familiar (que existe desde los días de programación de mi escritorio hasta la Web 2.0)

Descripción de los valores numéricos en la imagen:

  1. Widgets que representan las vistas de mi aplicación. Esto debería ser extensible y separado de manera clara, lo que resultaría en una buena separación que MVC intenta lograr en lugar de convertir mi widget en un código spaghetti (equivalente en la aplicación web de poner un gran bloque de Javascript directamente en HTML). Cada widget se comunica a través de otros al escuchar el evento generado por otros widgets, lo que reduce el fuerte acoplamiento entre los widgets que podrían generar un código inmanejable (¿recuerda el día de agregar onclick en todas partes que apunta a funciones globales en la etiqueta de script? Urgh ...)
  2. Modelos de objetos que representan los datos que quiero llenar en los widgets y que van y vienen al servidor. Al encapsular los datos a su modelo, la aplicación se convierte en agnósticos del formato de datos. Por ejemplo: si bien, naturalmente, en Javascript, estos modelos de objetos están en su mayoría serializados y deserializados en JSON, si de alguna manera el servidor utiliza XML para la comunicación, todo lo que debo cambiar es cambiar la capa de serialización / deserialización y no necesariamente tiene que cambiar todas las clases de widgets. .
  3. Clases de controlador que administran la lógica de negocios y la comunicación con el servidor +, ocasionalmente, la capa de caché Esta capa controla el protocolo de comunicación al servidor y coloca los datos necesarios en los modelos de objetos.
  4. Las clases están envueltas cuidadosamente en sus espacios de nombres correspondientes. Estoy seguro de que todos sabemos lo desagradable que puede ser el espacio de nombres global en Javascript.

En el pasado, separaba los archivos en sus propios js y usaba la práctica común para crear principios OO en Javascript. El problema que pronto descubrí es que hay varias formas de escribir JS OO y no es necesariamente que todos los miembros del equipo tengan el mismo enfoque. A medida que el equipo se hizo más grande (en mi caso, más de 15 personas), esto se complica ya que no hay un enfoque estándar para Javascript orientado a objetos. Al mismo tiempo, no quiero escribir mi propio marco y repetir algunos de los trabajos que estoy seguro que son personas más inteligentes que las que he resuelto.

jQuery es increíblemente bueno como Javascript Framework y me encanta, sin embargo, a medida que el proyecto crece, claramente necesito una estructura adicional para mi aplicación web, especialmente para facilitar la estandarización de la práctica de OO. Por mi parte, después de varios experimentos, encuentro que YUI3 Base and Widget ( http://yuilibrary.com/yui/docs/widget/ y http://yuilibrary.com/yui/docs/base/index.html ) proporciona la infraestructura exactamente lo que necesito. Pocas razones por las que los uso.

  1. Proporciona soporte de espacio de nombres. Una necesidad real de OO y una organización ordenada de su código.
  2. Apoya la noción de clases y objetos.
  3. Proporciona un medio de estandarización para agregar variables de instancia a su clase.
  4. Es compatible con la extensión de clase perfectamente
  5. Proporciona constructor y destructor.
  6. Proporciona render y enlace de eventos.
  7. Tiene un framework base de widgets.
  8. Cada widget ahora puede comunicarse entre sí mediante un modelo estándar basado en eventos
  9. Lo más importante es que le da a todos los ingenieros un estándar OO para el desarrollo de Javascript

Contrariamente a muchas vistas, no necesariamente tengo que elegir entre jQuery y YUI3. Estos dos pueden coexistir pacíficamente. Si bien YUI3 proporciona la plantilla OO necesaria para mi aplicación web compleja, jQuery aún le brinda a mi equipo una abstracción JS fácil de usar con la que todos nos enamoramos y estamos familiarizados.

Usando YUI3, he logrado crear un patrón MVC al separar las clases que extienden la Base como el Modelo, las clases que extienden el Widget como una Vista y, por supuesto, tiene clases de Controladores que están haciendo las llamadas necesarias de la lógica y del servidor.

Widget puede comunicarse entre sí utilizando un modelo basado en eventos y escuchando el evento y haciendo la tarea necesaria basada en una interfaz predefinida. En pocas palabras, poner la estructura de OO + MVC en JS es una alegría para mí.

Solo un descargo de responsabilidad, no trabajo para Yahoo! y simplemente un arquitecto que está tratando de hacer frente al mismo problema que plantea la pregunta original. Creo que si alguien encuentra un marco OO equivalente, esto también funcionaría. Principalmente, esta pregunta se aplica a otras tecnologías también. Gracias a Dios por todas las personas que crearon OO Principles + MVC para hacer que nuestros días de programación sean más manejables.



Estoy usando esta cosita. Te da la directiva 'include' para plantillas JS y HTML. Elimina el desorden por completo.

https://github.com/gaperton/include.js/

$.include({
    html: "my_template.html" // include template from file...
})
.define( function( _ ){ // define module...
    _.exports = function widget( $this, a_data, a_events ){ // exporting function...
        _.html.renderTo( $this, a_data ); // which expands template inside of $this.

        $this.find( "#ok").click( a_events.on_click ); // throw event up to the caller...
        $this.find( "#refresh").click( function(){
            widget( $this, a_data, a_events ); // ...and update ourself. Yep, in that easy way.
        });
    }
});

No mencionas cuál es tu lenguaje de servidor. O, de manera más pertinente, qué marco está utilizando, si lo tiene, en el lado del servidor.

IME, organizo las cosas en el lado del servidor y dejo que todo se agite en la página web. Al marco se le asigna la tarea de organizar no solo JS que cada página debe cargar, sino también fragmentos JS que funcionan con el marcado generado. Tales fragmentos que normalmente no desea emitir más de una vez, es por eso que se abstraen en el marco para que ese código se ocupe de ese problema. :-)

Para las páginas finales que tienen que emitir su propio JS, generalmente encuentro que hay una estructura lógica en el marcado generado. Dicha JS localizada a menudo se puede ensamblar al principio y / o al final de dicha estructura.

Tenga en cuenta que nada de esto le exime de escribir JavaScript eficiente. :-)


Puede usar jquery mx (usado en javascriptMVC), que es un conjunto de scripts que le permite usar modelos, vistas y controladores. Lo usé en un proyecto y me ayudó a crear javascript estructurado, con tamaños de script mínimos debido a la compresión. Este es un ejemplo de controlador:

$.Controller.extend('Todos',{
  ".todo mouseover" : function( el, ev ) {
   el.css("backgroundColor","red")
  },
  ".todo mouseout" : function( el, ev ) {
   el.css("backgroundColor","")
  },
  ".create click" : function() {
   this.find("ol").append("<li class='todo'>New Todo</li>"); 
  }
})

new Todos($('#todos'));

También puede usar solo el lado del controlador de jquerymx si no está interesado en la vista y las partes del modelo.


Utilizo un script personalizado inspirado en el comportamiento de Ben Nolan (lamentablemente, no puedo encontrar un enlace actual a esto) para almacenar la mayoría de los controladores de eventos. Estos controladores de eventos son activados por los elementos className o Id, por ejemplo. Ejemplo:

Behaviour.register({ 
    'a.delete-post': function(element) {
        element.observe('click', function(event) { ... });
    },

    'a.anotherlink': function(element) {
        element.observe('click', function(event) { ... });
    }

});

Me gusta incluir la mayoría de mis bibliotecas de Javascript sobre la marcha, excepto las que contienen un comportamiento global. Utilizo el marcador de posición headScript () de Zend Framework para esto, pero también puede usar javascript para cargar otros scripts sobre la marcha con Ajile por ejemplo.





formatting