[Javascript] jQuery有没有“存在”功能?


Answers

是!

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

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

这是为了回应: 与Jeff Atwood合作的“牧群规范”播客

Question

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

我现在的代码是这样的:

if ($(selector).length > 0) {
    // 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);

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    */
    }
})



检查一个元素的存在是否正式记录在jQuery官方网站上!

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

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

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

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



你可以使用这个:

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

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



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

$.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



怎么样:

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

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

这是非常小的,并且可以节省您每次都必须用$()包含选择器。




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

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

这是可行的,因为每个jQuery对象也伪装成一个数组,所以我们可以使用数组解引用操作符来获取数组中的第一项。 如果在指定索引处没有项目,它将返回undefined




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

jQuery.contains(容器,包含)

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

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




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



你可以使用这个:

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



尝试测试DOM元素

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



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

if($(selector).length){
  // true if length is not 0
} else {
  // false if length is 0
}



所有以前的答案需要.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 */

在某些情况下,这可能是需要的。 它可以像这样用于循环:

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



if ( $('#myDiv').size() > 0 ) { //do something }

size()计算选择器返回的元素数量




我正在使用这个:

    $.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/