セレクタがnullを返すかどうかをどのように検出できますか?


271

jQuery-selectorが空のオブジェクトを返すかどうかを検出する最良の方法は何ですか。もし、するなら:

alert($('#notAnElement'));

あなたは[オブジェクトオブジェクト]を取得するので、私が今それを行う方法は次のとおりです:

alert($('#notAnElement').get(0));

"undefined"と書かれるので、それをチェックすることができます。しかし、それは非常に悪いようです。他にどのような方法がありますか?

回答:


494

私のお気に入りは、この小さな便利さでjQueryを拡張することです。

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

次のように使用:

$("#notAnElement").exists();

長さを使用するよりも明確です。


2
'this'を$()でラップしたのはなぜですか?このコンテキストの 'this'は実際にはjQueryオブジェクトを指していませんか?
Adham Atta 2011年

1
帰るthisほうがに比べてずっと便利だと思いますtrue。Railsのpresenceメソッドを移植した私の答えを見てください。
マルク=アンドレ・Lafortune

5
連鎖する機能を維持したい場合、関数がtrueを返した場合、またはこのメソッドを使用thisして変数に割り当てたい場合は、returnステートメントをCSharpが持っているものに変更することをお勧めます。
2013年

1
マグナー、この「拡張」機能が実際にどのように機能するか説明していただけませんか?私はそれがJavaScriptの概念であり、厳密にJQueryの概念ではないと想定しています。私はプロトタイピングを調べましたが、それがここに当てはまるかどうか、また構文が「$ .fn」になる理由がわかりません。
KyleM 2014

3
@Adamはい。ただし、その場合は、jQueryの動作を考慮して、exists-checkを削除するだけです。セレクタに一致する要素がない場合は、何もしません。
Magnar


67

セレクターはjQueryオブジェクトの配列を返します。一致する要素が見つからない場合は、空の配列を返します。あなたは確認することができます.length最初の配列要素は、「未定義」であるかどうかチェックセレクタによって返されるコレクションのを。

IFステートメント内で次の例を使用すると、すべて同じ結果が生成されます。セレクタが一致する要素を見つけた場合はtrue、それ以外の場合はfalse。

$('#notAnElement').length > 0
$('#notAnElement').get(0) !== undefined
$('#notAnElement')[0] !== undefined

1
.lengthコードがホットでない限り、私は使用します。それは確かに意図が最も明確です。また、.size()は非推奨で、何年も前から存在しています(1.8以降)。私はあなたの答えを編集してそれを削除するつもりです、メモを付けて自由に追加し直してください、しかしそれはとても古く、私はそれがなくなった方が良いと思います。
エヴァンキャロル

1
技術的には、DOMノードを含まないjQueryオブジェクトを返します。それが空の配列を返すと言うのは正しくありません。
Vigrant 2017

39

私はこのようなことをするのが好きです:

$.fn.exists = function(){
    return this.length > 0 ? this : false;
}

だからあなたはこのようなことをすることができます:

var firstExistingElement = 
    $('#iDontExist').exists() ||      //<-returns false;
    $('#iExist').exists() ||          //<-gets assigned to the variable 
    $('#iExistAsWell').exists();      //<-never runs

firstExistingElement.doSomething();   //<-executes on #iExist

http://jsfiddle.net/vhbSG/


6
@Ehsan実際には、受け入れられた回答の複製ではありません...受け入れられた回答はtrue / falseのみを返しますが、この回答は元のオブジェクト(「this」)またはfalseを返します。この回答により、戻り値がfalseでない場合、戻り値を使用して追加の処理(追加の関数チェーンなど)を実行できます。
RSW 2015年

1
私の標準ツールキットにはまったく同じコードがあります。このフォームはRailsのobject.presenceに相当し、@ CSharpが記述するフォールスルー構成で非常に役立ちます。
inopinatus

これは良い答えですが、テストされた要素が1つも存在しない場合にどうなるかを説明すると役に立ちます。短い答え:TypeError: firstExistingElement.doSomething is not a function。あなたは....もし()で変数全体の割り当て/テストをラップし、唯一の要素が見つかった場合に何かを行うことができます
スティーブン・R

9

Ruby on Railspresenceからインスピレーションを得て使用したい:

$.fn.presence = function () {
    return this.length !== 0 && this;
}

あなたの例は次のようになります:

alert($('#notAnElement').presence() || "No object found");

$.fn.existsブール演算子またはを引き続き使用できるため、提案されたものより優れていますifが、真実の結果の方が便利です。もう一つの例:

$ul = $elem.find('ul').presence() || $('<ul class="foo">').appendTo($elem)
$ul.append('...')

7

私の好み、そしてなぜこれがjQueryにまだないのか私にはわかりません:

$.fn.orElse = function(elseFunction) {
  if (!this.length) {
    elseFunction();
  }
};

このように使用されます:

$('#notAnElement').each(function () {
  alert("Wrong, it is an element")
}).orElse(function() {
  alert("Yup, it's not an element")
});

または、CoffeeScriptを見ると次のようになります。

$('#notAnElement').each ->
  alert "Wrong, it is an element"; return
.orElse ->
  alert "Yup, it's not an element"


0

デフォルトでこれを常に実行したい場合があります。エラーなしにこれを行うためにjquery関数またはjquery.fn.initメソッドをラップするのに苦労してきましたが、jqueryソースに簡単な変更を加えることでこれを行うことができます。含まれているのは、検索できる周囲の行です。私はjqueryソースを検索することをお勧めしますThe jQuery object is actually just the init constructor 'enhanced'

var
  version = "3.3.1",

  // Define a local copy of jQuery
  jQuery = function( selector, context ) {

    // The jQuery object is actually just the init constructor 'enhanced'
    // Need init if jQuery is called (just allow error to be thrown if not included)
    var result = new jQuery.fn.init( selector, context );
    if ( result.length === 0 ) {
      if (window.console && console.warn && context !== 'failsafe') {
        if (selector != null) {
          console.warn(
            new Error('$(\''+selector+'\') selected nothing. Do $(sel, "failsafe") to silence warning. Context:'+context)
          );
        }
      }
    }
    return result;
  },

  // Support: Android <=4.0 only
  // Make sure we trim BOM and NBSP
  rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;

jQuery.fn = jQuery.prototype = {

最後に重要なことですが、ここで非圧縮jqueryソースコードを取得できます。http//code.jquery.com/

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.