Есть ли функция «существует» для jQuery?

2944

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

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

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

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

0
2619

В JavaScript все «правдиво» или «ложно», а числа 0означают falseвсе остальное true. Итак, вы могли написать:

if ($(selector).length)

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

7
  • 59
    @ abhirathore2006 Если вы используете селектор идентификатора, а элемент не существует, длина равна 0 и не вызывает исключений. Robert 29 июня '17 в 20:35
  • 19
    Достаточно интересно NaN != false. Robert 29 июня '17 в 20:52
  • 18
    @ Джеймс Это потому, что [].toString() === [].join(',') === ""и "" === "". Ismael Miguel 08 июл.
  • 12
    @ Роберт иtypeof NaN == 'number'oriadam 31 янв.
  • 8
    Есть ли ощутимая польза от отказа от этой > 0детали? Мне так кажется более ясным. Sinjai 14 фев '18 в 5: 092018-02-14 5:09
1394

Да!

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

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

Это ответ на: Подкаст Herding Code с Джеффом Этвудом

9
  • 257
    Я просто пишу: if ($ (selector) .length) {...} без '> 0'vsync 24 нояб.
  • 372
    Ваш $.fn.existsпример заменяет поиск свойств (дешево!) Двумя вызовами функций, которые намного дороже, и один из этих вызовов функций воссоздает объект jQuery, который у вас уже есть, что просто глупо. C Snover 30 мая '10 в 4:14
  • 216
    @redsquare: Удобочитаемость кода - лучшее объяснение для добавления такой функции в jQuery. То, что называется, .existsчитает чисто, тогда как .lengthчитается как нечто семантически отличное, даже если семантика совпадает с идентичным результатом. Ben Zotto 02 авг.
  • 51
    @quixoto, извините, но .length - это стандарт для многих языков, который не требует упаковки. Как еще вы интерпретируете .length? redsquare 03 авг.
  • 148
    На мой взгляд, это по крайней мере одно логическое косвенное указание от концепции «длина списка больше нуля» к концепции «элемента (ов), для которого я написал селектор». Да, технически это одно и то же, но концептуальная абстракция находится на другом уровне. Это заставляет некоторых людей предпочесть более явный индикатор, даже за счет некоторой потери производительности. Ben Zotto 03 авг.
386

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

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 */ }
8
  • 14
    Первый метод лучше читается. $ ("a"). exists () читается как "если существуют элементы <a>". $ .exists ("a") читается как "если существуют элементы <a>". strager 14 янв.
  • 19
    правда, но опять же, вы подразумеваете, что цепочка возможна, и если бы я попытался сделать что-то вроде $ (selector) .exists (). css ("color", "red"), это не сработало бы, и тогда я был бы = * (Jon Erickson 15 янв.
  • 23
    Уже есть методы, которые нельзя объединять в цепочку, например функции attr и data. Я все же понимаю вашу точку зрения и, чего бы это ни стоило, я в любом случае просто проверяю длину> 0. Matthew Crumley 16 янв.
  • 42
    Зачем вам это нужно связывать? $(".missing").css("color", "red")уже поступает правильно… (т.е. ничего не делает)Ben Blank 8 сен.
  • 21 год
    Дело в том, что цепочка - это полная чушь - существует множество$.fn методов jQuery, которые возвращают что-то, кроме нового объекта jQuery, и поэтому не связываются. Alnitak 18 июля '14 в 11: 122014-07-18 11:12
142

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

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

// if element does not exist
if(!$('selector').length){ /* do something */ }
2
  • 138
    Разве вы не видели, что Тим Бют уже дал этот ответ за 2 года до вас? Th4t Guy 31 июля '14 в 17:28
  • 110
    Пффф, Тим никогда не показывал, как проверить, не существует ли элемента. Jeremy W 5 авг.
111

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

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

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

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

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

11
  • 61
    Совершенно не одно и то же. Селекторы JQuery можно использовать для любого правила CSS, например $('#foo a.special'). И он может возвращать более одного элемента. getElementByIdне могу приблизиться к этому. kikito 7 марта '12 в 16:30
  • 7
    Вы правы в том, что он не так широко применим, как селекторы. Однако в наиболее частом случае он выполняет свою работу достаточно хорошо (проверяя, существует ли единственный элемент). Аргументы в пользу самообъяснения и скорости остаются в силе. Magne 10 мая '12 в 8:55
  • 32
    @Noz if(document.querySelector("#foo a.special"))будет работать. Не требуется jQuery. Blue Skies 08 дек.
  • 38
    Аргумент скорости в движках JS мертв только в сознании людей, которые не могут работать без jQuery, поскольку это аргумент, который они не могут выиграть. Blue Skies 08 дек.
  • 26 год
    Помните старые добрые времена, когда у нас было все, что у нас было document.getElementById? И я всегда забывал документ. и не мог понять, почему это не сработало. И я всегда писал неправильно и неправильно использовал регистр символов. JustJohn 18 ноя '14 в 21:05
80

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

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

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

4
  • 1
    Я пришел сюда, чтобы опубликовать этот точный ответ ... обязательная скрипка: jsfiddle.net/jasonwilczak/ekjj80gy/2JasonWilczak 25 марта '15 в 15: 082015-03-25 15:08
  • 3
    @JasonWilczak Не забудьте прокомментировать, почему бы вместо этого: .eq [0] или .first () для ссылки на первый найденный элемент, а не на приведение типов? Jean Paul -JP A.K.A el_vete 21 июля '15 в 13:51
  • 7
    Нет, jQuery.first()или jQuery.eq(0)оба возвращают объекты, объекты являются правдивыми, даже если они пустые. Этот пример должен проиллюстрировать, почему эти функции нельзя использовать как есть:if(jQuery("#does-not-exist").eq(0)) alert("#does-not-exist exists")Salman A 21 июля '15 в 18:16
  • 1
    Верный. .eq(0)возвращает просто еще один объект jQuery, усеченный до длины 1 или 0. .first()Это просто удобный метод для .eq(0). Но .get(0)возвращает первый элемент DOM или undefinedи совпадает с [0]. Первый элемент DOM в объекте jQuery хранится в свойстве обычного объекта с именем '0'. Это простой доступ к собственности. Единственное приведение типа происходит из неявного преобразования числа 0в строку '0'. Поэтому, если приведение типов является проблемой, вы можете использовать $.find(selector)['0']вместо этого. Robert 29 июн.
71

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

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

Чуть более элегантно, возможно.

5
  • 40
    Это слишком много для такой простой вещи. см. ответ Тима Бютеvsync 24 нояб.
  • 1
    Это правильный ответ. Метод 'length' имеет проблему, заключающуюся в том, что он дает ложное срабатывание с любым числом, например: $ (666) .length // возвращает 1, но это недопустимый селекторearnaz 16 сен.
  • 2
    Это очень дорого для очень простой задачи. Просто посмотрите на реализацию jquery if .is (), и вы увидите, сколько кода нужно обработать, чтобы ответить вам на этот простой вопрос. Также не очевидно, что именно вы хотите сделать, поэтому оно такое же или, может быть, менее элегантное, чем рассматриваемое решение. micropro.cz 22 фев '16 в 19:59
  • 2
    @earnaz отличный момент, хороший улов. Однако я не понимаю, где это действительно стоящее беспокойство. Разработчики, идентифицирующие элементы, 666вероятно, имеют множество других причин, по которым их код не работает. Хотя это недопустимый селектор, $ (666) .length является допустимым javascript : он оценивается как истинный и, следовательно, должен удовлетворять условию. Todd 8 марта '16 в 12:55
  • 1
    @earnaz, чтобы избежать этого конкретного случая, $.find(666).lengthработает. Emile Bergeron 08 окт.
70

Этот плагин можно использовать в 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    */
    }
})
1
  • 1
    В версии обратного вызова не должен ли Has Itemsобратный вызов фактически передавать объект в качестве аргумента? Chris Marisic 16 июня '16 в 17:46
68

Я вижу, что большинство ответов здесь не точны, как они должны быть, они проверяют длину элемента, во многих случаях это может быть нормально , но не на 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
0
58

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

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

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

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

1
  • 5
    Я знаю: он не отвечает напрямую на исходный вопрос (который запрашивает функцию jquery), но в этом случае ответ будет «Нет» или «семантически неправильное решение». amypellegrini 14 нояб.
58

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

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

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

Причина, по которой для всех предыдущих ответов требуется .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 */

В некоторых случаях это может быть желательно. Его можно использовать в цикле 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);
44 год

Это $.contains()то, что ты хочешь?

jQuery.contains( container, contained )

The $.contains() method returns true if the DOM element provided by the second argument is a descendant of the DOM element provided by the first argument, whether it is a direct child or nested more deeply. Otherwise, it returns false. Only element nodes are supported; if the second argument is a text or comment node, $.contains() will return false.

Note: The first argument must be a DOM element, not a jQuery object or plain JavaScript object.

1
  • 3
    Это не принимает селектор, что означает, что ему придется его выбрать, а это значит, что он может просто проверить результат своего выбора. user1106925 4 июня '16 в 13:28
44 год

Вы можете проверить, присутствует ли элемент или нет, используя длину в 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
}
2
  • 4
    Вам не нужно проверять, что длина погоды больше 0, если ($ ('# elementid'). Length) {} будет достаточно. Pranav Labhe 22 авг.
  • 13
    Вы действительно прочитали вопрос? Это точно такой же метод, который использует OP. A1rPun 16 марта '16 в 16: 012016-03-16 16:01
42

Я обнаружил, 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
5
  • 12
    Как часто вы звоните $()с пустым объектом в качестве аргумента? nnnnnn 22 дек.
  • @nnnnnn На самом деле никогда (я больше не использую jQuery). Но я думаю, 3 года назад у меня был случай, когда я раскрыл API, который брал бы селектор и возвращал количество элементов для этого селектора. Если другой разработчик передаст пустой объект, он неправильно ответит 1.Oleg 22 дек.
  • 3
    Почему на земле вы бы передать пустой объект {}в $()? All Workers Are Essential 26 марта '15 в 18: 462015-03-26 15:46
  • 8
    @cpburnz, почему ты меня спрашиваешь? Я был всего лишь поставщиком API ... Люди передают API всякие глупости. Oleg 26 марта '15 в 18: 482015-03-26 15:48
  • 4
    Только что заметил, ветка проблемы jquery, на которую ссылается @FagnerBrack, была обновлена ​​вскоре после его комментария; похоже, что он все-таки никуда не денется. Joseph Gabriel 18 апр '16 в 21:09
38

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

Use the .length property of the jQuery collection returned by your selector:

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

Note that it isn't always necessary to test whether an element exists. The following code will show the element if it exists, and do nothing (with no errors) if it does not:

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

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

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

if ($(selector).exists()) {
    // the element exists, now what?...
}
1
  • 2
    Потому что иногдаBoolean(x) может быть более эффективным. user7892745 22 мая '17 в 21:47
29
$(selector).length && //Do something
3
  • 19
    Я ненавижу эти умные способы избежать использования, ifгде ifбы улучшилась читаемость за счет 2 байтов. Emile Bergeron 08 окт.
  • К тому же минификаторы сделают все это &&за вас. user7892745 22 мая '17 в 21:46
  • Ха-ха, 8 лет спустя, это так часто встречается в React JS 😄Tilak Maddy 12 июл.
29

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

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

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

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

Нет необходимости в 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

0
26

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

function isExists(selector){
  return document.querySelectorAll(selector).length>0;
}
24

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

$.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
3
  • 9
    Я считаю, что оригинальный подход OP не только гораздо более минималистичен, но и более элегантен, чем этот. Кажется излишним писать столько кода, когда метод OP короче и не включает обратные вызовы. Lev 5 авг.
  • Для простых случаев - ты прав. Но для более сложных ситуаций, требующих большого количества кода в обоих случаях, я думаю, что мой подход лучше. Eternal1 5 авг.
  • 4
    В какой сложной ситуации этот подход был бы лучше простого оператора if / else? Jarvl 24 июня '16 в 18:55
20

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

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

Как насчет:

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

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

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

1
  • 3
    Это читается как «если существует вещь» вместо «если вещь существует», которая if($("#thing").exists(){}читается как. Кроме того, это не способ jQuery. 1j01 21 июня '15 в 21:48
16

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

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

16

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

if($("selector").length){
   //code in the case
} 
1
  • 5
    «дать массив» - нет. Он дает вам объект jQuery (который разделяет некоторые свойства с массивом). Ваш ответ по сути такой же, как и у Тима Бете из 2009 года. Quentin 27 апр '16 в 12:33
15

Вот мой любимый 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
    }
);
15

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

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

Вот полный пример различных ситуаций и способ проверить, существует ли элемент с помощью прямого, если селектор 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

Демо

console.log("existing id", $('#id-1').length)
console.log("non existing id", $('#id-2').length)

console.log("existing class single instance", $('.cls-1').length)
console.log("existing class multiple instance", $('.cls-2').length)
console.log("non existing class", $('.cls-3').length)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="id-1">
  <div class="cls-1 cls-2"></div>
  <div class="cls-2"></div>
</div>
1
  • Вы можете попробовать $ ("# xysyxxs") в своем отладчике, и вы увидите, что jquery не возвращает null или undefined. Так что окончательное решение не сработаетBéranger 9 сен '16 в 12:27