题 jQuery是否存在“存在”功能?


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

我当前的代码是这样的:

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

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


2330
2017-08-27 19:49


起源




答案:


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

if ($(selector).length)

你不需要那个 >0 部分。


2072
2018-02-25 19:16



如果您使用Id选择器,如果元素不存在,这将抛出错误。检查我做过的各种测试......在我的回答中 - abhirathore2006
@ abhirathore2006如果使用id选择器并且该元素不存在则length为0并且不会抛出异常。 - Robert
有趣的是 NaN != false。 - Robert
@Robert和 [] + [] = ""...啊,我喜欢javascript - James
@deblocker 这是一个视频 我想你会喜欢的! - James


是!

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

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

这是对: 与杰夫阿特伍德的羊群编码播客


1247
2017-08-27 19:50



我只写:if($(selector)。length){...}没有'> 0' - vsync
你的 $.fn.exists 示例是使用两个函数调用替换属性查找(便宜!),这两个函数调用要贵得多 - 其中一个函数调用会重新创建一个已经拥有的jQuery对象,这很愚蠢。 - C Snover
@redsquare:代码可读性是在jQuery上添加此类函数的最佳理由。有东西叫 .exists 读得很干净,而 .length 读取语义不同的东西,即使语义与相同的结果一致。 - Ben Zotto
@quixoto,抱歉,但.length是许多语言的标准,不需要包装。你怎么解释.length? - redsquare
在我看来,它至少是一个逻辑间接,从“列表长度大于零”的概念到“我为可存在的选择器编写的元素”的概念。是的,它们在技术上是相同的,但概念抽象处于不同的层面。这导致一些人更喜欢更明确的指标,即使在某些性能成本下也是如此。 - Ben Zotto


如果你用过

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对象数组中没有值,那么获取数组中的第一个项将返回undefined。

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

324
2018-01-14 19:46



第一种方法读得更好。 $(“a”)。exists()读为“if <a>元素存在。” $ .exists(“a”)读作“如果存在<a>元素”。 - strager
是的,但是再一次,你暗示链接是可能的,如果我尝试做类似$(selector).exists()。css(“color”,“red”)之类的东西它将不起作用然后我会= *( - Jon Erickson
已经存在不可链接的方法,如attr和data函数。我确实看到了你的观点,并且,为了它的价值,我只测试长度> 0。 - Matthew Crumley
为什么你需要链接这个? $(".missing").css("color", "red") 已经做对了...(即什么都没有) - Ben Blank
关于链接的东西是完整的东西 - 有 丰富 的jQuery $.fn 返回除新jQuery对象之外的其他东西的方法,因此不会链接。 - Alnitak


你可以用这个:

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

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

98
2018-04-03 12:17



你有没有看到TimBüthe已经给了这个 回答 在你之前2年? - Th4t Guy
Pfft,Tim从未展示如何测试元素是否不存在。 - Jeremy W
你的意思是生活“别的”?我的Q是这样的:错误,它必须存在或者选择器不匹配。长度是多余的。 - RichieHH
这个答案和评论总结了stackoverflow的工作原理 - aswzen


检查存在的最快和最语义的自我解释方法实际上是使用纯JavaScript:

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

写入比jQuery长度替代要长一些,但执行速度更快,因为它是本机JS方法。

它比编写自己的jQuery函数更好。由于@snover的原因,这种替代方案较慢。但它也会给其他程序员一种印象,即exists()函数是jQuery固有的东西。编辑代码的其他人将会/应该理解JavaScript,而不会增加知识债务。

注意:注意元素之前缺少'#'(因为这是普通的JS,而不是jQuery)。


73
2018-01-11 12:27



完全不一样的东西。例如,JQuery选择器可用于任何CSS规则 $('#foo a.special')。它可以返回多个元素。 getElementById 不能开始接近那个。 - kikito
你是正确的,它不像选择器那样广泛适用。但是,它在最常见的情况下完成工作(检查是否存在单个元素)。自我解释和速度的论点仍然存在。 - Magne
@Noz if(document.querySelector("#foo a.special")) 会工作。不需要jQuery。 - Blue Skies
JS引擎中的速度论证只会在没有jQuery的情况下无法运行的人心中死亡,因为这是他们无法获胜的论点。 - Blue Skies
还记得我们曾经拥有的document.getElementById过去的美好时光吗?我总是忘记这份文件。并且无法弄清楚为什么它不起作用。而且我总是把它拼写错误并且让字符大小错误。 - JustJohn


您可以通过编写来保存几个字节:

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

这是有效的,因为每个jQuery对象也伪装成一个数组,所以我们可以使用数组解除引用运算符来获取第一个项目 排列。它回来了 undefined 如果指定的索引没有项目。


53
2018-01-18 09:04



我来到这里发布这个确切的答案...强制小提琴: jsfiddle.net/jasonwilczak/ekjj80gy/2 - JasonWilczak
@JasonWilczak关注为什么不这样做:.eq [0]或.first()来引用找到的第一个元素而不是类型转换? - Jean Paul A.K.A el_vete
没有, jQuery.first() 要么 jQuery.eq(0) 两个返回对象,即使它们是空的,对象也是真实的。这个例子应该说明为什么这些函数不能按原样使用: if(jQuery("#does-not-exist").eq(0)) alert("#does-not-exist exists") - Salman A
正确。 .eq(0) 返回另一个截断为长度为1或0的jQuery对象。 .first() 只是一种方便的方法 .eq(0)。但 .get(0) 返回第一个DOM元素或 undefined 和是一样的 [0]。 jQuery对象中的第一个DOM元素存储在具有名称的常规对象属性中 '0'。这是一个简单的属性访问。唯一的类型转换源于数字的隐式转换 0 到字符串 '0'。因此,如果类型转换是您可以使用的问题 $.find(selector)['0'] 代替。 - Robert


您可以使用:

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

一个  或许更优雅。


50
2017-09-17 17:53



这对于这么简单的事情来说太过分了。看到TimBüthe的答案 - vsync
这是正确的答案。 'length'方法有一个问题,即它给出任何数字的误报,例如:$(666)。length //返回1,但它不是有效的选择器 - earnaz
这对于非常简单的任务来说非常昂贵。只需查看jquery实现,如果.is(),您将看到需要处理多少代码来回答这个简单的问题。此外,您想要做的事情并不明显,因此它与问题解决方案相同或者可能不那么优雅。 - micropro.cz
@earnaz很棒,很好听。不过,我看不出这实际上值得关注的地方。开发人员识别元素 666 他们的代码可能还有很多其他原因。虽然它是一个无效的选择器,$(666).length 是有效的JavaScript:它评估为真实,因此 应该 满足条件。 - Todd
@earnaz为了避免这种具体情况, $.find(666).length 作品。 - Emile Bergeron


这个插件可用于 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    */
    }
})

48
2017-11-14 14:20



在回调版本上,不应该 Has Items 回调实际上作为参数传入对象? - Chris Marisic