为什么我的 JQuery 选择器返回 n.fn.init[0],它是什么?

Why is my JQuery selector returning a n.fn.init[0], and what is it?

我有一组动态生成的复选框,其中每个复选框都有一个对应于数据库整数 ID 的 data-id 属性。当我用要编辑的对象填充我的 html 表单时,有一个整数列表表示应该选中哪些复选框。复选框包裹在 div 和 class 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 在自动递增索引号上运行,而 data-id 可能具有不同的 id 值。我想通过 data-id select 他们。

现在,使用 JQuery,我知道我可以 select 像这样的相关复选框:

$(".checkbox-wrapper>input[data-id='99']");
$(".checkbox-wrapper>input[data-id='1']");

这在我的控制台中有效,在 chrome 中,它 return 是相关的 DOM 元素。同样,下面将复选框设置为已选中:

$(".checkbox-wrapper>input[data-id='99']").prop("checked", "checked");
$(".checkbox-wrapper>input[data-id='1']").prop("checked", "checked");

但是,如果我在 javascript 代码中遍历整数列表(不是直接在控制台中),并根据 id 值记录 returned 元素,我得到一些奇怪的结果:

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]

打印的 selector 字符串看起来很完美。当直接写入 chrome 控制台时,select 或 return 与 DOM 元素完全相同。然后他们 return 这样的对象:

[<input type=​"checkbox" id=​"checkbox1" data-id=​"1">​]

什么是 n.fn.init[0],为什么要 returned?为什么我的两个看似相同的 JQuery 函数 return 不同?

另一种方法(在$function内部确保eachdocument 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:https://jsfiddle.net/robertrozas/w5uda72v/

What is the n.fn.init[0], and why it is returned? Why are my two seemingly identical JQuery functions returning different things?

Answer: It seems that your elements are not in the DOM yet, when you are trying to find them. As @Rory McCrossan pointed out, the length:0 means that it doesn't find any element based on your search criteria.

关于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 );
};

So when you use a selector you are creating an instance of the jquery function; when found an element based on the selector criteria it returns the matched elements; when the criteria does not match anything it returns the prototype object of the function.

以下是如何快速检查 n.fn.init[0] 是否由您的 DOM 元素未及时加载引起的。通过将其包装在 setTimeout 函数中来延迟您的选择器函数,如下所示:

function timeout(){ 

    ...your selector function that returns n.fn.init[0] goes here...

}

setTimeout(timeout, 5000)

这将导致您的选择器函数延迟 5 秒执行,这应该足以加载几乎所有内容。

这只是一个粗略的 hack,用于检查 DOM 是否已准备好用于您的选择器功能。这不是(永久)解决方案。

在执行函数之前检查 DOM 是否已加载的首选方法如下:

1) 将选择器函数包装在

$(document).ready(function(){  ... your selector function...  };

2) 如果这不起作用,请使用 DOMContentLoaded

3) 尝试 window.onload,它首先等待所有图像加载,因此它最不受欢迎

window.onload = function () {  ... your selector function...  }

4) 如果您正在等待分几步加载的库加载或有某种延迟,那么您可能需要一些复杂的自定义解决方案。这就是 "MathJax" 图书馆发生在我身上的事情。 This question 讨论如何检查 MathJax 库何时加载其 DOM 元素,如果有任何帮助。

5) 最后,您可以坚持使用硬编码的 setTimeout 函数,这可能需要 1-3 秒。这实际上是我认为最不受欢迎的方法。

此修复列表可能远非完美,因此欢迎大家对其进行编辑。

我遇到这个问题是因为我的选择器同时依赖于 id I did not set id for my element

我的 selector

$("#EmployeeName")

但是我的 HTML element

<input type="text" name="EmployeeName">

so just make sure that your selector criteria are valid

错误是您使用的 'ID' 是小写的 'checkbox1',但是当您循环 json 对象时,它的 return 是大写的。所以需要将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="">

我遇到了同样的错误,但是当我替换 html 代码中的 id 时,它的工作正常。

之后

<input type="text" name="abc" id="ABC" value="">

您的结果对象是 jQuery 元素,而不是 javascript 数组。您希望的数组必须在 .get()

As the return value is a jQuery object, which contains an array, it's very common to call .get() on the result to work with a basic array. http://api.jquery.com/map/

我只想为这些很棒的答案添加一些内容。如果您的 DOM 元素没有及时加载。您仍然可以设置该值。

let Ctrl = $('#mySelectElement'); ... Ctrl.attr('value', myValue);

在那之后 most DOM 接受值属性的元素应该正确填充。