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

Kje*_*din 41 jquery jquery-selectors

我有一组动态生成的复选框,其中每个复选框都有一个data-id对应于数据库整数id 的属性.当我用我要编辑的对象填充我的html表单时,会有一个整数列表,表示应该检查哪些复选框.复选框包含在divwith类中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>
Run Code Online (Sandbox Code Playgroud)

请注意,id在自动增量索引号上运行,而data-id可能具有不同的id值.我想通过data-id选择它们.

现在,使用JQuery,我知道我可以选择相关的复选框,如下所示:

$(".checkbox-wrapper>input[data-id='99']");
$(".checkbox-wrapper>input[data-id='1']");
Run Code Online (Sandbox Code Playgroud)

这在我的控制台中以chrome运行,它返回相关的DOM元素.同样,在下面,将复选框设置为选中:

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

但是,如果我在我的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");    
}); 
Run Code Online (Sandbox Code Playgroud)

首先,没有选中复选框.其次,我的控制台打印出奇怪的结果

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]
Run Code Online (Sandbox Code Playgroud)

打印的选择器字符串看起来很完美.当直接写入chrome控制台时,完全相同的选择器返回DOM元素.然后他们返回这样的对象:

[<input type=?"checkbox" id=?"checkbox1" data-id=?"1">?]
Run Code Online (Sandbox Code Playgroud)

什么是n.fn.init [0],以及返回的原因是什么?为什么我的两个看似相同的JQuery函数返回不同的东西?

Hac*_*man 25

另一种方法(内部$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");
    }
  });
});
Run Code Online (Sandbox Code Playgroud)

工作小提琴:https://jsfiddle.net/robertrozas/w5uda72v/

什么是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 );
};
Run Code Online (Sandbox Code Playgroud)

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 );
};
Run Code Online (Sandbox Code Playgroud)

因此,当您使用选择器时,您正在创建jquery函数的实例; 当根据选择标准找到一个元素时,它返回匹配的元素; 当条件与任何东西都不匹配时,它返回函数的原型对象.

  • @KjetilNordin,我不是为代表做这件事,我这样做是为了帮助别人,所以别担心.也许这个答案可以为其他人服务,所以我不会删除它,积分也不会成熟.正如你所说:它看起来像一个伟大的代码xD. (3认同)
  • 虽然它可能是很棒的代码,但这并不能回答我的问题的任何部分。而且它也解决不了任何问题,因为我的复选框在尝试填充它们时似乎还没有准备好。意思是,这个方法将迭代零个 DOM 元素。 (2认同)
  • 似乎我的速度有点快http://jsperf.com/perf-checkboxes-so (2认同)
  • 我吃了我的话!通过http://jsperf.com/,您刚刚与我分享了一个很棒的资源.我不知道那一个.我将来可能会使用它很多.想想它,它是有道理的,因为你只执行一个jquery选择,虽然有更多的遍历,但它似乎对资源要求更低.你是我的朋友,给我上了一堂课:).谢谢! (2认同)
  • 答案已编辑...从小开始,逐渐成长:) (2认同)

Art*_*sov 6

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

function timeout(){ 

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

}

setTimeout(timeout, 5000)
Run Code Online (Sandbox Code Playgroud)

这将导致您的选择器功能以5秒的延迟执行,这对于几乎任何要加载的东西都应该足够了.

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

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

1)包裹您的选择器功能

$(document).ready(function(){  ... your selector function...  };
Run Code Online (Sandbox Code Playgroud)

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

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

window.onload = function () {  ... your selector function...  }
Run Code Online (Sandbox Code Playgroud)

4)如果您正在等待一个库以几个步骤加载该加载或者它有自己的某种延迟,那么您可能需要一些复杂的自定义解决方案.这就是我用"MathJax"库发生的事情.这个问题讨论了如何检查MathJax库何时加载其DOM元素,如果它有任何帮助.

5)最后,你可以坚持使用硬编码setTimeout功能,可能需要1-3秒.在我看来,这实际上是最不受欢迎的方法.

这个修复列表可能远非完美,所以欢迎大家编辑它.


Bas*_*ANI 5

I faced this issue because my selector was depend on id meanwhile I did not set id for my element

my selector was

$("#EmployeeName")
Run Code Online (Sandbox Code Playgroud)

but my HTML element

<input type="text" name="EmployeeName">
Run Code Online (Sandbox Code Playgroud)

so just make sure that your selector criteria are valid


cel*_*rno 5

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

由于返回值是一个包含数组的 jQuery 对象,因此在结果上调用 .get() 以使用基本数组是很常见的。 http://api.jquery.com/map/