如果 id 不存在,为什么 $('#id') 返回 true?

IT技术 javascript jquery
2021-03-10 19:35:09

我一直想知道如果我试图通过 id 选择器查找 DOM 结构中不存在的元素,为什么 jQuery 返回 true。

像这样:

<div id="one">one</div>

<script>
    console.log( !!$('#one') ) // prints true
    console.log( !!$('#two') ) // is also true! (empty jQuery object)
    console.log( !!document.getElementById('two') ) // prints false
</script>

我知道!!$('#two').length如果对象为空,我可以使用因为 length === 0 ,但对我来说,如果找到,选择器将返回元素似乎合乎逻辑,否则null(就像本机document.getElementById一样)。

F.ex,这个逻辑不能在 jQuery 中完成:

var div = $('#two') || $('<div id="two"></div>');

如果 ID 选择器在未找到时返回 null 会不会更合乎逻辑?

任何人?

6个回答

选择此行为是因为否则 jQuery 会定期抛出 NullReference Exceptions

几乎所有的 jQuery 函数都返回一个 jQuery 对象作为所讨论的 Dom 元素的包装器,因此您可以使用点表示法。

$("#balloon").css({"color":"red"});

现在想象一下$("#balloon")返回null这意味着这$("#balloon").css({"color":"red"}); 会引发错误,而不是像您期望的那样默默地做任何事情。

因此,您只需要使用.lengthor .size()

如果某些元素不存在,我同意抛出错误。可靠的代码抛出异常并发生异常。:) 不幸的是,jQuery 不是我们最好的朋友。
2021-04-18 19:35:09
我还以为这是原因之一。但是,以这种方式抑制错误真的是个好主意吗?如果找不到 id,我肯定想知道错误在哪里抛出,而不是调试每个链。
2021-04-20 19:35:09
如果您使用 id 选择器,这可能是您想要的行为,因为 ids(通常)是唯一的。但是如果您使用类选择器来关闭页面上的所有对话框/弹出窗口呢?您不希望该函数仅仅因为用户当前没有打开任何对话框而引发错误。你会希望它默默地什么都不做。
2021-04-27 19:35:09
JavaScript 没有任何称为 NullReference Exceptions 的东西。也许你的意思是ReferenceError
2021-05-03 19:35:09

这就是 jQuery 的工作方式。

$("#something")

对象 0=div#something length=1 jquery=1.2.6

$("#nothing")

对象长度=0 jquery=1.2.6

您可以通过访问元素的长度来接近做您想做的事情,并结合三元运算符:

console.log(!!$('#notfound').length);  // false
console.log(!!$('#exists').length);    // true
var element= $('#notfound').length ? $('#notfound') : $('#exists');
console.log(element.attr('id'));  // outputs 'exists'

至于问题的核心:

如果 ID 选择器在未找到时返回 null 会不会更合乎逻辑?

不,不是为了 JQuery 的做事方式——即支持 JQuery 语句的链接:

    $('#notfound').hide("slow", function(){
      jQuery(this)
        .addClass("done")
        .find("span")
          .addClass("done")
        .end()
        .show("slow", function(){
          jQuery(this).removeClass("done");
        });
    });

即使notfound不存在,此代码也会在不停止脚本执行的情况下运行。如果初始选择器返回空值,则必须添加一个 if/then 块来检查空值。如果 addClass、find、end 和 show 方法返回 null,则必须添加 if/then 块来检查每个方法的返回状态。链接是在动态类型语言(如 Javascript)中处理程序流的绝佳方式。

它返回真,因为对 Javascript 来说,它是一个定义的对象,因此不是假的,并且无论是否找到元素,jQuery 都会始终为您提供一个新对象 - 但是数组长度将为零,例如

$("span").length

如果您没有<span>,这将是零,但它可能是 1 或更多。

您可以编写自己的插件以避免重复 if 语句作为 Jquery 插件,就像我为这个插件所做的那样这很容易做到:

(function($)
{
        /* Checks if a jQuery object exists in the DOM, by checking the length of its child elements. */
        $.fn.elementExists = function()
        {
                ///     <summary>
                ///     Checks if a jQuery object exists in the DOM, by checking the length of its child elements.
                ///     </summary>
                ///     <returns type="Boolean" />
                return jQuery(this).length > 0;
        };
})(jQuery);

用法:

if ($("#someid").elementExists())
{

}

您可以检查.lengthjQuery 对象属性。像这样:

if($("#two").length > 0) { // exists...

} else { // doesn't exist

}
这是一个很好的。它实际上还可以缩短:也if ($("#two").length)应该这样做。
2021-05-13 19:35:09