Питання Чи існує функція "існує" для jQuery?


Як перевірити наявність елемента у jQuery?

Поточний код, який я маю, це:

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

Чи є більш елегантний спосіб підійти до цього? Можливо, плагін або функція?


2330
2017-08-27 19:49


походження




Відповіді:


У JavaScript все є "truthy" або "falsey", а для чисел 0 (і NaN) означає false, все інше true. Так що ви могли написати:

if ($(selector).length)

Вам це не потрібно >0 частина


2072
2018-02-25 19:16



це викличе помилку, якщо ви використовуєте селектор ідентифікаторів, якщо елемента не існує. перевірити різні тести я зробив ... у моїй відповіді - abhirathore2006
@ abhirathore2006 Якщо ви використовуєте перемикач id, і елемент не існує, тоді довжина 0 і не викидає винятки. - Robert
Цікаво NaN != false. - Robert
@ Роберт і [] + [] = ""... ах я люблю JavaScript - James
@debloker це відео Я думаю, вам сподобається! - James


Так!

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

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

Це відповідає: Подкаст коду Herding Code з Джефом Етвудом


1247
2017-08-27 19:50



Я просто пишу: якщо ($ (selector) .length) (...) без '> 0' - vsync
Твій $.fn.exists приклад замінює пошук нерухомості (дешево!) з двома функціональними викликами, які набагато дорожчі - і один із цих функціональних викликів відтворює вже існуючий об'єкт jQuery, що просто дурний. - C Snover
@redsquare: читабельність коду є найкращим підставою для додавання такого роду функції в jQuery. Маючи щось називається .exists читає чисто, тоді як .length читається як щось семантично інше, навіть якщо семантика збігається з однаковим результатом. - Ben Zotto
@quixoto, вибачте, але .length є стандартом на багатьох мовах, яке не потребує обгортання. Як ще ви інтерпретуєте довжину? - redsquare
На мій погляд, це, принаймні, одна логічна спрямованість від поняття "довжина списку, яка перевищує нуль", до поняття "елемент (и), я написав селектор для існування". Так, вони однаково технічно, але концептуальна абстракція знаходиться на іншому рівні. Це змушує деяких людей віддавати перевагу більш явним показникам, навіть за певних витрат на ефективність. - Ben Zotto


Якщо ви використовували

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 немає значень, то отримання першого елемента в масиві повернеться невизначеною.

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

324
2018-01-14 19:46



Перший метод читається краще. $ ("a"). існує () читається як "якщо <a> елементи існують". $ .exists ("a") читається як "якщо існують <a> елементи". - strager
правда, але знову ж таки, ви майте на увазі, що це ланцюжок можливий, і якщо я намагався зробити щось подібне до $ (selector) .exists (). css ("колір", "червоний") він не працює, а потім я б = * ( - Jon Erickson
Існують вже методи, які не є ланцюговими, як-от attr та функції даних. Я бачу вашу точку, хоча і, для чого це коштує, я просто перевіряю довжину> 0 у будь-якому випадку. - Matthew Crumley
Чому на землі треба це зробити? $(".missing").css("color", "red") вже робить правильну дію ... (тобто нічого) - Ben Blank
Все про ланцюгування завершено - вони є багато з jQuery $.fn методи, які повертають щось інше, ніж новий об'єкт jQuery, і тому не ланцюга. - Alnitak


Ви можете використовувати це:

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

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

98
2018-04-03 12:17



Ти не бачив, що Тим Бюте вже дав це відповісти 2 роки до вас? - Th4t Guy
Pfft, Тім ніколи не показував, як перевірити, чи немає елемента. - Jeremy W
Ви маєте на увазі життя "ще"? Мій Q це: помилка, вона повинна існувати або селектор не збігається. Довжина є зайвою. - RichieHH
ця відповідь та коментарі підсумовують, як працює стекавпотік - aswzen


Найшвидший і найбільш семантично пояснюючий спосіб перевірки наявності є насправді за допомогою простого JavaScript:

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

Писати трохи довше, ніж альтернатива jQuery, але вона виконується швидше, оскільки це рідний метод JS.

І це краще, ніж альтернатива написання власної функції jQuery. Ця альтернатива є повільною, з причин, про які сказано @snover. Але це також дасть іншим програмістам враження, що функція exists () є чимось притаманним jQuery. JavaScript буде / повинно бути зрозумілим іншим редагувати ваш код, без збільшення боргу знань.

NB: Зверніть увагу на відсутність "#" перед елементом element_id (оскільки це звичайний JS, а не jQuery).


73
2018-01-11 12:27



Зовсім не те ж саме. Селектори jQuery можуть бути використані для будь-якого правила CSS - наприклад $('#foo a.special'). І це може повернути більше одного елемента. getElementById не можемо наблизитися до цього. - kikito
Ви правильні тим, що це не таке широке застосування як селектори. Однак, він виконує роботу досить добре в найбільш поширених випадках (перевірка наявності одного елемента). Аргументи самообґрунтування та швидкості все ще стоять. - Magne
@Noz if(document.querySelector("#foo a.special")) буде працювати JQuery не потрібен. - Blue Skies
Аргумент швидкості в двигунах JS тільки мертвий в розумі людей, які не можуть працювати без jQuery, оскільки це аргумент, який вони не можуть перемогти. - Blue Skies
Пам'ятайте старі добрі часи, коли document.getElementById було все, що було у нас? І я завжди забув документ. і не міг зрозуміти, чому це не спрацювало. І я завжди писав це неправильно і отримав кошик персонажа неправильно. - JustJohn


Ви можете зберегти кілька байтів, написавши:

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

Це працює тому, що кожен об'єкт jQuery також маскується як масив, тому ми можемо використовувати оператор десенсування масиву, щоб отримати перший елемент з масив. Це повертається undefined якщо у вказаному індексі немає елемента.


53
2018-01-18 09:04



Я прийшов сюди, щоб опублікувати цю точну відповідь ... обов'язкова скрипка: jsfiddle.net/jasonwilczak/ekjj80gy/2 - JasonWilczak
@JasonWilczak Догляд, щоб коментувати чому не замість:. Eq [0] або .first (), щоб послатися на перший елемент, а не на типове відображення? - Jean Paul A.K.A el_vete
Немає, jQuery.first() або jQuery.eq(0) обидва повертають об'єкти, об'єкти є істинними, навіть якщо вони порожні-іш. Цей приклад повинен проілюструвати, чому ці функції не можуть бути використані як такі: if(jQuery("#does-not-exist").eq(0)) alert("#does-not-exist exists") - Salman A
Правильно. .eq(0) повертає ще один об'єкт jQuery, скорочений до довжини 1 або 0. .first() це просто метод зручності для .eq(0). Але .get(0) повертає перший елемент DOM або undefined і такий же, як і [0]. Перший елемент DOM в об'єкті jQuery зберігається в властивості звичайного об'єкта з ім'ям '0'. Це простий доступ до ресурсів. Лише типове відтворення обумовлено неявним перетворенням числа 0 до ланцюжка '0'. Отже, якщо типове рішення є проблемою, яку ви можете використати $.find(selector)['0'] замість цього. - Robert


Ви можете використовувати:

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

А. мало більш елегантний, мабуть.


50
2017-09-17 17:53



Це занадто для такої простої речі. див. відповідь Тім Бюте - vsync
Це правильна відповідь. Метод 'length' має проблему, що вона дає помилково позитивну з будь-яким числом, наприклад: $ (666). Length // повертає 1, але це недійсний селектор - earnaz
Це надзвичайно дорого для дуже простих завдань. Просто перегляньте реалізацію jquery, якщо .is (), і ви побачите, скільки коду потрібно обробляти, щоб відповісти на це просте запитання. Також це не є очевидним що ви захочете зробити точно, так це є той же, або, можливо, менш елегантний тоді розглянутий розгляд. - micropro.cz
@earnaz відмінна точка, приємний вилов. Я не бачу, де це насправді варто турбуватися. Devs, що ідентифікують елементи з 666 напевно, є багато інших причин, через що їх код порушений. Хоча це недійсний селектор, $ (666). Length дійсний javascript: Він оцінює істинність, і тому повинен задовольнити умови. - Todd
@earnaz, щоб уникнути цього конкретного випадку, $.find(666).length працює - Emile Bergeron


Цей плагін може бути використаний в 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    */
    }
})

48
2017-11-14 14:20



У версії зворотного виклику не слід Has Items Зворотний дзвінок насправді передає об'єкт як аргумент? - Chris Marisic


JQuery дійсно не потрібна. З простим JavaScript це простіше і семантично правильно перевірити на:

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

Якщо з якихось причин ви не бажаєте додавати ідентифікатор до елемента, ви все ще можете використовувати будь-який інший метод JavaScript, призначений для доступу до DOM.

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


44
2018-05-20 09:21



Я знаю: він не відповідає безпосередньо на оригінальне запитання (який вимагає функції jQuery), але в такому випадку відповідь буде "ні" або "не семантично правильне рішення". - amypellegrini


Я бачу, що більшість відповідей тут не точні, як вони повинні бути, вони перевіряють довжину елемента, це може бути добре в багатьох випадках, але не 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

40
2018-06-01 07:20