Czy istnieje funkcja „istnieje” dla jQuery?

2778

Jak mogę sprawdzić istnienie elementu w jQuery?

Obecny kod, który mam, to:

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

Czy istnieje bardziej elegancki sposób na to? Być może wtyczka lub funkcja?

Jake McGraw
źródło

Odpowiedzi:

2489

W JavaScript wszystko jest „prawdą” lub „fałszem”, a dla liczb 0(i NaN) oznacza falsewszystko inne true. Abyś mógł napisać:

if ($(selector).length)

Nie potrzebujesz tej >0części.

Tim Büthe
źródło
52
@ abhirathore2006 Jeśli użyjesz selektora id, a element nie istnieje, długość wynosi 0 i nie zgłasza wyjątków.
Robert
14
Co ciekawe NaN != false.
Robert
35
@Robert i [] + []= ""... ahh Uwielbiam javascript
James
9
@James To dlatego, że [].toString() === [].join(',') === ""i "" === "".
Ismael Miguel
5
@Robert itypeof NaN == 'number'
oriadam
1356

Tak!

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

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

Jest to odpowiedź na: podcast Herding Code z Jeffem Atwoodem

Jake McGraw
źródło
254
Po prostu piszę: if ($ (selektor) .length) {...} bez „> 0”
vsync
369
Twój $.fn.existsprzykład jest zastąpienie własności odnośnika (tanio!) Z dwoma wywołań funkcji, które są znacznie droższe, a jeden z tych wywołań funkcji odtwarza obiekt jQuery, które już masz, co jest po prostu głupie.
C Snover
212
@redsquare: Czytelność kodu jest najlepszym uzasadnieniem dodania tego rodzaju funkcji do jQuery. Posiadanie czegoś zwanego .existsczyta się czysto, podczas gdy .lengthczyta się jako coś semantycznie odmiennego, nawet jeśli semantyka pokrywa się z identycznym wynikiem.
Ben Zotto,
48
@quixoto, przepraszam, ale .length jest standardem w wielu językach i nie wymaga pakowania. Jak inaczej interpretujesz długość.
redsquare
144
Moim zdaniem jest to co najmniej jedna logiczna pośrednia koncepcja od „długości listy większej niż zero” do koncepcji „elementu (ów), dla którego napisałem selektor dla istnienia”. Tak, technicznie to samo, ale abstrakcja pojęciowa jest na innym poziomie. To powoduje, że niektórzy wolą bardziej wyraźny wskaźnik, nawet przy pewnym koszcie wydajności.
Ben Zotto,
377

Jeśli używałeś

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

sugerowałbyś, że tworzenie łańcuchów było możliwe, gdy tak nie jest.

Byłoby lepiej:

jQuery.exists = function(selector) {return ($(selector).length > 0);}
if ($.exists(selector)) { }

Alternatywnie z FAQ :

if ( $('#myDiv').length ) { /* Do something */ }

Możesz również skorzystać z poniższych. Jeśli w tablicy obiektów jQuery nie ma żadnych wartości, uzyskanie pierwszego elementu w tablicy zwróci niezdefiniowane.

if ( $('#myDiv')[0] ) { /* Do something */ }
Jon Erickson
źródło
11
Pierwsza metoda brzmi lepiej. $ („a”). istnieje () brzmi „jeśli istnieją elementy <a>”. $ .exists („a”) brzmi „jeśli istnieją elementy <a>”.
strager
16
prawda, ale znowu sugerujesz, że tworzenie łańcuchów jest możliwe, a gdybym spróbował zrobić coś takiego jak $ (selektor) .exists (). css („kolor”, „czerwony”), to nie zadziałałoby, a wtedy byłbym = * (
Jon Erickson
19
Istnieją już metody, których nie można łączyć, takie jak funkcje attr i danych. Rozumiem jednak twój punkt widzenia i, o ile jest to warte, po prostu testuję dla długości> 0.
Matthew Crumley
39
Dlaczego, u licha, miałbyś to wiązać? $(".missing").css("color", "red")już robi właściwą rzecz… (tj. nic)
Ben Blank
15
Sprawy związane z łańcuchem są kompletne - istnieje wiele$.fn metod jQuery , które zwracają coś innego niż nowy obiekt jQuery i dlatego nie łączą łańcuchów.
Alnitak
136

Możesz użyć tego:

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

// if element does not exist
if(!$('selector').length){ /* do something */ }
Yanni
źródło
134
Nie widziałeś, że Tim Büthe udzielił już tej odpowiedzi 2 lata przed tobą?
Th4t Guy
101
Pfft, Tim nigdy nie pokazał, jak sprawdzić, czy element nie istnieje.
Jeremy W,
1
Masz na myśli życie „jeszcze”? Moje Q jest następujące: err, musi istnieć lub selektor nie pasuje. Długość jest zbyteczna.
RichieHH
26
ta odpowiedź i komentarze podsumowują działanie stackoverflow
aswzen
101

Najszybszym i najbardziej semantycznie samo wyjaśniającym sposobem sprawdzenia istnienia jest użycie zwykłego JavaScript:

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

Trochę dłużej trwa pisanie niż alternatywa jQuery, ale działa szybciej, ponieważ jest to natywna metoda JS.

I to jest lepsze niż alternatywa pisania własnej jQueryfunkcji. Ta alternatywa jest wolniejsza z powodów podanych przez @snover. Ale dałoby to również innym programistom wrażenie, że exists()funkcja jest nieodłączną częścią jQuery. JavaScriptbędą / powinny być rozumiane przez innych, którzy edytują Twój kod, bez zwiększonego zadłużenia z wiedzy.

Uwaga: zauważ brak „#” przed element_id(ponieważ jest to zwykły JS, nie jQuery).

Magne
źródło
56
Zupełnie nie to samo. Selektorów JQuery można użyć dla dowolnej reguły CSS - na przykład $('#foo a.special'). I może zwrócić więcej niż jeden element. getElementByIdnie mogę do tego podejść.
kikito
7
Masz rację, ponieważ nie ma tak szerokiego zastosowania jak selektory. Jednak wykonuje to zadanie całkiem dobrze w najczęstszym przypadku (sprawdzanie, czy istnieje pojedynczy element). Argumenty dotyczące wyjaśnienia i szybkości są nadal aktualne.
Magne
29
@Noz if(document.querySelector("#foo a.special"))będzie działać. Nie wymaga jQuery.
Blue Skies
34
Argument prędkości w silnikach JS jest martwy tylko w umyśle ludzi, którzy nie mogą funkcjonować bez jQuery, ponieważ to argument, którego nie mogą wygrać.
Blue Skies
22
Pamiętasz stare dobre czasy, kiedy document.getElementById było wszystkim, co mieliśmy? I zawsze zapomniałem o dokumencie. i nie mogłem zrozumieć, dlaczego to nie zadziałało. I zawsze źle to napisałem i źle zrobiłem obudowę postaci.
JustJohn,
73

Możesz zapisać kilka bajtów, pisząc:

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

Działa to, ponieważ każdy obiekt jQuery również podszywa się pod tablicę, więc możemy użyć operatora dereferencji tablicy, aby uzyskać pierwszy element z tablicy . Zwraca, undefinedjeśli nie ma pozycji o podanym indeksie.

Salman A.
źródło
1
Przyszedłem tutaj, aby opublikować tę dokładną odpowiedź ... obowiązkowe skrzypce: jsfiddle.net/jasonwilczak/ekjj80gy/2
JasonWilczak
3
@JasonWilczak Staraj się komentować, dlaczego nie zamiast tego: .eq [0] lub .first () w odniesieniu do pierwszego znalezionego elementu zamiast rzutowania typu?
Jean Paul AKA el_vete
5
Nie, jQuery.first()lub jQuery.eq(0)oba zwracają obiekty, obiekty są prawdziwe, nawet jeśli są puste. Ten przykład powinien zilustrować, dlaczego tych funkcji nie można używać if(jQuery("#does-not-exist").eq(0)) alert("#does-not-exist exists")
Salman A
1
Poprawny. .eq(0)zwraca tylko kolejny obiekt jQuery obcięty do długości 1 lub 0. .first()To tylko wygodna metoda .eq(0). Ale .get(0)zwraca pierwszy element DOM lub undefinedjest taki sam jak [0]. Pierwszy element DOM w obiekcie jQuery jest przechowywany we właściwości zwykłego obiektu o nazwie '0'. To prosty dostęp do nieruchomości. Jedyny typ rzutowania wynika z niejawnej konwersji liczby 0na ciąg '0'. Jeśli więc rzutowanie tekstu jest problemem, możesz $.find(selector)['0']zamiast tego użyć .
Robert
66

Możesz użyć:

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

Może trochę bardziej elegancki.

Devon
źródło
38
To za dużo na tak prostą rzecz. patrz odpowiedź Tim Büthe
vsync
To jest poprawna odpowiedź. W metodzie „długość” występuje problem polegający na tym, że daje fałszywie dodatnią dowolną liczbę, na przykład: $ (666). Długość // zwraca 1, ale nie jest to prawidłowy selektor
earnaz
Jest to niezwykle kosztowne w przypadku bardzo prostego zadania. Wystarczy spojrzeć na implementację jquery, jeśli .is (), a zobaczysz, ile kodu musi przetworzyć, aby odpowiedzieć na to proste pytanie. Nie jest też oczywiste, co dokładnie chcesz zrobić, więc jest to samo lub może mniej eleganckie rozwiązanie niż to, o którym mowa.
micropro.cz
1
@earnaz great point, nice catch. Nie wiem jednak, gdzie jest to naprawdę warte uwagi. Twórcy identyfikujący elementy 666prawdopodobnie mają wiele innych powodów, dla których ich kod jest uszkodzony. Chociaż jest to niepoprawny selektor, $ (666) .length jest prawidłowym skryptem javascript : ocenia na prawdę i dlatego powinien spełniać warunek.
Todd
@earnaz, aby uniknąć tego konkretnego przypadku, $.find(666).lengthdziała.
Emile Bergeron,
66

Wtyczki tej można użyć w ifinstrukcji takiej jak if ($(ele).exist()) { /* DO WORK */ }lub przy użyciu wywołania zwrotnego.

Podłącz

;;(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

Możesz określić jeden lub dwa połączenia zwrotne. Pierwszy uruchomi się, jeśli element istnieje, drugi uruchomi się, jeśli element nie istnieje. Jeśli jednak wybierzesz przekazanie tylko jednej funkcji, zadziała ona tylko wtedy, gdy element istnieje. Zatem łańcuch umrze, jeśli wybrany element nie istnieje. Oczywiście, jeśli istnieje, uruchomi się pierwsza funkcja i łańcuch będzie kontynuowany.

Pamiętaj, że użycie wariantu wywołania zwrotnego pomaga utrzymać łańcuchowość - element jest zwracany i możesz kontynuować tworzenie łańcuchów poleceń jak w przypadku każdej innej metody jQuery!

Przykładowe zastosowania

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    */
    }
})
SpYk3HH
źródło
1
Czy w wersji wywołania zwrotnego nie powinno ono Has Itemsfaktycznie przekazać obiektu jako argumentu?
Chris Marisic
62

Widzę, że większość odpowiedzi tutaj nie jest dokładna, jak powinny, sprawdzają długość elementu, w wielu przypadkach może być OK , ale nie 100% , wyobraź sobie, że zamiast tego liczba przechodzi do funkcji, więc prototypuję funkcję, która sprawdza wszystkie warunki i zwróć odpowiedź tak, jak powinna:

$.fn.exists = $.fn.exists || function() { 
  return !!(this.length && (this[0] instanceof HTMLDocument || this[0] instanceof HTMLElement)); 
}

Spowoduje to sprawdzenie zarówno długości, jak i typu. Teraz możesz to sprawdzić w ten sposób:

$(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
Alireza
źródło
55

Tak naprawdę nie ma potrzeby korzystania z jQuery. Dzięki zwykłemu JavaScriptowi łatwiej i semantycznie poprawne jest sprawdzenie:

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

Jeśli z jakiegoś powodu nie chcesz wstawiać identyfikatora do elementu, nadal możesz użyć dowolnej innej metody JavaScript zaprojektowanej w celu uzyskania dostępu do DOM.

jQuery jest naprawdę fajny, ale nie pozwól, aby czysty JavaScript popadł w zapomnienie ...

amypellegrini
źródło
5
Wiem: nie odpowiada bezpośrednio na pierwotne pytanie (które wymaga funkcji jquery), ale w takim przypadku odpowiedź brzmiałaby „Nie” lub „nie semantycznie poprawne rozwiązanie”.
amypellegrini
Co jeśli potrzebujesz selektora rodzica :has()?
Константин Ван
54

Możesz użyć tego:

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

if($(selector).exists()){/*do something*/}
Amitabha
źródło
43

Powodem, dla którego wszystkie poprzednie odpowiedzi wymagają tego .lengthparametru, jest to, że najczęściej używają $()selektora jquery, który ma querySelectorAll za zasłonami (lub używają go bezpośrednio). Ta metoda jest raczej powolna, ponieważ musi przeanalizować całe drzewo DOM w poszukiwaniu wszystkich dopasowań do tego selektora i zapełnić je tablicą.

Parametr [„długość”] nie jest potrzebny ani przydatny, a kod będzie znacznie szybszy, jeśli użyjesz go bezpośrednio document.querySelector(selector), ponieważ zwraca pierwszy zgodny element lub null, jeśli nie zostanie znaleziony.

function elementIfExists(selector){  //named this way on purpose, see below
    return document.querySelector(selector);
}
/* usage: */
var myelement = elementIfExists("#myid") || myfallbackelement;

Jednak ta metoda pozostawia nam zwracany obiekt; co jest w porządku, jeśli nie będzie zapisywane jako zmienne i używane wielokrotnie (w ten sposób zachowamy odniesienie, jeśli zapomnimy).

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

W niektórych przypadkach może to być pożądane. Można go użyć w pętli 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;

Jeśli tak naprawdę nie potrzebujesz tego elementu i chcesz uzyskać / zapisać tylko wartość prawda / fałsz, po prostu nie podwój! Działa z butami, które nie są rozwiązywane, więc po co tu węzeł?

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);
technozaur
źródło
40

Czy $.contains()chcesz

jQuery.contains( container, contained )

$.contains()Sposób powraca prawdziwe, jeżeli element DOM przez drugi argument jest potomkiem elementu DOM przez pierwszy argument czy bezpośredni dziecko lub zagnieżdżone głębiej. W przeciwnym razie zwraca false. Obsługiwane są tylko węzły elementów; jeśli drugi argument jest węzłem tekstowym lub komentarzem, $.contains()zwróci false.

Uwaga : Pierwszy argument musi być elementem DOM, a nie obiektem jQuery lub zwykłym obiektem JavaScript.

Autostrada
źródło
3
To nie akceptuje selektora, co oznacza, że ​​musiałby go wybrać, co oznacza, że ​​mógł po prostu sprawdzić wynik swojego wyboru.
39

Stwierdziłem, if ($(selector).length) {}że jest niewystarczający. Cicho zepsuje Twoją aplikację, gdy selectorjest pustym obiektem {}.

var $target = $({});        
console.log($target, $target.length);

// Console output:
// -------------------------------------
// [▼ Object              ] 1
//    ► __proto__: Object

Moją jedyną propozycją jest wykonanie dodatkowej kontroli {}.

if ($.isEmptyObject(selector) || !$(selector).length) {
    throw new Error('Unable to work with the given selector.');
}

Wciąż szukam lepszego rozwiązania, ponieważ jest ono trochę ciężkie.

Edycja: OSTRZEŻENIE! To nie działa w IE, gdy selectorjest ciągiem.

$.isEmptyObject('hello') // FALSE in Chrome and TRUE in IE
Oleg
źródło
12
Jak często zdarza ci się dzwonić $()z pustym obiektem jako argumentem?
nnnnnn
@ nnnnnn Właściwie nigdy (już nie używam jQuery). Ale wydaje mi się, że 3 lata temu miałem przypadek ujawnienia interfejsu API, który wziąłby selektor i zwrócił liczbę elementów dla tego selektora. Jeśli inny dev przejdzie do pustego obiektu, niepoprawnie zareaguje na 1.
Oleg
3
Dlaczego na ziemi byłoby przekazać pusty obiekt {}do $()?
Wszyscy pracownicy są niezbędni
7
@cpburnz dlaczego mnie pytasz? Byłem tylko dostawcą API ... Ludzie przekazują API wszelkiego rodzaju głupie rzeczy.
Oleg
4
Właśnie zauważyłem, że wątek dotyczący jquery, do którego odwoływał się @FagnerBrack, został zaktualizowany wkrótce po jego komentarzu; wygląda na to, że wcale nie odchodzi.
Joseph Gabriel
38

Możesz sprawdzić, czy element jest obecny lub nie używa długości w skrypcie Java. Jeśli długość jest większa od zera, wówczas element jest obecny, jeśli długość wynosi zero, wówczas element nie jest obecny

// 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
}
Anurag Deokar
źródło
4
Nie musisz sprawdzać, czy długość pogody jest większa niż 0, jeśli ($ ('# elementid'). Length) {} będzie wystarczające.
Pranav Labhe
13
Czy rzeczywiście przeczytałeś pytanie? Jest to dokładnie ta sama metoda, której używa OP.
A1rPun,
34

Sprawdzanie istnienia elementu jest starannie udokumentowane na oficjalnej stronie jQuery!

Użyj właściwości .length kolekcji jQuery zwróconej przez selektor:

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

Pamiętaj, że nie zawsze konieczne jest sprawdzenie, czy element istnieje. Poniższy kod pokaże element, jeśli istnieje, i nie rób nic (bez błędów), jeśli nie istnieje:

$("#myDiv").show();
Tilak Maddy
źródło
31

jest to bardzo podobne do wszystkich odpowiedzi, ale dlaczego nie użyć !operatora dwa razy, aby uzyskać wartość logiczną:

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

if ($(selector).exists()) {
    // the element exists, now what?...
}
Santiago Hernández
źródło
2
Ponieważ czasamiBoolean(x) może być bardziej wydajny.
28
$(selector).length && //Do something
SJG
źródło
19
Nienawidzę tych sprytnych sposobów unikania aby użyć ifgdy ifpoprawi czytelność kosztem 2 bajty.
Emile Bergeron,
Dodatkowo, minizatory zrobią to wszystko &&za Ciebie.
27

Spróbuj przetestować dla DOMelementu

if (!!$(selector)[0]) // do stuff
guest271314
źródło
27

Zainspirowany odpowiedzią hiway wymyśliłem:

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

jQuery.contains pobiera dwa elementy DOM i sprawdza, czy pierwszy zawiera drugi.

Użycie document.documentElementjako pierwszego argumentu spełnia semantykęexists metody, gdy chcemy ją zastosować wyłącznie w celu sprawdzenia istnienia elementu w bieżącym dokumencie.

Poniżej umieściłem razem fragment, który porównuje jQuery.exists()przeciwko $(sel)[0]i $(sel).lengthpodejść, które zwracają truthywartości $(4)podczas $(4).exists()powrotów false. W kontekście sprawdzania istnienia elementu w DOM wydaje się to pożądanym rezultatem .

Oliver
źródło
26

Brak potrzeby jQuery (podstawowe rozwiązanie)

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

Znacznie bardziej wydajna opcja poniżej (zauważ brak kropki przed klasą).

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

querySelector używa odpowiedniego silnika dopasowującego, takiego jak $ () (skwierczenie) w jQuery i zużywa więcej mocy obliczeniowej, ale w 99% przypadków da sobie radę. Druga opcja jest bardziej wyraźna i mówi kodowi, co dokładnie zrobić. Jest znacznie szybszy według jsperf https://jsperf.com/getelementsbyclassname-vs-queryselectorall/25

Paweł
źródło
25

Po prostu lubię używać do tego zwykłego javascript waniliowego.

function isExists(selector){
  return document.querySelectorAll(selector).length>0;
}
Sanu Uthaiah Bollera
źródło
23

Natknąłem się na to pytanie i chciałbym udostępnić fragment kodu, którego obecnie używam:

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

A teraz mogę napisać taki kod -

$("#elem").exists(function(){
    alert ("it exists");
}).otherwise(function(){
    alert ("it doesn't exist");
});

Może wydawać się dużo kodu, ale napisany w CoffeeScript jest dość mały:

$.fn.exists = (callback) ->
    exists = @length
    callback.call() if exists        
    new class
       otherwise: (fallback) ->            
            fallback.call() if not exists
Eternal 1
źródło
9
Uważam, że oryginalne podejście OP jest nie tylko znacznie bardziej minimalne, ale także bardziej eleganckie. Wydaje się, że przesadne jest pisanie tak dużej ilości kodu, gdy metoda OP jest krótsza i nie wymaga wywołań zwrotnych.
Lev
W prostych przypadkach - masz rację. Ale w przypadku bardziej skomplikowanych sytuacji z dużą ilością kodu w obu przypadkach myślę, że moje podejście jest lepsze.
Eternal1
4
W jakiej złożonej sytuacji takie podejście byłoby lepsze niż proste stwierdzenie „jeśli / inaczej”?
Jarvl
19

Miałem przypadek, w którym chciałem sprawdzić, czy jakiś obiekt istnieje w innym, więc dodałem coś do pierwszej odpowiedzi, aby sprawdzić selektor wewnątrz selektora.

// 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;
};
jcreamer898
źródło
18

Co powiesz na:

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

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

Jest to bardzo minimalne i oszczędza konieczności $()każdorazowego zamykania selektora .

GWIAZDA G
źródło
3
To brzmi „jeśli istnieje rzecz” zamiast „jeśli coś istnieje”, co if($("#thing").exists(){}brzmi jak. Poza tym nie jest to jQuery.
1j01
15

Używam tego:

    $.fn.ifExists = function(fn) {
      if (this.length) {
        $(fn(this));
      }
    };
    $("#element").ifExists( 
      function($this){
        $this.addClass('someClass').animate({marginTop:20},function(){alert('ok')});               
      }
    ); 

Wykonaj łańcuch tylko wtedy, gdy istnieje element jQuery - http://jsfiddle.net/andres_314/vbNM3/2/

andy_314
źródło
14

Oto moja ulubiona existmetoda w jQuery

$.fn.exist = function(callback) {
    return $(this).each(function () {
        var target = $(this);

        if (this.length > 0 && typeof callback === 'function') {
            callback.call(target);
        }
    });
};

oraz inna wersja obsługująca oddzwanianie, gdy selektor nie istnieje

$.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);
            }
        }
    });
};

Przykład:

$('#foo .bar').exist(
    function () {
        // Stuff when '#foo .bar' exists
    },
    function () {
        // Stuff when '#foo .bar' does not exist
    }
);
ducdhm
źródło
14

$("selector") zwraca obiekt, który ma lengthwłaściwość. Jeśli selektor znajdzie jakieś elementy, zostaną one uwzględnione w obiekcie. Jeśli więc sprawdzisz jego długość, zobaczysz, czy istnieją jakieś elementy. W JavaScript 0 == false, więc jeśli nie dostaniesz 0kodu, uruchomi się.

if($("selector").length){
   //code in the case
} 
Kamuran Sönecek
źródło
5
„daj tablicę” - Nie, nie ma. Daje ci obiekt jQuery (który ma pewne właściwości z tablicą). Twoja odpowiedź jest zasadniczo taka sama jak u Tima Büthe'a z 2009 roku.
Quentin
11

Oto kompletny przykład różnych sytuacji i sposobu sprawdzenia, czy element istnieje przy użyciu direct, jeśli na jQuery selektor może działać lub nie, ponieważ zwraca tablicę lub elementy.

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

OSTATECZNE ROZWIĄZANIE

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
abhirathore2006
źródło
Możesz wypróbować $ („# xysyxxs”) w swoim debuggerze, zobaczysz, że jquery nie zwraca wartości null ani niezdefiniowanej. Tak więc ostateczne rozwiązanie nie zadziałałoby
Béranger
11

Nie musisz sprawdzać, czy jest większy niż 0podoba $(selector).length > 0, $(selector).lengthwystarczy i jest to elegancki sposób na sprawdzenie istnienia elementów. Nie sądzę, że warto napisać funkcję tylko do tego, jeśli chcesz zrobić więcej dodatkowych rzeczy, tak.

if($(selector).length){
  // true if length is not 0
} else {
  // false if length is 0
}
Andrei Todorut
źródło