如何检查 jQuery 中的元素是否存在?
我目前的代码是这样的:
if ($(selector).length > 0) {
// Do something
}
有没有更优雅的方法来解决这个问题?也许是插件或功能?
在 JavaScript 中,一切都是“真”或“假”,对于数字 0
意味着 false
,其他一切都是 true
。所以你可以写:
if ($(selector).length)
您不需要那个 >0
部分。
是的!
jQuery.fn.exists = function(){ return this.length > 0; }
if ($(selector).exists()) {
// Do something
}
这是为了回应:Herding Code podcast with Jeff Atwood
$.fn.exists
示例用两个函数调用替换属性查找(便宜!),这要昂贵得多,其中一个函数调用重新创建了一个您已经拥有的 jQuery 对象。
.exists
的东西读起来很干净,而 .length
读起来是语义上不同的东西,即使语义与相同的结果一致。
如果你用过
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 */ }
$(".missing").css("color", "red")
已经做了正确的事……(即什么都没有)
你可以使用这个:
// if element exists
if($('selector').length){ /* do something */ }
// if element does not exist
if(!$('selector').length){ /* do something */ }
检查存在的最快和语义上最自我解释的方法实际上是使用简单的 JavaScript
:
if (document.getElementById('element_id')) {
// Do something
}
它比 jQuery 长度替代方法要长一些,但由于它是原生 JS 方法,所以执行速度更快。
它比编写自己的 jQuery
函数更好。出于@snover 所述的原因,该替代方案较慢。但它也会给其他程序员一种印象,即 exists()
函数是 jQuery 固有的。 JavaScript
将/应该被编辑您的代码的其他人理解,而不会增加知识债务。
注意:请注意 element_id
之前缺少一个“#”(因为这是纯 JS,而不是 jQuery
)。
$('#foo a.special')
。它可以返回多个元素。 getElementById
无法解决这个问题。
if(document.querySelector("#foo a.special"))
会工作。不需要 jQuery。
您可以通过编写节省几个字节:
if ($(selector)[0]) { ... }
这是因为每个 jQuery 对象也伪装成一个数组,所以我们可以使用数组解引用运算符从 array 中获取第一项。如果指定索引处没有项目,则返回 undefined
。
jQuery.first()
或 jQuery.eq(0)
都返回对象,对象是真实的,即使它们是空的。此示例应说明为什么不能按原样使用这些函数:if(jQuery("#does-not-exist").eq(0)) alert("#does-not-exist exists")
您可以使用:
if ($(selector).is('*')) {
// Do something
}
也许更优雅一点。
此插件可用于 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);
您可以指定一个或两个回调。如果元素存在,第一个将触发,如果元素不存在,则第二个将触发。但是,如果您选择只传递一个函数,它只会在元素存在时触发。因此,如果所选元素不存在,则链将终止。当然,如果它确实存在,第一个函数将触发并且链将继续。
请记住,使用回调变体有助于保持可链接性——元素被返回,您可以像使用任何其他 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
回调实际上不应该将对象作为参数传递吗?
我看到这里的大多数答案都不准确,他们检查元素长度,在很多情况下都可以,但不是 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
真的不需要 jQuery。使用纯 JavaScript,检查以下内容更容易且语义正确:
if(document.getElementById("myElement")) {
//Do something...
}
如果出于某种原因您不想为元素添加 id,您仍然可以使用任何其他旨在访问 DOM 的 JavaScript 方法。
jQuery 真的很酷,但不要让纯 JavaScript 被遗忘……
你可以使用这个:
jQuery.fn.extend({
exists: function() { return this.length }
});
if($(selector).exists()){/*do something*/}
所有前面的答案都需要 .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);
$.contains()
是您想要的吗?
jQuery.contains(container, contains) 如果第二个参数提供的 DOM 元素是第一个参数提供的 DOM 元素的后代,则 $.contains() 方法返回 true,无论它是直接子元素还是嵌套更深。否则,它返回 false。仅支持元素节点;如果第二个参数是文本或注释节点,$.contains() 将返回 false。注意:第一个参数必须是 DOM 元素,而不是 jQuery 对象或纯 JavaScript 对象。
您可以在 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
}
我发现 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
$()
的频率如何?
{}
传递给 $()
?
Checking for existence of an element 整齐地记录在官方 jQuery 网站本身!
使用选择器返回的 jQuery 集合的 .length 属性: if ($("#myDiv").length) { $("#myDiv").show();请注意,并不总是需要测试元素是否存在。以下代码将显示该元素(如果存在),如果不存在则不执行任何操作(没有错误): $("#myDiv").show();
这与所有答案都非常相似,但为什么不使用两次 !
运算符,以便获得布尔值:
jQuery.fn.exists = function(){return !!this.length};
if ($(selector).exists()) {
// the element exists, now what?...
}
Boolean(x)
有时会更有效率。
$(selector).length && //Do something
if
的巧妙方法,其中 if
会以 2 个字节为代价提高可读性。
&&
。
尝试测试 DOM
元素
if (!!$(selector)[0]) // do stuff
不需要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,它要快得多
受 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 = "
NaN != false
。[].toString() === [].join(',') === ""
和"" === ""
。NaN != a
当a
字面上 是任何值。NaN
可能是!= false
,但NaN
肯定是 falsy,这是一个稍微不同的东西