如何检测选择器是否返回null?


271

检测jQuery选择器是否返回空对象的最佳方法是什么。如果您这样做:

alert($('#notAnElement'));

您得到[object Object],所以我现在的方法是:

alert($('#notAnElement').get(0));

它将写为“ undefined”,因此您可以对此进行检查。但这似乎很糟糕。还有什么其他方式?

Answers:


494

我最喜欢的是使用这种微小的便利来扩展jQuery:

$.fn.exists = function () {
    return this.length !== 0;
}

像这样使用:

$("#notAnElement").exists();

比使用长度更明确。


2
为什么将'this'包装在$()中?在这种情况下,“ this”实际上不会指向jQuery对象吗?
Adham Atta

1
我发现回国this比更有帮助true。请参阅我的答案移植Rails的presence方法。
马克-安德烈·Lafortune

5
如果要保持链接的能力,函数应该返回true,或者如果您想使用此方法分配this给变量,则建议将return语句更改为CSharp的内容。
汉娜(Hanna)

1
Magnar,能否请您解释一下这个“扩展”功能是如何工作的?我假设这是一个Javascript概念,而不是严格的JQuery概念。我研究了原型制作,但不确定在这里是否适用以及为什么语法为“ $ .fn”。
KyleM 2014年

3
@亚当是的 但是在那种情况下,只要考虑到jQuery的工作原理,您就应该删除exist-check。如果没有匹配选择器的元素,它将只是不做任何事情。
Magnar

197
if ( $("#anid").length ) {
  alert("element(s) found")
} 
else {
  alert("nothing found")
}

67

选择器返回一个jQuery对象数组。如果找不到匹配的元素,它将返回一个空数组。您可以检查.length选择器返回的集合的,或检查第一个数组元素是否为'undefined'。

您可以在IF语句中使用以下任何示例,它们都将产生相同的结果。如果选择器找到匹配的元素,则为true,否则为false。

$('#notAnElement').length > 0
$('#notAnElement').get(0) !== undefined
$('#notAnElement')[0] !== undefined

1
我使用.length除非代码是热的。这当然是最明确的意图。此外,.size()已弃用,并且已经存在多年了(从1.8开始)。我将编辑您的答案并将其删除,可以随时随便添加回它,但它太旧了,我认为最好不要了。
埃文·卡罗尔

1
从技术上讲,它返回一个不包含DOM节点的jQuery对象。说返回空数组是不正确的。
激进

39

我喜欢做这样的事情:

$.fn.exists = function(){
    return this.length > 0 ? this : false;
}

因此,您可以执行以下操作:

var firstExistingElement = 
    $('#iDontExist').exists() ||      //<-returns false;
    $('#iExist').exists() ||          //<-gets assigned to the variable 
    $('#iExistAsWell').exists();      //<-never runs

firstExistingElement.doSomething();   //<-executes on #iExist

http://jsfiddle.net/vhbSG/


6
@Ehsan实际上,它不是已接受答案的重复...请注意,已接受答案仅返回true / false,而此答案返回原始对象(“ this”)或false。如果答案为非假,则此答案允许您使用返回值(例如,附加函数链接)来做其他事情。
RSW 2015年

1
我的标准工具箱中的代码完全相同。这种形式等效于Rails中的object.presence,并且在@CSharp描述的穿透构造中非常有用。
inopinatus

这是一个很好的答案,但是如果您解释说如果没有被测元素存在,将会发生什么,这将是有帮助的。简短答案:TypeError: firstExistingElement.doSomething is not a function。您可以在包装,如果整个变量赋值/测试(),只有做一些事情,如果一个元素被发现....
斯蒂芬- [R

9

我喜欢使用Ruby on Rails的presence启发:

$.fn.presence = function () {
    return this.length !== 0 && this;
}

您的示例变为:

alert($('#notAnElement').presence() || "No object found");

我发现它比建议的要好,$.fn.exists因为您仍然可以使用布尔运算符或if,但是真实的结果更有用。另一个例子:

$ul = $elem.find('ul').presence() || $('<ul class="foo">').appendTo($elem)
$ul.append('...')

7

我的偏好,我不知道为什么jQuery中还没有这个功能:

$.fn.orElse = function(elseFunction) {
  if (!this.length) {
    elseFunction();
  }
};

像这样使用:

$('#notAnElement').each(function () {
  alert("Wrong, it is an element")
}).orElse(function() {
  alert("Yup, it's not an element")
});

或者,如在CoffeeScript中所示:

$('#notAnElement').each ->
  alert "Wrong, it is an element"; return
.orElse ->
  alert "Yup, it's not an element"


0

默认情况下,您可能一直想要这样做。我一直在努力包装jquery函数或jquery.fn.init方法来做到这一点而没有错误,但是您可以对jquery源进行简单的更改来做到这一点。包括一些您可以搜索的周围的线。我建议搜索jQuery源The jQuery object is actually just the init constructor 'enhanced'

var
  version = "3.3.1",

  // Define a local copy of jQuery
  jQuery = function( selector, context ) {

    // The jQuery object is actually just the init constructor 'enhanced'
    // Need init if jQuery is called (just allow error to be thrown if not included)
    var result = new jQuery.fn.init( selector, context );
    if ( result.length === 0 ) {
      if (window.console && console.warn && context !== 'failsafe') {
        if (selector != null) {
          console.warn(
            new Error('$(\''+selector+'\') selected nothing. Do $(sel, "failsafe") to silence warning. Context:'+context)
          );
        }
      }
    }
    return result;
  },

  // Support: Android <=4.0 only
  // Make sure we trim BOM and NBSP
  rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;

jQuery.fn = jQuery.prototype = {

最后但并非最不重要的一点是,您可以在此处获取未压缩的jquery源代码:http : //code.jquery.com/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.