ChatGPT解决这个技术问题 Extra ChatGPT

jQuery 是否有“存在”功能?

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

我目前的代码是这样的:

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

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


M
MartinNajemi

在 JavaScript 中,一切都是“真”或“假”,对于数字 0 意味着 false,其他一切都是 true。所以你可以写:

if ($(selector).length)

您不需要那个 >0 部分。


@abhirathore2006 如果您使用 id 选择器并且该元素不存在,则长度为 0 并且不会引发异常。
有趣的是NaN != false
@James 那是因为 [].toString() === [].join(',') === """" === ""
@Robert,那是因为 NaN != aa 字面上 是任何值。
NaN 可能是 != false,但 NaN 肯定是 falsy,这是一个稍微不同的东西
J
Jake McGraw

是的!

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

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

这是为了回应:Herding Code podcast with Jeff Atwood


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

如果你用过

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

你会暗示链接是可能的,而不是。

这会更好:

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

或者,from the FAQ

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

您还可以使用以下内容。如果 jQuery 对象数组中没有值,那么获取数组中的第一项将返回 undefined。

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

已经有一些不可链接的方法,例如 attr 和 data 函数。不过,我确实明白你的观点,而且,不管怎样,我只是测试长度 > 0。
为什么你需要把它锁起来? $(".missing").css("color", "red") 已经做了正确的事……(即什么都没有)
D
Derek 朕會功夫

你可以使用这个:

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

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

您没有看到 Tim Büthe 在您之前 2 年就已经给出了这个 answer 吗?
Pfft,Tim 从未展示过如何测试元素是否不存在。
R
Randika Vishman

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

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

它比 jQuery 长度替代方法要长一些,但由于它是原生 JS 方法,所以执行速度更快。

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

注意:请注意 element_id 之前缺少一个“#”(因为这是纯 JS,而不是 jQuery)。


完全不是一回事。 JQuery 选择器可用于任何 CSS 规则 - 例如 $('#foo a.special')。它可以返回多个元素。 getElementById 无法解决这个问题。
@Noz if(document.querySelector("#foo a.special")) 会工作。不需要 jQuery。
JS 引擎中关于速度的论点只在没有 jQuery 就无法运行的人的脑海中消失,因为这是他们无法取胜的论点。
还记得 document.getElementById 是我们仅有的美好时光吗?我总是忘记文件。并且无法弄清楚为什么它不起作用。而且我总是拼写错误并且字符大小写错误。
S
Salman A

您可以通过编写节省几个字节:

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

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


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

您可以使用:

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

也许更优雅一点。


对于这么简单的事情,这太过分了。见 Tim Büthe 答案
这是正确的答案。 'length' 方法的问题是它对任何数字都给出误报,例如: $(666).length // 返回 1,但它不是有效的选择器
这对于非常简单的任务来说是非常昂贵的。只需查看 jquery 实现 if .is() ,您就会看到它需要处理多少代码才能回答您这个简单的问题。此外,您想要做什么并不明显,因此它与所讨论的解决方案相同或可能不太优雅。
2
22 revs, 6 users 64%

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

在回调版本中,Has Items 回调实际上不应该将对象作为参数传递吗?
A
Alireza

我看到这里的大多数答案都不准确,他们检查元素长度,在很多情况下都可以,但不是 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

P
Peter Mortensen

真的不需要 jQuery。使用纯 JavaScript,检查以下内容更容易且语义正确:

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

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

jQuery 真的很酷,但不要让纯 JavaScript 被遗忘……


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

你可以使用这个:

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

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

t
technosaurus

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

['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;

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

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);

C
Community

$.contains() 是您想要的吗?

jQuery.contains(container, contains) 如果第二个参数提供的 DOM 元素是第一个参数提供的 DOM 元素的后代,则 $.contains() 方法返回 true,无论它是直接子元素还是嵌套更深。否则,它返回 false。仅支持元素节点;如果第二个参数是文本或注释节点,$.contains() 将返回 false。注意:第一个参数必须是 DOM 元素,而不是 jQuery 对象或纯 JavaScript 对象。


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

您可以在 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
}

您无需检查天气长度是否大于 0, if( $('#elementid').length ) { } 就足够了。
你真的读过这个问题吗?这与 OP 使用的方法完全相同。
O
Oleg

我发现 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

您发现自己以空对象作为参数调用 $() 的频率如何?
@nnnnnn 实际上从来没有(我不再使用 jQuery)。但我想 3 年前我曾公开一个 API 的案例,该 API 将采用一个选择器并返回该选择器的元素数量。如果另一个开发者传入一个空对象,它会错误地响应 1。
你到底为什么要将一个空对象 {} 传递给 $()
@cpburnz 你为什么问我?我只是一个 API 提供者......人们将各种愚蠢的东西传递给 API。
刚刚注意到,@FagnerBrack 引用的 jquery 问题线程在他发表评论后不久就更新了;看起来它毕竟不会消失。
P
Palec

Checking for existence of an element 整齐地记录在官方 jQuery 网站本身!

使用选择器返回的 jQuery 集合的 .length 属性: if ($("#myDiv").length) { $("#myDiv").show();请注意,并不总是需要测试元素是否存在。以下代码将显示该元素(如果存在),如果不存在则不执行任何操作(没有错误): $("#myDiv").show();


S
Santiago Hernández

这与所有答案都非常相似,但为什么不使用两次 ! 运算符,以便获得布尔值:

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

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

因为Boolean(x)有时会更有效率。
S
SJG
$(selector).length && //Do something

我讨厌这些避免使用 if 的巧妙方法,其中 if 会以 2 个字节为代价提高可读性。
此外,缩小器会为您完成所有这些&&
哈哈 现在 8 年后它在 React JS 中很常见😄
g
guest271314

尝试测试 DOM 元素

if (!!$(selector)[0]) // do stuff

t
tagurit

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

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

下面是性能更高的选项(请注意 a-class 之前缺少一个点)。

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

querySelector 在 jQuery 中使用了像 $()(嘶嘶声)这样的适当匹配引擎,并使用了更多的计算能力,但在 99% 的情况下都可以正常工作。第二个选项更明确,并准确地告诉代码要做什么。根据 JSBench https://jsbench.me/65l2up3t8i,它要快得多


C
Community

hiway's answer 的启发,我提出了以下建议:

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

jQuery.contains 采用两个 DOM 元素并检查第一个元素是否包含第二个元素。

当我们只想应用 document.documentElement 作为第一个参数来满足 exists 方法的语义时,它只是用于检查当前文档中是否存在元素。

下面,我汇总了一个片段,将 jQuery.exists()$(sel)[0]$(sel).length 方法进行比较,这两种方法都返回 truthy$(4) 值,而 $(4).exists() 返回 false。在检查是否存在 DOM 中的元素的上下文中,这似乎是期望的结果

$.fn.exists = function() { return $.contains(document.documentElement, this[0]); } var testFuncs = [ function(jq) { return !!jq[0]; }, function(jq) { return !!jq.length; }, function(jq) { return jq.exists(); }, ]; var 输入 = [ ["$()",$()], ["$(4)",$(4)], ["$('#idoexist')",$('#idoexist')], ["$('#idontexist')",$('#idontexist')] ]; for( var i = 0, l = inputs.length, tr, input; i < l; i++ ) { input = inputs[i][1]; tr = "" + 输入[i][0] + "" + testFuncs[0](输入) + "" + testFuncs[1 ](输入) + "" + testFuncs[2](输入) + ""; $("table").append(tr); } td { 边框:1px 纯黑色 }

#idoexist
<表格样式> 输入!!$(sel)[0]!!$(sel)。长度$(sel).exists()


您可以在调试器中尝试 $("#xysyxxs") ,您会看到 jquery 不会返回 null 或 undefined。所以最终的解决方案是行不通的