Почему мой селектор JQuery возвращает n.fn.init [0], и что это такое?
У меня есть набор динамически сгенерированных флажков, где каждый из них имеет атрибут data-id
, соответствующий идентификатору целого числа базы данных. Когда я заполняю свою html-форму объектом для редактирования, есть список целых чисел, представляющих, какие флажки должны быть проверены. Флажки помещены в div
с классом checkbox-wrapper
.
Итак, html выглядит так:
<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>
Обратите внимание, что идентификатор запускается с номерами индексов автоматического инкремента, тогда как идентификатор данных может иметь другое значение id. Я хочу выбрать их по идентификатору данных.
Теперь, используя JQuery, я знаю, что я могу выбрать соответствующие флажки, например:
$(".checkbox-wrapper>input[data-id='99']");
$(".checkbox-wrapper>input[data-id='1']");
Это работает на моей консоли, в chrome, и возвращает соответствующий DOM-элемент. Аналогично, это ниже, устанавливает флажки для проверки:
$(".checkbox-wrapper>input[data-id='99']").prop("checked", "checked");
$(".checkbox-wrapper>input[data-id='1']").prop("checked", "checked");
Однако, если я перебираю список целых чисел в своем javascript-коде (не непосредственно в консоли) и регистрирую возвращаемые элементы на основе значений id, я получаю некоторые странные результаты:
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");
});
Прежде всего, флажки не отмечены. Во-вторых, моя консоль печатает странные результаты:
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]
Печатные селекторные строки кажутся идеальными. Точные же селекторы возвращают DOM-элементы, когда они записываются непосредственно в хром-консоль. Затем они возвращают объекты следующим образом:
[<input type="checkbox" id="checkbox1" data-id="1">]
Что такое n.fn.init [0] и почему он возвращается? Почему мои две, казалось бы, идентичные функции JQuery возвращают разные вещи?
Ответы
Ответ 1
Другой подход (внутри $function
, чтобы утверждать, что each
выполняется на 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");
}
});
});
Что такое n.fn.init [0] и почему он возвращается? Почему мои две, казалось бы, идентичные функции JQuery возвращают разные вещи?
Ответ: Кажется, что ваши элементы еще не находятся в DOM, когда вы пытаетесь их найти. Как отметил @Rory McCrossan, length:0
означает, что он не находит ни одного элемента, основанного на ваших критериях поиска.
О n.fn.init[0]
, давайте посмотрим на ядро библиотеки 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 );
};
Поэтому, когда вы используете селектор, вы создаете экземпляр функции jquery; при обнаружении элемента, основанного на критериях выбора, он возвращает согласованные элементы; когда критерии не соответствуют чему-либо, он возвращает объект-прототип функции.
Ответ 2
Вот как сделать быструю проверку, чтобы убедиться, что n.fn.init[0]
вызван вашими элементами DOM, которые не загружаются вовремя. Заблокируйте свою функцию выбора, завернув ее в функцию setTimeout
следующим образом:
function timeout(){
...your selector function that returns n.fn.init[0] goes here...
}
setTimeout(timeout, 5000)
Это приведет к тому, что ваша функция выбора будет выполняться с задержкой в 5 секунд, которая должна быть достаточной для загрузки всего.
Это просто грубый взлом, чтобы проверить, готова ли DOM к вашей функции выбора или нет. Это не постоянное решение.
Предпочтительные способы проверки загрузки DOM перед выполнением вашей функции:
1) Оберните свою селекторную функцию в
$(document).ready(function(){ ... your selector function... };
2) Если это не работает, используйте DOMContentLoaded
3) Попробуйте window.onload, который ждет загрузки всех изображений сначала, поэтому его наименее предпочтительный
window.onload = function () { ... your selector function... }
4) Если вы ожидаете загрузки библиотеки, загружаемой в несколько этапов или имеющей некоторую задержку, тогда вам может понадобиться сложное настраиваемое решение. Вот что случилось со мной с библиотекой "MathJax". В этом вопросе обсуждается, как проверить, когда библиотека MathJax загрузила свои элементы DOM, если это поможет.
5) Наконец, вы можете придерживаться жестко закодированной функции setTimeout
, делая ее, возможно, 1-3 секунды. По-моему, это самый наименее предпочтительный метод.
Этот список исправлений, вероятно, далек от совершенства, поэтому каждый может редактировать его.
Ответ 3
Я столкнулся с этой проблемой, потому что мой селектор зависел от id
между тем I did not set id for my element
my selector
был
$("#EmployeeName")
но мой HTML element
<input type="text" name="EmployeeName">
просто убедитесь, что критерии выбора действительны.
Ответ 4
Ваш объект result является элементом jQuery, а не массивом javascript. Массив, который вы хотите, должен находиться под .get()
Поскольку возвращаемое значение является объектом jQuery, который содержит массив, это очень общий вызов .get() для результата для работы с базовым массивом. http://api.jquery.com/map/
Ответ 5
Ошибка в том, что вы используете "ID" в нижнем регистре, например "checkbox1", но когда вы зацикливаете json object на его возврат в верхнем регистре. Поэтому вам нужно заменить checkbox1 на CHECKBOX1.
В моем случае: -
var response = jQuery.parseJSON(response);
$.each(response, function(key, value) {
$.each(value, function(key, value){
$('#'+key).val(value);
});
});
Перед
<input type="text" name="abc" id="abc" value="">
Я получаю ту же ошибку, но когда я заменяю id в html-коде, его работа прекрасна.
После
<input type="text" name="abc" id="ABC" value="">