2011-11-18 22 views
8

La firma de la función jQuery .on esambigüedad en la interpretación de parámetros opcionales

$ (elementos) .ON (eventos [, selectores] [, datos], handler);

donde selector y son opcionales. Por lo tanto, la función llama a

$ (elementos) .on (var1, var2, var3);

podría interpretarse con var2 ya sea como selector o como data. ¿Hay ambigüedad?

Más en general, ¿cómo se trata la ambigüedad de los parámetros opcionales para cualquier otra función de jQuery?

+2

+1 a menudo me he preguntado esto. – jondavidjohn

Respuesta

4

Si sólo uno de los parámetros de selección de datos y se proporciona y el valor es una cadena de caracteres que se supone que es un selector.

Desde el jQuery doco for .on():

El argumento de datos puede ser de cualquier tipo, pero si se utiliza una cadena del selector o bien debe ser proporcionada o explícitamente pasado como nulo por lo que los datos no se confunde con un selector. La mejor práctica es usar un objeto (mapa) para que se puedan pasar múltiples valores como propiedades.

Un principio similar se aplica a otros métodos jQuery con parámetros opcionales.

1

Selector es una cadena y da un objeto de datos. La prueba debería ser algo así como

if (typeof var2 === 'string') { 
    // var2 is selector 
} else { 
    // var2 is data 
} 

Editar, la fuente real de jQuery https://github.com/jquery/jquery/blob/master/src/event.js

on: function(types, selector, data, fn, /*INTERNAL*/ one) { 
    var origFn, type; 

    // Types can be a map of types/handlers 
    if (typeof types === "object") { 
     // (types-Object, selector, data) 
     if (typeof selector !== "string") { 
      // (types-Object, data) 
      data = selector; 
      selector = undefined; 
     } 
     for (type in types) { 
      this.on(type, selector, data, types[ type ], one); 
     } 
     return this; 
    } 
1

Para el ejemplo que proporcionó, los argumentos selector y data esperan diferentes tipos de objetos. El argumento selector debe ser una Cadena, y data debe ser un Objeto. Se pueden diferenciar entre usar el operador typeof. Por ejemplo:

if(typeof selector === "string") { 
    //We know that the 2nd argument is actually a selector string 
} 

Tenga en cuenta que si hacía falta para pasar una cadena en on como argumento data, el argumento selector tendría que especificarse también (incluso si sólo pasa en null).

1

Aquí hay un poco de la fuente de jquery. Básicamente, están buscando los tipos de parámetros y asignándolos a otros parámetros según sea necesario. Por ejemplo, si el elemento en la posición "selector" en la lista de parámetros no es una cadena, suponen que se suponía que era el parámetro "datos", y así sucesivamente.

on: function(types, selector, data, fn, /*INTERNAL*/ one) { 
    var origFn, type; 

    // Types can be a map of types/handlers 
    if (typeof types === "object") { 
     // (types-Object, selector, data) 
     if (typeof selector !== "string") { 
      // (types-Object, data) 
      data = selector; 
      selector = undefined; 
     } 
     for (type in types) { 
      this.on(type, selector, data, types[ type ], one); 
     } 
     return this; 
    } 

    if (data == null && fn == null) { 
     // (types, fn) 
     fn = selector; 
     data = selector = undefined; 
    } else if (fn == null) { 
     if (typeof selector === "string") { 
      // (types, selector, fn) 
      fn = data; 
      data = undefined; 
     } else { 
      // (types, data, fn) 
      fn = data; 
      data = selector; 
      selector = undefined; 
     } 
    } 
1

Tengo mis propios reparos con .on() también ...

El contexto de this siempre fue muy claro con delegate vs bind (o cualquier atajo de enlace). Ahora con on, el contexto puede cambiar muy pronto ...

Por ejemplo,

//This is pretty clear, you now want to turn the paragraph tag red when clicked 
$('p').on('click', function() { 
    $(this).css('color', 'red'); 
}); 

//Woah... so the context of `this` just changed by a single argument 
//this now refers to all anchor tags that are descendants of paragraph tags. 
$('p').on('click', 'a', function() { 
    $(this).css('color', 'red'); 
}); 

Este es el primer método jQuery nunca para cambiar el contexto de this simplemente pasando un argumento diferente.

hecho de rápida - delegate - (1.4.2) fue el primer método que no utilice el selector para representar el contexto de la función de devolución de llamada. Pero al menos todavía estaba claro ... cuando ves .delegate() entiendes lo que está sucediendo.

+0

'this' se aplica al elemento especificado, como dijiste: el elemento a en tu segundo ejemplo. ¿Por qué es eso una sorpresa? En cualquier caso, esto es completamente fuera de tema. – nnnnnn

+0

@nnnnnn La ambigüedad de on() está fuera de tema? –

+0

Sí. La pregunta es cómo se interpretan los parámetros opcionales, para on() específicamente y otras funciones jQuery en general. El punto que planteas sobre() vale la pena discutirlo por sí mismo, pero no se relaciona con la forma en que jQuery resuelve los parámetros opcionales. (No te preocupes, no perdoné ni nada). – nnnnnn

Cuestiones relacionadas