ejemplos all javascript jquery api design api-design

javascript - all - parent().parent() jquery



Diseño de API y jQuery (4)

Incluido en jquery:

.post() .get() .getScript() .getJSON() .load()

No en jQuery:

$.getXML(); $.headXML(); $.postXML(); $.putXML(); $.traceXML(); $.deleteXML(); $.connectXML(); $.getJSON(); $.headJSON(); $.postJSON(); $.putJSON(); $.traceJSON(); $.deleteJSON(); $.connectJSON(); $.headScript(); $.postScript(); $.putScript(); $.traceScript(); $.deleteScript(); $.connectScript(); $.getHTML(); $.headHTML(); $.postHTML(); $.putHTML(); $.traceHTML(); $.deleteHTML(); $.connectHTML(); $.getText(); $.headText(); $.postText(); $.putText(); $.traceText(); $.deleteText(); $.connectText(); $.head(); $.put(); $.trace(); $.delete(); $.connect();

¿Por qué esto me molesta? No porque no tengamos los métodos anteriores en la biblioteca, eso es simplemente tonto y odiaría si alguna vez lo hiciéramos (además, la mayoría no funcionaría con los navegadores), pero lo que odio son estos métodos abreviados de todo el lugar: $.post(); Envía una solicitud de Ajax por correo.

¿Sabes lo que cubre todo en esta lista? La única función que no es short-hand, $.ajax , tiene todas las funciones y cubre todo, incluso puede configurarlo para almacenar valores predeterminados y, en esencia, crear todas estas manos cortas. Puede crear sus propios métodos si desea llamar a ajax (que es lo que hacen todos).

Aquí es donde realmente es realmente molesto.

Alguien escribe todo su código usando la taquigrafía:

$.getJSON( ''ajax/test.html'', function(data) { $(''.result'').html(data); } );

De acuerdo, espera, queremos cambiar eso a un feed XML que recibimos de una publicación, también tenemos que hacer que algo suceda antes y después de la publicación. Oh, vamos a cambiar al método de no mano corta

$.ajax({ type: ''POST'', url: url, data: data, success: success dataType: dataType });

Oh, espera, no puedo simplemente reemplazar la palabra, toda la estructura está por todos lados.

Esto, y especialmente para cosas como $ .load (), cruzan las líneas de por qué PHP tiene una API tan odiada, están tratando de hacer cosas que no deberían hacer.

Para extender esto más allá de las llamadas AJAX, mira la porción de animación. Tenemos llamadas a slideUp, slideDown, fadeIn, fadeOut, fadeToggle, show y hide. ¿Por qué? ¿Dónde queda mi diapositiva, deslizar hacia la derecha, deslizar hacia adentro, deslizar hacia afuera, teletransportarme y todo lo demás que podamos pensar? ¿Por qué no simplemente quedarse con $ .animate () y dejar que alguien escriba un complemento si queremos esos efectos? De hecho, alguien escribió un complemento, jQueryUI amplía las animaciones. Esto es simplemente una locura, y hace que las personas no sepan que algunos efectos crean reglas de CSS en sus divs que terminan por hacer lo que quieren hacer más adelante.

Manténgalo puro, manténgalo simple.

A menudo he escuchado que jQuery ha tomado algunas decisiones de API pobres. Aunque jQuery no es mi biblioteca favorita, es la biblioteca que he utilizado con más frecuencia y me resulta difícil señalar errores específicos en el diseño de la API o cómo se podría haber mejorado.

¿Qué partes de la API de jQuery se podrían haber hecho mejor, cómo se podría haber implementado diferente y por qué esa implementación diferente sería mejor?

La pregunta se extiende tanto a los detalles individuales de nivel bajo de la API como a los detalles de alto nivel de la API. Solo hablamos de fallas en la API en lugar de fallas en el diseño / propósito de alto nivel de la biblioteca, jQuery sigue siendo una biblioteca de manipulación de DOM centrada en un motor de selección.

Debido a la necesidad de la congelación de API en las bibliotecas populares, jQuery está atrapado en su estado actual y los desarrolladores están haciendo un gran trabajo. Como puede verse en el reciente cambio .attr vs .prop , los desarrolladores no tienen la flexibilidad para cambiar ninguna de sus decisiones de diseño (¡lo cual es una pena!).

Un ejemplo específico en el que puedo pensar sería

$.each(function(key, val) { })

vs

$.grep(function(val, key) { })

que es lo suficientemente confuso como para tener que verificar dos veces cuáles son los parámetros con frecuencia.

Por favor, no compare la biblioteca de jQuery con marcos completos como Dojo y YUI y no se queje de la falta de funciones.


La forma en que jQuery maneja las colecciones frente a los elementos individuales puede ser confusa.

Digamos que si actualizamos alguna propiedad CSS en una colección de elementos, podríamos escribir,

$(''p'').css(''background-color'', ''blue'');

El colocador actualizará el color de fondo de todos los elementos coincidentes. El captador, sin embargo, asume que solo está interesado en recuperar el valor del primer elemento.

$(''p'').css(''background-color'')

MooTools devolvería una matriz que contiene los colores de fondo de cada elemento coincidente, lo que parece más intuitivo.

Las convenciones de nomenclatura para jQuery promueven la concisión en lugar de la claridad. Me gusta la estrategia de Apple para nombrar cosas:

Es mejor ser claro que breve.

Y aquí hay un ejemplo de un nombre de método de una clase de matriz mutable ( NSMutableArray ) en Objective-C.

removeObjectAtIndex:(..)

No trata de ser inteligente acerca de lo que se elimina o de dónde se elimina. Toda la información que necesita saber está contenida en el nombre del método. Contraste esto con la mayoría de los métodos de jQuery como after e insertAfter .

Si alguien puede descubrir intuitivamente lo que after o insertAfter hacer sin leer los documentos o el código fuente, entonces esa persona es un genio. Desafortunadamente, no soy uno, y hasta la fecha, todavía tengo que ir a la documentación para averiguar qué diablos se coloca al usar estos dos métodos.


patrick dw golpeó la mayoría de los puntos en su (fantástica) respuesta. Solo para agregar a su colección con algunos otros ejemplos.

Se supone que una API es consistente; y jQuery tiene éxito en muchas áreas (siendo muy consistente para devolver un objeto jQuery / obtener valor, como se espera en muchos casos). En otras situaciones, sin embargo, no funciona tan bien.

Nombres de método Como ya lo señaló patrick; closest() es un nombre de método de mierda. prev() y next() aparecen a la mayoría como si hicieran el trabajo que prevAll() y nextAll() proporcionan en realidad.

delay() confunde a muchas personas: en el siguiente ejemplo, ¿qué espera que suceda? ( ¿Qué sucede en realidad? )

$(''#foo'').hide().delay(2000).slideDown().text(''Hello!'').delay(2000).hide();

Argumentos del método Muchas de las funciones de cruce de árbol son inconsistentes con lo que aceptan; todos aceptan una combinación de selectores, objetos jQuery y elementos, pero ninguno es consistente; lo cual es malo teniendo en cuenta que todos hacen trabajos similares. Consulte closest() , find() , siblings() , parents() , parent() y compare las diferencias.

Internamente, el "núcleo" de jQuery originalmente contenía muchos métodos entrelazados, que el equipo de desarrollo ha tenido problemas para dividirse (y hacerlo realmente bien) en los últimos lanzamientos. Los módulos internos como css, atributos, manipulación y desplazamiento solían agruparse en el mismo paquete grande.


  • .load() está sobrecargado con un comportamiento completamente diferente según los argumentos pasados

  • .toggle() está sobrecargado con un comportamiento completamente diferente según los argumentos pasados

  • demasiada sobrecarga de la función jQuery() tal vez.

  • el .attr() que mencionaste. La distinción de las propiedades debería haber sido inmediata OMI.

  • .map( key,val ) pero $.map( val,key ) , y this valores son diferentes.

  • los selectores no estándar deberían haberse mantenido fuera de Sizzle IMO. Los motores de selección basados ​​en Javascript deberían volverse obsoletos en varios años, y las personas conectadas a los selectores propietarios tendrán una transición más difícil.

  • método pobre de nombres de métodos como .closest() o .live() . ¿Qué es exactamente lo que hacen?

  • Recientemente descubrí que no puede establecer los atributos estándar de width y height través del argumento props al crear un elemento nuevo. jQuery ejecuta sus propios métodos de width y height lugar. OMI, los atributos de la especificación deberían tener prioridad, especialmente dado que el width y el height se pueden establecer a través de css .

$(''<img/>'', { css:{width:100, height:100}, width:100, // <-- calls method, why? height:100, // <-- calls method, why? });

  • $.get() y .get() son completamente diferentes.

  • .get() y .toArray() son idénticos al pasar sin argumentos

  • toArray() y $.makeArray() hacen efectivamente lo mismo. ¿Por qué no les dieron el mismo nombre como .each() y $.each() ?

  • dos métodos diferentes de delegación de eventos . .delegate() el sensible, y .live() el mágico "wow, ¡simplemente funciona!" uno.

  • .index() está sobrecargado con 3 comportamientos, pero sus diferencias pueden ser confusas

// v---get index v---from collection (siblings is implied) $(''selector'').index(); // v---from collection v---get index $(''selector'').index(element); // v---get index v---from collection $(''selector'').index(''selector'');

El primero es comprensible si recuerdas que solo opera en el primer elemento

El segundo tiene más sentido ya que los métodos jQuery generalmente operan en una colección completa.

El tercero es completamente confuso. El método no proporciona ninguna indicación de qué selector es la colección y qué selector representa el elemento cuyo índice desea de la colección.

¿Por qué no simplemente eliminar el tercero y que la gente use el segundo así?

// v---from collection v---get index $(''selector'').index( $(''selector'') );

De esta forma, se ajusta más al resto de jQuery donde .index() opera en toda la colección.

O al menos invertir el significado de los selectores para que quepan mejor:

// v---from collection v---get index $(''selector'').index(''selector'');

Aquí hay otro para pensar de todos modos.

Tengo algunas preocupaciones con el sistema de manejo de datos / manejo de eventos de jQuery. Se elogia porque no agrega funciones a propiedades de on[event] que pueden cerrarse alrededor de otros elementos, creando pérdidas de memoria en IE. En su lugar, coloca una propiedad de expansión ligera, que se correlaciona con una entrada en jQuery.cache , que contiene controladores y otros datos.

Creo que luego conecta a un controlador que a su vez invoca el controlador que asignó. O algo así.

Cualquiera sea el sistema, realmente no importa. El punto es que la conexión entre el (los) elemento (s) y el jQuery.cache es esa expansión.

¿Por qué es eso un gran problema? Bueno, filosóficamente jQuery no es un marco; es una biblioteca Parecería que, como biblioteca, debería poder utilizar o no las funciones jQuery sin preocuparse por los efectos negativos. Sin embargo, si sale de jQuery al eliminar elementos del DOM, ha dejado huérfanos a los manejadores y otros datos asociados con esos elementos a través de expando, creando una buena y completa fuga de memoria entre navegadores.

Entonces, por ejemplo, algo tan simple como el.innerHTML = '''' podría ser muy peligroso.

jQuery.noConflict() esto con la característica jQuery.noConflict() . Esto permite a los desarrolladores utilizar jQuery con otras bibliotecas que utilizan el espacio de nombres $ global. ¿Y qué pasa si una de esas bibliotecas elimina algunos elementos? El mismo problema. Tengo la sensación de que el desarrollador que necesita usar una biblioteca como Prototypejs junto con jQuery probablemente no sepa suficiente JavaScript para tomar buenas decisiones de diseño, y estará sujeto a un problema tal como lo describí.

En términos de mejoras dentro de la filosofía de la biblioteca, hasta donde yo sé, su filosofía es "Hacer más, escribir menos" o algo así. Creo que lo logran muy bien. Puede escribir un código muy conciso pero expresivo que hará una enorme cantidad de trabajo.

Si bien esto es muy bueno, de alguna manera lo pienso como algo negativo. Puedes hacer mucho, tan fácilmente, que es muy fácil para los principiantes escribir un código muy malo. Sería bueno, creo, que si hubiera una "compilación de desarrollador" registrara las advertencias de mal uso de la biblioteca.

Un ejemplo común es ejecutar un selector en un bucle. La selección DOM es muy fácil de hacer, parece que puede ejecutar un selector cada vez que necesita un elemento, incluso si acaba de ejecutar ese selector. Una mejora que creo que sería para la función jQuery() registrar los usos repetidos de un selector, y dar a una nota de la consola que un selector puede ser almacenado en caché.

Debido a que jQuery es tan dominante, creo que sería bueno si no solo facilitaran ser un programador de JavaScript / DOM, sino que también lo ayudaran a ser uno mejor.