jQuery是否有“存在”功能?


2778

如何检查jQuery中元素的存在?

我当前的代码是这样的:

if ($(selector).length > 0) {
    // Do something
}

有没有更优雅的方式来解决这个问题?也许是插件还是功能?

Answers:


2488

在JavaScript中,一切都是“真实的”或“虚假的”,对于数字0(和NaN)意味着false其他一切true。所以你可以这样写:

if ($(selector).length)

您不需要那>0部分。


52
@ abhirathore2006如果使用id选择器,并且元素不存在,则length为0,并且不会引发异常。
罗伯特·

14
有趣的是NaN != false
罗伯特·

35
@Robert and [] + []= ""...啊,我爱JavaScript
James James

9
@James那是因为[].toString() === [].join(',') === """" === ""
Ismael Miguel

5
@Robert andtypeof NaN == 'number'
oriadam '18

1356

是!

jQuery.fn.exists = function(){ return this.length > 0; }

if ($(selector).exists()) {
    // Do something
}

这是为了响应:与Jeff Atwood一起进行的“ 牧群代码”播客


254
我只写:if($(selector.length){...},不带'>
0'– vsync

369
您的$.fn.exists示例用两个函数调用替换了一个属性查找(便宜!),这两个函数调用要昂贵得多,而其中一个函数调用会重新创建您已经拥有的jQuery对象,这很愚蠢。
C Snover 2010年

212
@redsquare:代码可读性是在jQuery上添加此类功能的最佳理由。即使语义与相同的结果吻合,拥有被称为“东西”的.exists内容.length也会清晰地读取,而在语义上却是不同的。
Ben Zotto

48
@quixoto,很抱歉,.length是许多语言中不需要包装的标准。您还如何解释.length?
redsquare 2010年

144
我认为,从“列表长度大于零”的概念到“我为之编写选择器的元素存在”的概念,这至少是一种逻辑间接。是的,从技术上讲,它们是同一件事,但是概念上的抽象处于不同的层次上。即使某些性能成本,这也会使某些人更喜欢更明确的指标。
Ben Zotto

377

如果你用过

jQuery.fn.exists = function(){return ($(this).length > 0);}
if ($(selector).exists()) { }

您可能会暗示,如果没有,链接是可能的。

这样会更好:

jQuery.exists = function(selector) {return ($(selector).length > 0);}
if ($.exists(selector)) { }

或者,从FAQ中

if ( $('#myDiv').length ) { /* Do something */ }

您也可以使用以下内容。如果jQuery对象数组中没有值,则获取数组中的第一项将返回未定义。

if ( $('#myDiv')[0] ) { /* Do something */ }

11
第一种方法读起来更好。$(“ a”)。exists()读为“如果<a>元素存在。” $ .exists(“ a”)读为“如果存在<a>元素”。
斯特拉格

16
是的,但同样,您的意思是暗示可以进行链接,并且如果我尝试执行类似$(selector).exists()。css(“ color”,“ red”)的操作,则此操作将无效,那么我将= *(
乔恩·埃里克森

19
已经有一些不可链接的方法,例如attr和data函数。不过,我的确知道您的观点,对于它的价值,我还是只测试了长度> 0。
马修·克鲁姆利

39
为什么在地球上需要链接此对象?$(".missing").css("color", "red")已经做了正确的事……(即什么也没做)
Ben Blank

15
关于链接的内容是完整的- 很多 jQuery $.fn方法返回的不是新的jQuery对象,因此不链接。
Alnitak

136

您可以使用此:

// if element exists
if($('selector').length){ /* do something */ }

// if element does not exist
if(!$('selector').length){ /* do something */ }

134
您是否没有看到蒂姆·布特(TimBüthe)比您早两年就给出了这个答案
Th4t Guy 2014年

101
Pfft,Tim从未展示过如何测试该元素是否不存在。
杰里米·W

1
你的意思是生活“其他”?我的问题是:err,它必须存在或选择器不匹配。长度是多余的。
RichieHH

26
这个答案和评论总结了stackoverflow的工作原理
aswzen 18'Apr

101

检查存在性的最快,最语义上的自我解释方法实际上是使用plain JavaScript

if (document.getElementById('element_id')) {
    // Do something
}

它比jQuery长度替代方法更长一些,但是由于它是本机JS方法,因此执行速度更快。

它比编写您自己的jQuery函数的替代方法更好。由于@snover指出的原因,该替代方法较慢。但这也会给其他程序员一个印象,即该exists()函数是jQuery固有的。JavaScript其他人会/应该理解您的代码,而不会增加知识负担。

注意:请注意前面没有'#' element_id(因为这是普通JS而不是jQuery)。


56
完全不一样。jQuery选择器可用于任何CSS规则-例如$('#foo a.special')。它可以返回多个元素。getElementById无法开始解决这个问题。
kikito 2012年

7
您是正确的,因为它没有选择器广泛适用。但是,在最常见的情况下(检查是否存在单个元素),它的工作效果很好。关于自我解释和速度的争论仍然存在。
Magne

29
@Noz if(document.querySelector("#foo a.special"))会工作。无需jQuery。
蓝天

34
JS引擎中关于速度的争论只留给了没有jQuery无法运行的人,因为这是他们无法取胜的争论。
蓝天

22
还记得过去只有document.getElementById的美好时光吗?而且我总是忘了这份文件。而且不知道为什么它不起作用。而且我总是将其拼写错误并弄错了字符大小写。
JustJohn

73

您可以通过写一些字节来节省:

if ($(selector)[0]) { ... }

之所以可行,是因为每个jQuery对象也都伪装成一个数组,因此我们可以使用数组解引用运算符从array中获取第一项。undefined如果指定索引处没有任何项目,则返回。


1
我来这里发布这个确切的答案...强制性的小提琴:jsfiddle.net/jasonwilczak/ekjj80gy/2
JasonWilczak 2015年

3
@JasonWilczak为何要评论为什么不这样做:.eq [0]或.first()引用找到的第一个元素而不是类型转换?
Jean Paul AKA el_vete 2015年

5
不,jQuery.first()或者jQuery.eq(0)两者都返回对象,即使它们是空的,它们也是真实的。此示例应说明为什么不能按原样使用这些功能:if(jQuery("#does-not-exist").eq(0)) alert("#does-not-exist exists")
Salman A

1
正确。.eq(0)仅返回截断长度为1或0的另一个jQuery对象。这.first()只是的便捷方法.eq(0)。但是.get(0)返回第一个DOM元素或undefined和与相同[0]。jQuery对象中的第一个DOM元素以名称存储在常规对象属性中'0'。这是一个简单的属性访问。唯一的类型转换源于数字0到字符串的隐式转换'0'。因此,如果类型转换存在问题,则可以$.find(selector)['0']改用。
罗伯特·

66

您可以使用:

if ($(selector).is('*')) {
  // Do something
}

一个更优雅,也许。


38
对于这么简单的事情来说,这太多了。看到蒂姆·布泰答案
VSYNC

这是正确的答案。“长度”方法的问题在于,它会给出任何数字的误报,例如:$(666).length //返回1,但它不是有效的选择器
earnaz

对于非常简单的任务,这非常昂贵。只需查看.is()的jquery实现,您就会看到它需要处理多少代码才能回答这个简单的问题。同样,您不希望确切执行什么操作也不是很明显,因此与所讨论的解决方案相比,它是相同的,或者可能不够优雅。
micropro.cz

1
@earnaz很好,很高兴。不过,我看不出这实际上是值得关注的地方。开发人员识别元素666的原因可能还有很多其他原因,导致代码损坏。虽然它是无效的选择器,但$(666).length 是有效的javascript:它的计算结果为真实,因此满足条件。
托德

@earnaz可以避免这种情况$.find(666).length
Emile Bergeron,2016年

66

可以在if类似if ($(ele).exist()) { /* DO WORK */ }或使用回调的语句中使用此插件。

插入

;;(function($) {
    if (!$.exist) {
        $.extend({
            exist: function() {
                var ele, cbmExist, cbmNotExist;
                if (arguments.length) {
                    for (x in arguments) {
                        switch (typeof arguments[x]) {
                            case 'function':
                                if (typeof cbmExist == "undefined") cbmExist = arguments[x];
                                else cbmNotExist = arguments[x];
                                break;
                            case 'object':
                                if (arguments[x] instanceof jQuery) ele = arguments[x];
                                else {
                                    var obj = arguments[x];
                                    for (y in obj) {
                                        if (typeof obj[y] == 'function') {
                                            if (typeof cbmExist == "undefined") cbmExist = obj[y];
                                            else cbmNotExist = obj[y];
                                        }
                                        if (typeof obj[y] == 'object' && obj[y] instanceof jQuery) ele = obj[y];
                                        if (typeof obj[y] == 'string') ele = $(obj[y]);
                                    }
                                }
                                break;
                            case 'string':
                                ele = $(arguments[x]);
                                break;
                        }
                    }
                }

                if (typeof cbmExist == 'function') {
                    var exist =  ele.length > 0 ? true : false;
                    if (exist) {
                        return ele.each(function(i) { cbmExist.apply(this, [exist, ele, i]); });
                    }
                    else if (typeof cbmNotExist == 'function') {
                        cbmNotExist.apply(ele, [exist, ele]);
                        return ele;
                    }
                    else {
                        if (ele.length <= 1) return ele.length > 0 ? true : false;
                        else return ele.length;
                    }
                }
                else {
                    if (ele.length <= 1) return ele.length > 0 ? true : false;
                    else return ele.length;
                }

                return false;
            }
        });
        $.fn.extend({
            exist: function() {
                var args = [$(this)];
                if (arguments.length) for (x in arguments) args.push(arguments[x]);
                return $.exist.apply($, args);
            }
        });
    }
})(jQuery);

jsFiddle

您可以指定一个或两个回调。第一个将触发如果元素存在,如果元素没有第二人会火存在。但是,如果您选择仅传递一个函数,则仅在元素存在时才会触发。因此,如果所选择的元素并链条会死存在。当然,如果确实存在,则将触发第一个功能,并且链将继续。

请记住,使用回调变体有助于保持可链接性 -返回该元素,您可以像其他任何jQuery方法一样继续链接命令!

示例用途

if ($.exist('#eleID')) {    /*    DO WORK    */ }        //    param as STRING
if ($.exist($('#eleID'))) { /*    DO WORK    */ }        //    param as jQuery OBJECT
if ($('#eleID').exist()) {  /*    DO WORK    */ }        //    enduced on jQuery OBJECT

$.exist('#eleID', function() {            //    param is STRING && CALLBACK METHOD
    /*    DO WORK    */
    /*    This will ONLY fire if the element EXIST    */
}, function() {            //    param is STRING && CALLBACK METHOD
    /*    DO WORK    */
    /*    This will ONLY fire if the element DOES NOT EXIST    */
})

$('#eleID').exist(function() {            //    enduced on jQuery OBJECT with CALLBACK METHOD
    /*    DO WORK    */
    /*    This will ONLY fire if the element EXIST    */
})

$.exist({                        //    param is OBJECT containing 2 key|value pairs: element = STRING, callback = METHOD
    element: '#eleID',
    callback: function() {
        /*    DO WORK    */
        /*    This will ONLY fire if the element EXIST    */
    }
})

1
在回调版本中,Has Items回调实际上不应该将对象作为参数传递吗?
克里斯·马里西奇

62

我看到大部分的答案在这里是不准确的,因为他们应该是,他们检查元素长度,也可以是确定在许多情况下,但不是100% ,想象一下,如果数量传球而不是函数,所以我原型机检查所有功能条件并返回答案应为:

$.fn.exists = $.fn.exists || function() { 
  return !!(this.length && (this[0] instanceof HTMLDocument || this[0] instanceof HTMLElement)); 
}

这将同时检查长度和类型,现在您可以通过以下方式进行检查:

$(1980).exists(); //return false
$([1,2,3]).exists(); //return false
$({name: 'stackoverflow', url: 'http://www.stackoverflow.com'}).exists(); //return false
$([{nodeName: 'foo'}]).exists() // returns false
$('div').exists(); //return true
$('.header').exists(); //return true
$(document).exists(); //return true
$('body').exists(); //return true

55

确实不需要jQuery。使用普通JavaScript,检查以下内容会更容易且语义正确:

if(document.getElementById("myElement")) {
    //Do something...
}

如果出于某种原因您不想在该元素上添加id,则仍然可以使用旨在访问DOM的任何其他JavaScript方法。

jQuery确实很酷,但是不要让纯JavaScript被遗忘...


5
我知道:它不能直接回答原始问题(要求使用jquery函数),但在那种情况下,答案将是“否”或“不是语义上正确的解决方案”。
amypellegrini 2011年

如果需要父选择器:has()怎么办?
КонстантинВан”,19年

54

您可以使用此:

jQuery.fn.extend({
    exists: function() { return this.length }
});

if($(selector).exists()){/*do something*/}

43

前面所有答案都需要该.length参数的原因是,它们大多使用jquery的$()选择器,而后者的选择后面有querySelectorAll(或者它们直接使用它)。此方法相当慢,因为它需要解析整个DOM树以查找与该选择器的所有匹配项,并使用它们填充数组。

['length']参数不是必需的,也不有用,如果直接使用,则代码会快很多document.querySelector(selector),因为它返回匹配的第一个元素;如果找不到,则返回null。

function elementIfExists(selector){  //named this way on purpose, see below
    return document.querySelector(selector);
}
/* usage: */
var myelement = elementIfExists("#myid") || myfallbackelement;

但是,此方法使我们可以返回实际的对象。如果不会将其另存为变量并重复使用,则很好(因此,如果我们忘记了,请保留引用)。

var myel=elementIfExists("#myid");
// now we are using a reference to the element which will linger after removal
myel.getParentNode.removeChild(myel);
console.log(elementIfExists("#myid")); /* null */
console.log(myel); /* giant table lingering around detached from document */
myel=null; /* now it can be garbage collected */

在某些情况下,这可能是理想的。它可以在如下所示的for循环中使用:

/* locally scoped myel gets garbage collected even with the break; */
for (var myel; myel = elementIfExist(sel); myel.getParentNode.removeChild(myel))
    if (myel == myblacklistedel) break;

如果您实际上并不需要该元素,并且只想获取/存储一个true / false,则不加倍!它适用于解开的鞋子,那么为什么要在这里结呢?

function elementExists(selector){
    return !!document.querySelector(selector);
}
/* usage: */
var hastables = elementExists("table");  /* will be true or false */
if (hastables){
    /* insert css style sheet for our pretty tables */
}
setTimeOut(function (){if (hastables && !elementExists("#mytablecss"))
                           alert("bad table layouts");},3000);

40

$.contains()你想要的吗?

jQuery.contains( container, contained )

$.contains()如果第二个参数提供的DOM元素是第一个参数提供的DOM元素的后代(无论是直接子元素还是嵌套得更深),则该方法返回true。否则,它返回false。仅支持元素节点;如果第二个参数是文本或注释节点,$.contains()则将返回false。

注意:第一个参数必须是DOM元素,而不是jQuery对象或普通JavaScript对象。


3
这不接受选择器,这意味着他必须选择它,这意味着他可以检查选择的结果。

39

我发现if ($(selector).length) {}这还不够。当selector为空对象时,它将以无提示方式破坏您的应用程序{}

var $target = $({});        
console.log($target, $target.length);

// Console output:
// -------------------------------------
// [▼ Object              ] 1
//    ► __proto__: Object

我唯一的建议是对进行额外检查{}

if ($.isEmptyObject(selector) || !$(selector).length) {
    throw new Error('Unable to work with the given selector.');
}

我仍然在寻找更好的解决方案,尽管这个解决方案有点繁重。

编辑:警告!selector是字符串时,这在IE中不起作用。

$.isEmptyObject('hello') // FALSE in Chrome and TRUE in IE

12
您多久发现自己$()以一个空对象作为参数进行调用?
nnnnnn 2014年

@nnnnnn实际上从不(我不再使用jQuery)。但是我想3年前我有一个公开API的案例,该API会带有一个选择器并返回该选择器的元素数量。如果另一个dev的将通过在一个空的对象时,它会不正确地响应1
奥列格

3
为什么在地球上您会将一个空的物体传递{}$()
所有工人都很重要

7
@cpburnz为什么问我?我只是一个API提供者...人们将各种愚蠢的东西传递给API。
奥莱格2015年

4
刚刚注意到,@ FagnerBrack引用的jquery发行线程在他发表评论后不久就更新了;看来它并没有消失。
约瑟夫·加布里埃尔

38

您可以使用Java脚本中的长度来检查元素是否存在。如果长度大于零,则元素存在;如果长度为零,则元素不存在

// These by Id
if ($("#elementid").length > 0) {
  // Element is Present
} else {
  // Element is not Present
}

// These by Class
if ($(".elementClass").length > 0) {
  // Element is Present
} else {
  // Element is not Present
}

4
您不必检查天气长度是否大于0,如果($('#elementid')。length){}就足够了。
布拉纳夫

13
你真的读过这个问题吗?这与OP使用的方法完全相同。
A1rPun

34

在jQuery官方网站本身中整齐地记录了检查元素是否存在的信息!

使用选择器返回的jQuery集合的.length属性:

if ($("#myDiv").length) {
    $("#myDiv").show();
}

请注意,不一定总是需要测试元素是否存在。以下代码将显示元素是否存在,如果不存在,则不执行任何操作(无错误):

$("#myDiv").show();

31

这与所有答案非常相似,但是为什么不!两次使用运算符,这样您就可以得到布尔值:

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

if ($(selector).exists()) {
    // the element exists, now what?...
}

2
由于Boolean(x)有时更有效。

28
$(selector).length && //Do something

19
我恨避免使用这些聪明的方法if,其中一个if将在2个字节的成本提高可读性。
Emile Bergeron

此外,矿工将为您完成所有这些&&工作。


27

hiway的答案启发,我想到了以下内容:

$.fn.exists = function() {
    return $.contains( document.documentElement, this[0] );
}

jQuery.contains接受两个DOM元素,并检查第一个元素是否包含第二个DOM元素。

当我们只想将其document.documentElement用作exists检查当前文档中某个元素的存在时,使用作为第一个参数满足该方法的语义。

下面,我已经放在一起进行比较的一个片段jQuery.exists()反对$(sel)[0]$(sel).length接近,两者均返回truthy的值$(4),而$(4).exists()回报false。在检查 DOM中元素是否存在的情况下,这似乎是期望的结果


26

不需要jQuery(基本解决方案)

if(document.querySelector('.a-class')) {
  // do something
}

下面有更多性能选项(请注意,A级之前没有点号)。

if(document.getElementsByClassName('a-class')[0]) {
  // do something
}

querySelector在jQuery中使用适当的匹配引擎,例如$()(嘶嘶声),并使用更多的计算能力,但在99%的情况下就可以了。第二个选项更明确,并告诉代码确切的操作。根据jsperf https://jsperf.com/getelementsbyclassname-vs-queryselectorall/25的描述,它要快得多


25

我只是喜欢用普通的javascript来做到这一点。

function isExists(selector){
  return document.querySelectorAll(selector).length>0;
}

23

我偶然发现了这个问题,我想分享一下我当前使用的代码片段:

$.fn.exists = function(callback) {
    var self = this;
    var wrapper = (function(){
            function notExists () {}

            notExists.prototype.otherwise = function(fallback){
                if (!self.length) {                    
                    fallback.call();
                }
            };

            return new notExists;
        })();

    if(self.length) {
        callback.call();    
    }

    return wrapper;
}

现在我可以编写这样的代码-

$("#elem").exists(function(){
    alert ("it exists");
}).otherwise(function(){
    alert ("it doesn't exist");
});

可能看起来很多代码,但是当用CoffeeScript编写时,它很小:

$.fn.exists = (callback) ->
    exists = @length
    callback.call() if exists        
    new class
       otherwise: (fallback) ->            
            fallback.call() if not exists

9
我发现OP的原始方法不仅要最小化而且要优雅得多。当OP的方法更短并且不涉及回调时,编写这么多代码似乎有点过头了。
2014年

对于简单的情况-您是对的。但是对于涉及两种情况的大量代码的更复杂情况,我认为我的方法更好。
永恒2014年

4
在什么复杂的情况下,这种方法会比简单的if / else语句更好?
Jarvl

19

我有一种情况,我想查看一个对象是否存在于另一个对象中,因此我在第一个答案中添加了一些内容以检查选择器中的选择器。

// Checks if an object exists.
// Usage:
//
//     $(selector).exists()
//
// Or:
// 
//     $(selector).exists(anotherSelector);
jQuery.fn.exists = function(selector) {
    return selector ? this.find(selector).length : this.length;
};

18

怎么样:

function exists(selector) {
    return $(selector).length;
}

if (exists(selector)) {
    // do something
}

这非常少,省去了$()每次都要封装选择器的麻烦。


3
读为“如果存在的事物”,而不是读为“如果存在的事物” if($("#thing").exists(){}。而且,这不是jQuery的方式。
1j01 2015年

15

我正在使用这个:

    $.fn.ifExists = function(fn) {
      if (this.length) {
        $(fn(this));
      }
    };
    $("#element").ifExists( 
      function($this){
        $this.addClass('someClass').animate({marginTop:20},function(){alert('ok')});               
      }
    ); 

仅当存在jQuery元素时才执行链-http: //jsfiddle.net/andres_314/vbNM3/2/


14

这是我exist在jQuery中最喜欢的方法

$.fn.exist = function(callback) {
    return $(this).each(function () {
        var target = $(this);

        if (this.length > 0 && typeof callback === 'function') {
            callback.call(target);
        }
    });
};

和其他版本,当选择器不存在时支持回调

$.fn.exist = function(onExist, onNotExist) {
    return $(this).each(function() {
        var target = $(this);

        if (this.length > 0) {
            if (typeof onExist === 'function') {
                onExist.call(target);
            }
        } else {
            if (typeof onNotExist === 'function') {
                onNotExist.call(target);
            }
        }
    });
};

例:

$('#foo .bar').exist(
    function () {
        // Stuff when '#foo .bar' exists
    },
    function () {
        // Stuff when '#foo .bar' does not exist
    }
);

14

$("selector")返回具有该length属性的对象。如果选择器找到任何元素,则它们将包含在对象中。因此,如果检查其长度,可以看到是否存在任何元素。在JavaScript中0 == false,因此如果您不理解,0代码将运行。

if($("selector").length){
   //code in the case
} 

5
“给数组” —不,不是。它为您提供了一个jQuery对象(与数组共享一些属性)。您的答案与2009年的蒂姆·布特(TimBüthe)基本上相同。
Quentin

11

这是不同情况的完整示例,以及在jQuery选择器上使用直接if来检查元素是否存在的方法,因为它可以返回数组或元素,因此可能会或可能不会起作用。

var a = null;

var b = []

var c = undefined ;

if(a) { console.log(" a exist")} else { console.log("a doesn't exit")}
// output: a doesn't exit

if(b) { console.log(" b exist")} else { console.log("b doesn't exit")}
// output: b exist

if(c) { console.log(" c exist")} else { console.log("c doesn't exit")}
// output: c doesn't exit

最终解决方案

if($("#xysyxxs").length){ console.log("xusyxxs exist")} else { console.log("xusyxxs doesnn't exist") }
//output : xusyxxs doesnn't exist

if($(".xysyxxs").length){ console.log("xusyxxs exist")} else { console.log("xusyxxs doesnn't exist") }
    //output : xusyxxs doesnn't exist

您可以在调试器中尝试$(“#xysyxxs”),您会看到jquery不会返回null或未定义。所以,最终的解决方案是行不通的
贝朗杰

11

您不必检查它是否大于0like $(selector).length > 0$(selector).length这足够了并且是一种优雅的方法来检查元素的存在。我不认为仅为此编写函数是不值得的,如果您想做更多的事情,是的。

if($(selector).length){
  // true if length is not 0
} else {
  // false if length is 0
}
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.