Câu hỏi Có một chức năng "tồn tại" cho jQuery?


Làm thế nào tôi có thể kiểm tra sự tồn tại của một phần tử trong jQuery?

Mã hiện tại mà tôi có là:

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

Có cách nào thanh lịch hơn để tiếp cận điều này không? Có lẽ một plugin hoặc một chức năng?


2330
2017-08-27 19:49


gốc




Các câu trả lời:


Trong JavaScript, mọi thứ đều 'trung thực' hoặc 'giả' và đối với số 0 (và NaN) có nghĩa là false, mọi thứ khác true. Vì vậy, bạn có thể viết:

if ($(selector).length)

Bạn không cần điều đó >0 phần.


2072
2018-02-25 19:16



điều này sẽ ném lỗi nếu bạn sử dụng bộ chọn Id nếu phần tử không tồn tại. kiểm tra các bài kiểm tra khác nhau tôi đã làm ... trong câu trả lời của tôi - abhirathore2006
@ abhirathore2006 Nếu bạn sử dụng một bộ chọn id và phần tử không tồn tại thì độ dài là 0 và không ném ngoại lệ. - Robert
Thú vị đủ NaN != false. - Robert
@ Robert và [] + [] = ""... ahh Tôi yêu javascript - James
@deblocker heres một video Tôi nghĩ bạn sẽ thích! - James


Vâng!

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

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

Đây là để đáp ứng với: Herding Code podcast với Jeff Atwood


1247
2017-08-27 19:50



Tôi chỉ viết: if ($ (selector) .length) {...} không có '> 0' - vsync
Của bạn $.fn.exists Ví dụ là thay thế một tra cứu tài sản (giá rẻ!) với hai cuộc gọi hàm, đắt hơn nhiều - và một trong những hàm gọi lại đó tạo lại một đối tượng jQuery mà bạn đã có, điều này chỉ là ngớ ngẩn. - C Snover
@redsquare: Khả năng đọc mã là lý do tốt nhất để thêm loại hàm này vào jQuery. Có thứ gọi là .exists đọc sạch, trong khi .length đọc như một cái gì đó ngữ nghĩa khác nhau, ngay cả khi ngữ nghĩa trùng với một kết quả giống hệt nhau. - Ben Zotto
@quixoto, xin lỗi nhưng .length là một tiêu chuẩn trên nhiều ngôn ngữ không cần gói. Bạn giải thích như thế nào .length? - redsquare
Theo ý kiến ​​của tôi, đó là ít nhất một sự vô đạo đức hợp lý từ khái niệm "chiều dài danh sách lớn hơn 0" đối với khái niệm "phần tử (s) tôi đã viết một bộ chọn để tồn tại". Vâng, chúng giống nhau về mặt kỹ thuật, nhưng khái niệm trừu tượng ở mức độ khác. Điều này khiến một số người thích một chỉ báo rõ ràng hơn, ngay cả ở một số chi phí hiệu suất. - Ben Zotto


Nếu bạn đã sử dụng

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

bạn sẽ ngụ ý rằng chuỗi có thể xảy ra khi nó không có.

Điều này sẽ tốt hơn:

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

Ngoài ra, từ câu hỏi thường gặp:

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

Bạn cũng có thể sử dụng như sau. Nếu không có giá trị trong mảng đối tượng jQuery thì việc lấy mục đầu tiên trong mảng sẽ trả về không xác định.

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

324
2018-01-14 19:46



Phương pháp đầu tiên đọc tốt hơn. $ ("a"). tồn tại () đọc là "nếu <a> phần tử tồn tại." $ .exists ("a") đọc là "nếu có <a> phần tử". - strager
đúng nhưng một lần nữa, bạn ngụ ý rằng chuỗi là có thể và nếu tôi đã cố gắng làm một cái gì đó như $ (selector) .exists (). css ("color", "red") nó sẽ không hoạt động và sau đó tôi sẽ = * ( - Jon Erickson
Đã có các phương thức không có khả năng tạo chuỗi, như hàm attr và dữ liệu. Tôi thấy điểm của bạn mặc dù, và đối với những gì nó có giá trị, tôi chỉ cần kiểm tra chiều dài> 0 anyways. - Matthew Crumley
Tại sao trên trái đất bạn sẽ cần phải chuỗi này? $(".missing").css("color", "red") đã làm điều đúng ... (nghĩa là không có gì) - Ben Blank
Những thứ về chuỗi là hoàn thành tosh - có nhiều của jQuery $.fn các phương thức trả về một cái gì đó khác với một đối tượng jQuery mới và do đó không có chuỗi. - Alnitak


Bạn có thể sử dụng điều này:

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

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

98
2018-04-03 12:17



Bạn không thấy rằng Tim Büthe đã đưa ra điều này câu trả lời 2 năm trước bạn? - Th4t Guy
Pfft, Tim không bao giờ cho thấy làm thế nào để kiểm tra nếu phần tử không tồn tại. - Jeremy W
Bạn có nghĩa là cuộc sống "khác"? Q của tôi là: err, nó phải tồn tại hoặc bộ chọn không khớp. Chiều dài là thừa. - RichieHH
câu trả lời và nhận xét này tóm tắt cách hoạt động của stackoverflow - aswzen


Cách tự giải thích nhanh nhất và ngữ nghĩa nhất để kiểm tra sự tồn tại thực sự là bằng cách sử dụng JavaScript đơn giản:

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

Nó dài hơn một chút so với thay thế chiều dài của jQuery, nhưng thực thi nhanh hơn vì nó là một phương thức JS gốc.

Và nó là tốt hơn so với thay thế bằng cách viết chức năng jQuery của riêng bạn. Thay thế đó chậm hơn, vì những lý do @snover đã nêu. Nhưng nó cũng sẽ cung cấp cho các lập trình viên khác ấn tượng rằng hàm tồn tại () là một cái gì đó vốn có của jQuery. JavaScript sẽ / nên được hiểu bởi những người khác chỉnh sửa mã của bạn, mà không tăng nợ kiến ​​thức.

Lưu ý: thiếu một '#' trước phần tử element_id (vì đây là JS đơn giản, không phải jQuery).


73
2018-01-11 12:27



Hoàn toàn không giống nhau. Bộ chọn JQuery có thể được sử dụng cho bất kỳ quy tắc CSS nào - ví dụ $('#foo a.special'). Và nó có thể trả lại nhiều hơn một phần tử. getElementById không thể bắt đầu tiếp cận điều đó. - kikito
Bạn chính xác ở chỗ nó không được áp dụng rộng rãi như các bộ chọn. Tuy nhiên, nó thực hiện công việc khá tốt trong trường hợp phổ biến nhất (kiểm tra nếu một phần tử duy nhất tồn tại). Các lý lẽ về tự giải thích và tốc độ vẫn đứng vững. - Magne
@Noz if(document.querySelector("#foo a.special")) sẽ hoạt động. Không cần jQuery. - Blue Skies
Lập luận về tốc độ trong các động cơ JS chỉ chết trong tâm trí của những người không thể hoạt động mà không có jQuery, vì đó là một đối số mà họ không thể thắng. - Blue Skies
Hãy nhớ những ngày xưa tốt đẹp khi document.getElementById là tất cả những gì chúng tôi có? Và tôi luôn quên tài liệu. và không thể hiểu tại sao nó không hoạt động. Và tôi luôn đánh vần sai và có nhân vật sai. - JustJohn


Bạn có thể lưu một vài byte bằng cách viết:

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

Điều này làm việc vì mỗi đối tượng jQuery cũng giả mạo như một mảng, vì vậy chúng ta có thể sử dụng toán tử dereferencing mảng để lấy mục đầu tiên từ mảng. Nó trở lại undefined nếu không có mục nào ở chỉ mục được chỉ định.


53
2018-01-18 09:04



Tôi đến đây để đăng câu trả lời chính xác này ... jsfiddle.net/jasonwilczak/ekjj80gy/2 - JasonWilczak
@JasonWilczak Chăm sóc để bình luận lý do tại sao không thay vì: .eq [0] hoặc .first () để chỉ một yếu tố đầu tiên tìm thấy chứ không phải là loại đúc? - Jean Paul A.K.A el_vete
Không, jQuery.first() hoặc là jQuery.eq(0) cả hai đối tượng trả về, các đối tượng là sự thật ngay cả khi chúng trống rỗng. Ví dụ này sẽ minh họa tại sao các hàm này không thể được sử dụng như là: if(jQuery("#does-not-exist").eq(0)) alert("#does-not-exist exists") - Salman A
Chính xác. .eq(0) trả về chỉ một đối tượng jQuery khác được cắt ngắn thành độ dài 1 hoặc 0. .first() chỉ là một phương pháp tiện lợi cho .eq(0). Nhưng .get(0) trả về phần tử DOM đầu tiên hoặc undefined và giống như [0]. Phần tử DOM đầu tiên trong một đối tượng jQuery được lưu trữ trong thuộc tính đối tượng thông thường với tên '0'. Đó là một truy cập tài sản đơn giản. Loại đúc duy nhất bắt nguồn từ việc chuyển đổi ngầm định số 0 vào chuỗi '0'. Vì vậy, nếu loại đúc là một vấn đề bạn có thể sử dụng $.find(selector)['0'] thay thế. - Robert


Bạn có thể dùng:

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

A ít thanh lịch hơn, có lẽ.


50
2017-09-17 17:53



Đây là quá nhiều cho một điều đơn giản như vậy. xem Tim Büthe trả lời - vsync
Đây là câu trả lời chính xác. Phương thức 'length' có vấn đề là nó cho kết quả dương tính giả với bất kỳ số nào, ví dụ: $ (666) .length // trả về 1, nhưng nó không phải là một bộ chọn hợp lệ - earnaz
Điều này cực kỳ tốn kém cho công việc rất đơn giản. Chỉ cần nhìn vào thực thi jquery nếu .is () và bạn sẽ thấy bao nhiêu mã nó cần xử lý để trả lời cho bạn câu hỏi đơn giản này. Ngoài ra nó không phải là rõ ràng những gì bạn muốn làm chính xác, vì vậy nó là như nhau hoặc có thể ít thanh lịch sau đó giải pháp trong câu hỏi. - micropro.cz
@ learnaz điểm tuyệt vời, bắt tốt đẹp. Tuy nhiên, tôi không thấy đây thực sự là một mối quan tâm đáng giá. Devs xác định các yếu tố với 666 có thể có nhiều lý do khác khiến mã của họ bị hỏng. Trong khi đó là bộ chọn không hợp lệ, $ (666) .length là javascript hợp lệ: Nó đánh giá sự thật, và do đó Nên thỏa mãn điều kiện. - Todd
@earnaz để tránh trường hợp cụ thể đó, $.find(666).length công trinh. - Emile Bergeron


Plugin này có thể được sử dụng trong một if tuyên bố như if ($(ele).exist()) { /* DO WORK */ } hoặc sử dụng gọi lại.

Cắm vào

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

Bạn có thể chỉ định một hoặc hai cuộc gọi lại. Người đầu tiên sẽ kích hoạt nếu phần tử tồn tại, phần tử thứ hai sẽ kích hoạt nếu phần tử đó không phải hiện hữu. Tuy nhiên, nếu bạn chọn chỉ truyền một hàm, nó sẽ chỉ kích hoạt khi phần tử tồn tại. Do đó, chuỗi sẽ chết nếu phần tử đã chọn không không phải hiện hữu. Tất nhiên, nếu nó tồn tại, chức năng đầu tiên sẽ cháy và chuỗi sẽ tiếp tục.

Hãy nhớ rằng sử dụng biến thể gọi lại giúp duy trì khả năng chainability - phần tử được trả về và bạn có thể tiếp tục chuỗi lệnh như với bất kỳ phương thức jQuery nào khác!

Sử dụng ví dụ

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



Trên phiên bản gọi lại, không nên Has Items gọi lại thực sự vượt qua trong đối tượng như một đối số? - Chris Marisic


Không cần jQuery thực sự. Với JavaScript đơn giản, nó dễ dàng hơn và đúng ngữ nghĩa để kiểm tra:

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

Nếu vì bất kỳ lý do nào bạn không muốn đặt id cho phần tử, bạn vẫn có thể sử dụng bất kỳ phương thức JavaScript nào khác được thiết kế để truy cập DOM.

jQuery thực sự tuyệt vời, nhưng đừng để JavaScript thuần túy rơi vào quên lãng ...


44
2018-05-20 09:21



Tôi biết: nó không trả lời trực tiếp câu hỏi gốc (yêu cầu một hàm jquery), nhưng trong trường hợp đó câu trả lời sẽ là "Không" hoặc "không phải là một giải pháp đúng ngữ nghĩa". - amypellegrini