Как я могу проверить существование элемента в jQuery?

Текущий код, который у меня есть, это:

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

Есть ли более элегантный способ подойти к этому? Возможно, плагин или функция?

2975
Jake McGraw 27 Авг 2008 в 23:49

30 ответов

Лучший ответ

В JavaScript все «правдиво» или «ложно», а для чисел 0 (и NaN) означает false, все остальное true. Чтобы вы могли написать:

if ($(selector).length)

Вам не нужна эта >0 часть.

2456
Tim Büthe 17 Окт 2016 в 14:52

Вдохновленный ответом hiway, я придумал следующее:

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

jQuery.contains берет два элемента DOM и проверяет, содержит ли первый элемент второй.

Использование document.documentElement в качестве первого аргумента удовлетворяет семантике метода exists, когда мы хотим применить его исключительно для проверки существования элемента в текущем документе.

Ниже я собрал фрагмент, который сравнивает jQuery.exists() с подходами $(sel)[0] и $(sel).length, которые оба возвращают truthy значения для $(4), а {{X5} } возвращает 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 inputs = [
    ["$()",$()],
    ["$(4)",$(4)],
    ["$('#idoexist')",$('#idoexist')],
    ["$('#idontexist')",$('#idontexist')]
  ];
  
  for( var i = 0, l = inputs.length, tr, input; i < l; i++ ) {
    input = inputs[i][1];
    tr = "<tr><td>" + inputs[i][0] + "</td><td>"
          + testFuncs[0](input) + "</td><td>"
          + testFuncs[1](input) + "</td><td>"
          + testFuncs[2](input) + "</td></tr>";
    $("table").append(tr);
  }
td { border: 1px solid black }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="idoexist">#idoexist</div>
<table style>
<tr>
  <td>Input</td><td>!!$(sel)[0]</td><td>!!$(sel).length</td><td>$(sel).exists()</td>
</tr>
</table>
<script>
  
  $.fn.exists = function() {
    return $.contains(document.documentElement, this[0]); 
  }
  
</script>
26
Community 23 Май 2017 в 11:47

Вот полный пример различных ситуаций и способ проверить, существует ли элемент, используя direct, если на jQuery селектор может или не может работать, потому что он возвращает массив или элементы.

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
11
abhirathore2006 15 Окт 2016 в 07:10

Нет необходимости в jQuery (базовое решение)

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

Гораздо более производительный вариант ниже (обратите внимание на отсутствие точки перед классом).

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

QuerySelector использует правильный механизм сопоставления, такой как $ () (sizzle) в jQuery, и использует больше вычислительной мощности, но в 99% случаев все будет в порядке. Второй вариант более явный и сообщает коду, что именно делать. По словам jsperf, это намного быстрее, чем https://jsperf.com/getelementsbyclassname-vs-queryselectorall/25

26
Pawel 17 Июл 2019 в 14:43

Я вижу, что большинство ответов здесь не точны , как и должно быть, они проверяют длину элемента, во многих случаях это может быть ОК , но не 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
61
Alireza 17 Июл 2019 в 11:59

Вы можете использовать:

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

Возможно, немного более элегантный.

66
Devon 17 Сен 2008 в 17:53

Проверка существования элемент аккуратно задокументирован на официальном сайте jQuery!

Используйте .length коллекцию jQuery, возвращенную вашим селектор:

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

Обратите внимание, что не всегда необходимо проверять, существует ли элемент. Следующий код покажет элемент, если он существует, и ничего не сделает (без ошибок), если он не существует:

$("#myDiv").show();
34
Palec 10 Сен 2017 в 10:31

Этот плагин можно использовать в выражении if, например if ($(ele).exist()) { /* DO WORK */ }, или с помощью обратного вызова.

Plugin

;;(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    */
    }
})
66
22 revs, 6 users 64% 12 Июн 2016 в 09:10

Вы можете использовать это:

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

// if element does not exist
if(!$('selector').length){ /* do something */ }
136
Derek 朕會功夫 29 Июн 2016 в 04:43

Вот мой любимый метод 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
ducdhm 8 Мар 2016 в 17:06

Вы можете использовать это:

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

if($(selector).exists()){/*do something*/}
54
Bellash 15 Мар 2016 в 07:46

На самом деле нет необходимости в jQuery. С простым JavaScript легче и семантически правильно проверить:

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

Если по какой-либо причине вы не хотите добавлять идентификатор к элементу, вы все равно можете использовать любой другой метод JavaScript, предназначенный для доступа к DOM.

JQuery действительно крутой, но не позволяйте чистому JavaScript забыться ...

56
Peter Mortensen 10 Май 2013 в 07:48

Это очень похоже на все ответы, но почему бы не использовать оператор ! дважды, чтобы получить логическое значение:

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

if ($(selector).exists()) {
    // the element exists, now what?...
}
31
Santiago Hernández 4 Май 2015 в 03:31

У меня был случай, когда я хотел посмотреть, существует ли объект внутри другого, поэтому я добавил что-то в первый ответ, чтобы проверить селектор внутри селектора.

// 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;
};
19
jcreamer898 5 Апр 2012 в 21:02

Мне просто нравится использовать простой ванильный JavaScript для этого.

function isExists(selector){
  return document.querySelectorAll(selector).length>0;
}
25
Sanu Uthaiah Bollera 18 Июн 2016 в 22:37

Я обнаружил, что 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.');
}

Я все еще ищу лучшее решение, хотя это немного тяжело.

Изменить: ВНИМАНИЕ! . Это не работает в IE, когда selector является строкой.

$.isEmptyObject('hello') // FALSE in Chrome and TRUE in IE
39
Oleg 7 Фев 2012 в 17:43

Я наткнулся на этот вопрос, и я хотел бы поделиться фрагментом кода, который я сейчас использую:

$.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
23
Eternal1 16 Апр 2015 в 09:17

$("selector") возвращает объект, обладающий свойством length. Если селектор найдет какие-либо элементы, они будут включены в объект. Поэтому, если вы проверите его длину, вы увидите, существуют ли какие-либо элементы. В JavaScript 0 == false, поэтому, если вы не получите 0, ваш код будет работать.

if($("selector").length){
   //code in the case
} 
14
Hydrothermal 3 Янв 2019 в 10:00

Если вы использовали

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 */ }
373
R3tep 30 Июн 2015 в 08:09

Вы можете сохранить несколько байтов, написав:

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

Это работает, потому что каждый объект jQuery также маскируется как массив, поэтому мы можем использовать оператор разыменования массива, чтобы получить первый элемент из array . Возвращает undefined, если по указанному индексу нет элемента.

72
Salman A 18 Янв 2014 в 09:04

Является ли $.contains() тем, что вы хотите?

jQuery.contains( container, contained )

Метод $.contains() возвращает значение true, если элемент DOM, предоставленный вторым аргументом, является потомком элемента DOM, предоставленного первым аргументом, является ли он прямым дочерним элементом или вложенным более глубоко. В противном случае возвращается false. Поддерживаются только узлы элементов; если второй аргумент является узлом текста или комментария, $.contains() вернет false.

Примечание . Первый аргумент должен быть элементом DOM, а не объектом jQuery или простым объектом JavaScript.

40
Mohammad 28 Окт 2018 в 09:57

Я использую это:

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

15
andy_314 1 Авг 2012 в 21:56

Да!

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

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

Это ответ на подкаст «Стадный код» с Джеффом Этвудом

1353
Jake McGraw 13 Фев 2017 в 22:37

Как насчет:

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

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

Он очень минимален и избавляет вас от необходимости заключать селектор в $() каждый раз.

18
GSTAR 4 Мар 2014 в 21:15

Попробуйте проверить элемент DOM

if (!!$(selector)[0]) // do stuff
27
guest271314 9 Авг 2015 в 02:55

Самый быстрый и наиболее семантически понятный способ проверки существования - это использование простого JavaScript:

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

Это немного длиннее для записи, чем альтернатива длины jQuery, но выполняется быстрее, поскольку это нативный метод JS.

И это лучше, чем альтернатива написания собственной функции jQuery. Эта альтернатива медленнее, по причинам, указанным @snover. Но это также создало бы у других программистов впечатление, что функция exists() является чем-то присущим jQuery. JavaScript будут / должны быть поняты другими, редактирующими ваш код, без увеличения долга знаний.

Примечание: обратите внимание на отсутствие знака "#" перед element_id (поскольку это обычный JS, а не jQuery).

99
Randika Vishman 9 Фев 2019 в 03:48

Причина, по которой все предыдущие ответы требуют параметра .length, заключается в том, что они в основном используют селектор jquery $(), у которого есть запрос querySelectorAll (или они используют его напрямую). Этот метод довольно медленный, потому что ему нужно проанализировать все дерево DOM, найти все совпадения с этим селектором и заполнить ими массив.

Параметр ['length'] не нужен и не полезен, и код будет намного быстрее, если вместо этого вы будете использовать document.querySelector(selector), поскольку он возвращает первый соответствующий элемент или ноль, если не найден.

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);
43
technosaurus 13 Авг 2014 в 05:24

Вы можете проверить наличие или отсутствие элемента в 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
}
38
Ma'moun othman 20 Фев 2020 в 12:16
$(selector).length && //Do something
28
SJG 28 Май 2012 в 12:58

Вам не нужно проверять, больше ли оно 0, например $(selector).length > 0, $(selector).length, достаточно и элегантного способа проверить наличие элементов. Я не думаю, что стоит написать функцию только для этого, если вы хотите сделать больше лишних вещей, да.

if($(selector).length){
  // true if length is not 0
} else {
  // false if length is 0
}
11
Andrei Todorut 20 Июн 2017 в 09:43