2012-04-15 18 views
15

Estoy trabajando para crear una forma más semántica de verificar elementos con jQuery. Usando $("#element").length > 0 acaba realmente no se siente muy bien redactado para mí, así que estoy haciendo mi propio Además de selección para su uso en .is:¿Devuelve "verdadero" en la matriz de selección jQuery vacía?

if($("#element").is(":present")) { 
    console.log("It's aliiiveeee!!"); 
} 

Esa parte fue fácil, como esto:

$.extend($.expr[':'],{ 
    present: function(a) { 
     return $(a).length > 0; 
    } 
}); 

yo quiero ir un paso más allá, y que sea fácil de ver si un elemento no existe, utilizando una sintaxis similar:

$.extend($.expr[':'],{ 
    present: function(a) { 
     return $(a).length > 0; 
    }, 
    absent: function(a) { 
     return $(a).length === 0; 
    } 
}); 

$(function() { 
    if($("#element").is(":absent")) { 
    console.log("He's dead, Jim."); 
    } 
}); 

Pero esta parte es sorprendentemente difícil de hacer. Creo que es porque estoy recortando los elementos devueltos para obtener un resultado, y pelar el selector en .length === 0 es lo mismo que pedir ningún elemento: devuelve falso sin importar qué.

he intentado un montón de diferentes maneras de revertir las cosas y conseguir que esto devuelve true cuando el elemento no existe, y falso si no lo hace:

return $(a).length === 0; 

return !($(a).length > 0); 

if(!($(a).length > 0)) { 
    return true; 
} 

if($(a).length > 0) { 
    return false; 
} else { 
    return true; 
} 

return !!($(a).length === 0); 

// etc... 

¿Hay una manera fácil obtener esto para simplemente devolver verdadero si el elemento no existe, y falso si lo hace?

Respuesta

14

La definición de is:

Comprobar la corriente conjunto combinado de elementos contra un selector, elemento u objeto jQuery y devolver verdadero si al menos uno de estos elementos partidos los argumentos dados.

El problema es que ya que no tiene elementos, no es posible que uno de sus elementos coincida con alguna condición. jQuery ni siquiera está llamando a su código porque no hay elementos.

EDITAR: Para aclarar un poco, su código se llama una vez para cada elemento en su objeto (al menos hasta que uno devuelva verdadero). Sin elementos significa que el código nunca se llama. a en su código es siempre un solo elemento.

Edit2: Con esto en mente, esto sería una aplicación más eficiente de present:

$.extend($.expr[':'],{ 
    present: function(a) { 
     return true; 
    } 
}); 
+0

Entonces, '.is' en realidad no está diseñado para devolver verdadero cuando no existen elementos en el conjunto de selectores coincidentes? Otra opción que había considerado era simplemente usar: 'if ($ (" # element "). Is (": not (: present) ")) { console.log (" Está muerto, Jim ".); } ' Pero, curiosamente, eso tampoco funciona. –

+1

@Code Junkie: Nuevamente, no tiene ningún elemento para usar '.is()' con, por lo que esa función simplemente no se llamará. No importa qué selector le arrojes, ¡no pasará nada! – BoltClock

+0

¿Entonces puede que no haya forma de devolver verdadero en un resultado de selector vacío? –

1

0 es "falsy" en JavaScript.

Usted puede simplemente devolver !$(a).length.

+4

Si bien esto es cierto, se puede poner lo que quieras allí, el código no se ejecutará si no hay elementos. –

0

¿Qué tal:

if (!$(a)[0]) { 
    // $(a) is empty 
} 

Así, $(a)[0] recupera el primer elemento en el objeto jQuery. Si ese elemento es nulo/indefinido, eso significa que el objeto jQuery está vacío.

5

simplemente Puede usar

if(​$('element').length) // 1 or 0 will be returned 

o

$.extend($.expr[':'],{ 
    present: function(a) { 
     return $(a).length; 
    } 
}); 

if($('#element').is(':present')) 
{ 
    // code for existence 
} 
else 
{ 
    // code for non-existence 
} 

Example .

2

Dado que $().is() ni siquiera se ejecutará cuando la colección esté vacía, el selector :present es bastante superfluo. Así que en lugar de jugar con $.expr[':'], me gustaría ir con extender $.fn para contener la función apropiada, por ejemplo:

$.fn.extend({ 
    hasAny: function() { 
     return this.length > 0; 
    }, 
}); 

o

$.fn.extend({ 
    isEmpty: function() { 
     return this.length == 0; 
    }, 
}); 

La razón por la que personalmente ir con este enfoque es que los selectores son típicamente se utiliza para verificar las propiedades particulares de los elementos (comparar :checked, :enabled, :selected, :hover, etc.), no las propiedades del elemento jQuery establecido en conjunto (p. ej., .size(), .index()).

Uso Por supuesto, sería similar al siguiente:

if ($('#element').isEmpty()) 
    console.log("He's dead, Jim."); 
+0

Sí, esta es probablemente una forma mejor. Estaba jugando con todas las opciones, para ver cuál sería la mejor. Jugaré con este el próximo. ^^ –

Cuestiones relacionadas