name - ¿Por qué mi selector JQuery está devolviendo un n.fn.init[0], y qué es?
selectores jquery avanzados (5)
Tengo un conjunto de casillas de verificación generadas dinámicamente, donde cada una de ellas tiene un atributo de data-id
correspondiente a una id de entero de la base de datos. Cuando relleno mi formulario html con un objeto para editar, hay una lista de enteros que representan las casillas de verificación que se deben marcar. Las casillas de verificación están envueltas en un div
con la clase checkbox-wrapper
.
Así html se ve así:
<div class="checkbox-wrapper">
<input type="checkbox" id="checkbox1" data-id="1">
<label for="checkbox1">Checkbox 1</label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" id="checkbox2" data-id="2">
<label for="checkbox2">Checkbox 2</label>
</div>
<div class="checkbox-wrapper">
<input type="checkbox" id="checkbox3" data-id="99">
<label for="checkbox3">Checkbox 99</label>
</div>
Tenga en cuenta que la identificación se ejecuta en los números de índice de incremento automático, mientras que la identificación de datos puede tener un valor de identificación diferente. Quiero seleccionarlos por ID de datos.
Ahora, utilizando JQuery, sé que puedo seleccionar las casillas de verificación relevantes como esta:
$(".checkbox-wrapper>input[data-id=''99'']");
$(".checkbox-wrapper>input[data-id=''1'']");
Esto funciona en mi consola, en chrome, y devuelve el elemento DOM relevante. Del mismo modo, a continuación, establece las casillas de verificación marcadas:
$(".checkbox-wrapper>input[data-id=''99'']").prop("checked", "checked");
$(".checkbox-wrapper>input[data-id=''1'']").prop("checked", "checked");
Sin embargo, si itero a través de una lista de enteros en mi código javascript (no directamente en la consola), y registro los elementos devueltos, en función de los valores de identificación, obtengo algunos resultados extraños:
var ids = [1,2]
$.each(ids, function(index, myID){
console.log($(".checkbox-wrapper>input[data-id=''"+myID+"'']"));
$(".checkbox-wrapper>input[data-id=''"+myID+"'']").prop("checked", "checked");
});
En primer lugar, no se marcan las casillas de verificación. En segundo lugar, mi consola imprime resultados extraños:
n.fn.init[0]
context: document
length: 0
prevObject: n.fn.init[1]
selector: ".checkbox-wrapper>input[data-id=''1'']"
__proto__: n[0]
n.fn.init[0]
context: document
length: 0
prevObject: n.fn.init[1]
selector: ".checkbox-wrapper>input[data-id=''2'']"
__proto__: n[0]
El selector impreso Strings parece perfecto. Los mismos selectores exactos devuelven los elementos DOM, cuando se escriben directamente en la consola chrome. Luego devuelven objetos como este:
[<input type="checkbox" id="checkbox1" data-id="1">]
¿Qué es el n.fn.init [0] y por qué se devuelve? ¿Por qué mis dos funciones JQuery aparentemente idénticas están devolviendo cosas diferentes?
Aquí se muestra cómo realizar una comprobación rápida para ver si n.fn.init[0]
se debe a que los elementos DOM no se cargan a tiempo. Retrase la función de selección envolviéndola en la función setTimeout
esta manera:
function timeout(){
...your selector function that returns n.fn.init[0] goes here...
}
setTimeout(timeout, 5000)
Esto hará que la función de selección se ejecute con un retraso de 5 segundos, lo que debería ser suficiente para cargar casi cualquier cosa.
Esto es solo un truco para comprobar si DOM está listo para su función de selector o no. Esto no es una solución (permanente).
Las formas preferidas de verificar si el DOM está cargado antes de ejecutar su función son las siguientes:
1) Envuelva su función de selector en
$(document).ready(function(){ ... your selector function... };
2) Si eso no funciona, use DOMContentLoaded
3) Pruebe window.onload , que espera a que todas las imágenes se carguen primero, por lo que es el menos preferido
window.onload = function () { ... your selector function... }
4) Si está esperando que se cargue una biblioteca que se carga en varios pasos o tiene algún tipo de demora propia, es posible que necesite alguna solución personalizada complicada. Esto es lo que me pasó con la biblioteca "MathJax". Esta pregunta explica cómo verificar cuándo la biblioteca MathJax cargó sus elementos DOM, si es de alguna ayuda.
5) Finalmente, puede quedarse con la función setTimeout
codificada, lo que hace que sea de 1-3 segundos. Este es en realidad el método menos preferido en mi opinión.
Esta lista de arreglos probablemente esté lejos de ser perfecta, por lo que todos pueden editarla.
El error es que está usando ''ID'' en minúsculas como ''checkbox1'', pero cuando coloca en bucle el objeto json, vuelve a mayúsculas. Por lo que necesita reemplazar checkbox1 a CHECKBOX1.
En mi caso :-
var response = jQuery.parseJSON(response);
$.each(response, function(key, value) {
$.each(value, function(key, value){
$(''#''+key).val(value);
});
});
antes de
<input type="text" name="abc" id="abc" value="">
Recibo el mismo error, pero cuando reemplazo el ID en el código html, funciona bien.
Después
<input type="text" name="abc" id="ABC" value="">
Me enfrenté a este problema porque mi selector dependía de la id
mientras I did not set id for my element
mi selector
fue
$("#EmployeeName")
pero mi HTML element
<input type="text" name="EmployeeName">
así que asegúrese de que sus criterios de selección son válidos
Otro enfoque (dentro de la $function
para asegurar que each
se ejecute en el document ready
):
var ids = [1,2];
$(function(){
$(''.checkbox-wrapper>input[type="checkbox"]'').each(function(i,item){
if(ids.indexOf($(item).data(''id'')) > -1){
$(item).prop("checked", "checked");
}
});
});
Fiddle de trabajo: https://jsfiddle.net/robertrozas/w5uda72v/
¿Qué es el n.fn.init [0] y por qué se devuelve? ¿Por qué mis dos funciones JQuery aparentemente idénticas están devolviendo cosas diferentes?
Respuesta: Parece que sus elementos aún no están en el DOM, cuando está intentando encontrarlos. Como señaló @Rory McCrossan, la
length:0
significa que no encuentra ningún elemento en función de sus criterios de búsqueda.
Acerca de n.fn.init[0]
, veamos el núcleo de la Biblioteca Jquery:
var jQuery = function( selector, context ) {
return new jQuery.fn.init( selector, context );
};
Looks familiar, right?, now in a minified version of jquery, this should looks like:
var n = function( selector, context ) {
return new n.fn.init( selector, context );
};
Así que cuando usas un selector estás creando una instancia de la función jquery; cuando se encuentra un elemento basado en los criterios del selector, devuelve los elementos coincidentes; cuando los criterios no coinciden con nada, devuelve el objeto prototipo de la función.
Su objeto de resultado es un elemento jQuery, no una matriz javascript. La matriz que desea debe estar debajo de .get ()
Como el valor de retorno es un objeto jQuery, que contiene una matriz, es muy común llamar a .get () en el resultado para trabajar con una matriz básica. http://api.jquery.com/map/