表示されているDOMに要素が存在するかどうかを確認するにはどうすればよいですか?


421

getElementByIdメソッドを使用せずに要素の存在をどのようにテストしますか?

参考のためにライブデモをセットアップしました。ここにもコードを印刷します。

<!DOCTYPE html>
<html>
<head>
    <script>
    var getRandomID = function (size) {
            var str = "",
                i = 0,
                chars = "0123456789abcdefghijklmnopqurstuvwxyzABCDEFGHIJKLMNOPQURSTUVWXYZ";
            while (i < size) {
                str += chars.substr(Math.floor(Math.random() * 62), 1);
                i++;
            }
            return str;
        },
        isNull = function (element) {
            var randomID = getRandomID(12),
                savedID = (element.id)? element.id : null;
            element.id = randomID;
            var foundElm = document.getElementById(randomID);
            element.removeAttribute('id');
            if (savedID !== null) {
                element.id = savedID;
            }
            return (foundElm) ? false : true;
        };
    window.onload = function () {
        var image = document.getElementById("demo");
        console.log('undefined', (typeof image === 'undefined') ? true : false); // false
        console.log('null', (image === null) ? true : false); // false
        console.log('find-by-id', isNull(image)); // false
        image.parentNode.removeChild(image);
        console.log('undefined', (typeof image === 'undefined') ? true : false); // false ~ should be true?
        console.log('null', (image === null) ? true : false); // false ~ should be true?
        console.log('find-by-id', isNull(image)); // true ~ correct but there must be a better way than this?
    };
    </script>
</head>
<body>
    <div id="demo"></div>
</body>
</html>

基本的に上記のコードは、要素が変数に格納され、その後DOMから削除されることを示しています。要素がDOMから削除されていても、変数は最初に宣言されたときの要素を保持します。つまり、要素自体へのライブ参照ではなく、レプリカです。その結果、変数の値(要素)の存在を確認すると、予期しない結果が生じます。

このisNull関数は、変数から要素の存在を確認するための私の試みであり、機能しますが、同じ結果を達成する簡単な方法があるかどうか知りたいです。

PS:この話題に関連する優れた記事を誰かが知っている場合、JavaScript変数がこのように動作する理由にも興味があります。


18
実際、それは要素自体へのライブ参照であり、もはやドキュメントには存在しません。実際にDOMから要素を引き出し、後ですべてのイベントハンドラーなどを接続したまま元に戻すことができるため、この機能が必要です。なぜJS変数はそのように振る舞うのですか?彼らがそうしなかったらそれは信じられないほど迷惑になるでしょうから。JSは、変数への参照がなくなったときにのみ変数を削除します。この言語には、あなたが重要だと考える参照や、価値がないと考える参照を知る方法がありません。
Mark Kahn、

@cwolves興味深い。これまでに何度も遭遇したことがあり、あまり考えたことはありません。実際、現在のプロジェクトでは、変更を元に戻す場合に備えて、要素に変更を加える前に要素を配列に保存しています。
ジャスティンブル

1
ガベージコレクションは時々実行され、可能な限りすべてを削除します。ほとんどのブラウザーではかなりお粗末なようですが、一部のブラウザーは再起動の間に数日または数週間実行されることを開発者が認識しているため、ブラウザーのパフォーマンスには適切なガベージコレクションが不可欠です。Web開発者は、不要になったプロパティ(およびメモリ内のものへの参照)を削除することで支援できます。
RobG、2011

2
@JustinBullは、元に戻す要素のコピーを保存するときに注意してください。DOM要素を配列に格納する場合、コピーではなくDOM要素への参照が格納されるため、配列の要素を参照すると、DOM要素に加えられた変更が反映されます。これは、JavaScriptのすべてのオブジェクト(タイプ「オブジェクト」の変数)の場合です。
アンソニーディサンティ2011

回答:


545

一部の人々がここに着陸しているようで、要素が存在するかどうかを知りたいだけです(元の質問とは少し異なります)。

これは、ブラウザーの選択方法のいずれかを使用して、それが真の値かどうかをチェックする(通常)のと同じくらい簡単です。

たとえば、私の要素にidof がある場合、"find-me"単純に次のように使用できます...

var elementExists = document.getElementById("find-me");

これは、要素への参照を返すか、に指定されますnull。ブール値が必要な場合は!!、メソッド呼び出しの前にaをトスします。

さらに、要素を検索するために存在する他の多くの方法の一部を使用できますdocument

  • querySelector()/querySelectorAll()
  • getElementsByClassName()
  • getElementsByName()

これらのメソッドの一部はを返すため、a はオブジェクトであり、したがってtrueであるため、NodeListそのlengthプロパティを確認してください。NodeList


要素が表示DOMの一部として存在するかどうかを(実際に質問されたように)実際に判断するために、Csuwldcatは(この回答が以前は含まれていたため)独自のロールよりも優れたソリューションを提供します。つまり、DOM要素でこのcontains()メソッドを使用します。

こんな風に使えます...

document.body.contains(someReferenceToADomElement);

1
まさに私が探していたもの!だから明らかに笑、なぜ私はそれを考えなかったのですか。また、変数がこのように機能する理由を説明する優れた記事を知っていますか?
ジャスティンブル

3
さらに短い:var elementInDom = function( el ) { while ( el = el.parentNode ) if ( el === document ) return true; return false; }
bennedich

2
@ButtleButkus実際の質問を読んでください。あなたは意味がありません使用されている解決策getElementById() になる DOM要素への参照を返すかnull、そのため、使用してtypeof(特にRHSには)(それが定義されていない場合、LHS条件は投げるだろう間違っていますReferenceError)。
アレックス

2
以下に投稿されたものに対してこれを使用する理由はありますdocument.body.contains()か?これは非常に優れたブラウザサポートがあるようです?
2013年

1
@Jonzは古い回答部分を削除しました。忘れずにcsuwldcatに
alex

310

利用getElementById()可能な場合に使用します。

また、jQueryでこれを行う簡単な方法を次に示します。

if ($('#elementId').length > 0) {
  // Exists.
}

そして、サードパーティのライブラリを使用できない場合は、ベースJavaScriptに固執してください。

var element =  document.getElementById('elementId');
if (typeof(element) != 'undefined' && element != null)
{
  // Exists.
}

2
私が取り組んでいるプロジェクトでは、ライブラリを使用できません。古き良きファッションの生コードのみ。私はそのjQueryメソッドを知っていますが、jQueryコンテナーにラップされていない要素では機能しません。たとえば$('#elementId')[0].length、同じ結果は得られません。
ジャスティンブル

8
2番目のコード例のそのような複雑なifステートメントに正当な理由はありますか?なぜ単純ではないのですif (element) {}か?elementが未定義またはnullの場合、この式はfalseです。elementがDOM要素の場合、式はtrueです。
カヤー

2
@kayahr複雑すぎる。要素が見つからなかった場合getElementById()に返すnullように指定されているので、真の戻り値を確認するだけで十分です。
アレックス

5
それは常識だと思います。
2013年

8
getElementById決して戻るべきではありませんundefined。いずれにせよ、element != null小切手はこれを受け取ります。

191

Node.contains DOM APIを使用すると、ページ(現在DOM内)に要素が存在するかどうかを非常に簡単に確認できます。

document.body.contains(YOUR_ELEMENT_HERE);

CROSS-BROWSER注documentInternet Explorer のオブジェクトにはcontains()メソッドがありませんdocument.body.contains()。ブラウザ間の互換性を確保するには、代わりに使用してください。


4
これはこの問題に対する究極の答えのようです...そして、MDNが信じられるなら、そのサポートはかなり良いです。
2013年

2
これが最良の答えです。チェックするだけdocument.contains()で十分であることに注意してください。
アレックス

@csuwldcatそれは私のために、少なくともChromeで動作しましたdocument.contains(document.documentElement)document持っていませんNode(私の知る限り、そのプロトタイプチェーン上document- > HTMLDocument- > Document- > Node
アレックス

4
これは確かに最良の答えです。-Web標準です-非常によくサポートされています(Firefoxではバージョン9まで表示されませんが、IEで開発された非標準の機能であったため、後で標準化される)-ネイティブAPIへの単一の呼び出しを使用するため、最速である必要がある
Jon z

2
@LeeSaxon構文はdocument.body.contains([selector])、つまりdocument.body.contains(document.getElementById('div')
iglesiasedd

67

私は単に行います:

if(document.getElementById("myElementId")){
    alert("Element exists");
} else {
    alert("Element does not exist");
}

それは私にとってはうまくいき、まだ問題はありませんでした...


1
これは元の質問とは関係ありません。OPは、DOM要素への参照が可視DOMの一部であるかどうかを知りたいと考えています。
アレックス

16
しかし私を助けました。要素の存在の簡単なテストを探していました。これはうまくいきました。ありがとう。
khaverim 2013年

1
この回答は適切に機能しますが、要素にがある場合のみidです。表示されているDOMに要素が存在するかどうかを確認する方法という質問に答えるより良い解決策は任意の要素で、idsのない要素でさえも行うことですdocument.body.contains(element)
Edward

@Edwardこれはとは全く違うものであるcontains()
アレックス・

わかった。私はコメントで、他の回答の方が質問に適していることを示唆しています。
エドワード

11

parentNodeプロパティがnullかどうかを確認するだけです。

あれは、

if(!myElement.parentNode)
{
    // The node is NOT in the DOM
}
else
{
    // The element is in the DOM
}

私はこれが古い質問であることを知っていますが、この答えはまさに私が探していた質問に対するエレガントでシンプルな解決策の一種です。
poby

11
@poby:エレガントに見えるかもしれませんが、要求された動作を実際には行っていません。要素に親要素があるかどうかのみをチェックします。親要素が接続されていない可能性があるため、これは要素が可視DOMにあることを意味しません。
カヤール、2013年

最後のものがドキュメントであるかどうかを確認するには、親の親をすべて調べる必要があります。もう1つの問題は、他の多くの理由により、可視範囲外であるか、カバーされているか、見えない可能性があることです。
Arek Bal 2014

要素は、ドキュメントフラグメントに追加されているという理由だけでparentNodeを持つこともできます。

11

Mozilla Developer Networkから:

この関数は、要素がページの本文にあるかどうかを確認します。contains()は包括的であり、本体にそれ自体が含まれているかどうかを判別することはisInPageの意図ではないため、このケースは明示的にfalseを返します。

function isInPage(node) {
  return (node === document.body) ? false : document.body.contains(node);
}

nodeは、<body>で確認するノードです。


+1、これは(任意の)テキストノード(またはコメントノード)でも機能しますか?
Nikos M.

@ニコス どのhtmlタグでも機能するはずですが、テストしていません。
Ekramul Hoque 2014

4
すべきではないfalseことtrue
マルク・アンドレLafortune

もし nodeISのdocument.body、確かにメソッドは返すべきtrueですか?すなわち、return (node === document.body) || document.body.contains(node);
daiscog

7

最も簡単な解決策は、要素がDOMに挿入された場合にのみ設定されるbaseURIプロパティを確認することです。これは、削除されると空の文字列に戻ります。

var div = document.querySelector('div');

// "div" is in the DOM, so should print a string
console.log(div.baseURI);

// Remove "div" from the DOM
document.body.removeChild(div);

// Should print an empty string
console.log(div.baseURI);
<div></div>


5
DOMノードにbaseURIプロパティがあることさえ知りませんでした。このアプローチについて私が気に入っているのは、要素自体のプロパティを使用することです。これは、おそらく要素が別のドキュメント(iframeなど)にある場合でも機能することを意味します。それについて私が気に入らないのは、それがWebkitの外部では機能しないように見えることです。
DoctorDestructo 2014年

要素がドキュメントにない場合、次のエラーがスローされるので注意してくださいCannot read property 'baseURI' of null。例:console.log(document.querySelector('aside').baseURI)
イアンデイビス

このメソッドは常に同じ文字列を出力するため、使用できません。
鏡サッシャRosylight

4

jQueryソリューション:

if ($('#elementId').length) {
    // element exists, do something...
}

これは私にとってjQueryを使用して機能し、使用する必要はありませんでした$('#elementId')[0]


なぜ$('#elementId')[0]回避すべきことがあるのですか?
アレックス

長い間、私はこれに答えたので、$( '#elementId')[0]を使用します。値が0番目のインデックスになることを常に示していると思います。この方法では、常に最初に発生する要素をチェックしています。ラジオボタンのように、同じ名前のチェックボックスが複数あったのは何ですか。そのとき.lengthが役に立ちます。
コードバスター

3

csuwldcatのソリューションは束の中で最高のようですが、JavaScriptコードが実行されているものとは異なるドキュメントにある要素(iframeなど)で正しく機能するように、わずかな変更が必要です。

YOUR_ELEMENT.ownerDocument.body.contains(YOUR_ELEMENT);

ownerDocument単純な古いものとは対照的に、要素のプロパティの使用に注意してくださいdocument要素(要素の所有者ドキュメントを参照する場合としない場合がある)とは。

torazaburoは、非ローカル要素でも機能するさらに単純なメソッドを投稿しましたが、残念ながら、このbaseURIプロパティを使用しています。このプロパティは、現時点ではブラウザ間で均一に実装されていません(WebKitベースのものでしか機能しません)。同様の方法で使用できる他の要素またはノードプロパティを見つけることができなかったので、当分の間、上記のソリューションはそれと同じくらい良いと思います。


3

親を繰り返す代わりに、要素がDOMから切り離されたときにすべて0である境界矩形を取得できます。

function isInDOM(element) {
    if (!element)
        return false;
    var rect = element.getBoundingClientRect();
    return (rect.top || rect.left || rect.height || rect.width)?true:false;
}

幅0と高さ0の要素の、上端と左端がゼロのエッジケースを処理する場合は、親をまで繰り返してダブルチェックできますdocument.body

function isInDOM(element) {
    if (!element)
        return false;
    var rect = element.getBoundingClientRect();
    if (element.top || element.left || element.height || element.width)
        return true;
    while(element) {
        if (element == document.body)
            return true;
        element = element.parentNode;
    }
    return false;
}

これにより、再レイアウトが発生します。gist.github.com
Steven Vachon

3

要素が存在するかどうかを確認する簡単な方法は、jQueryの1行のコードで実行できます。

以下がそのコードです。

if ($('#elementId').length > 0) {
    // Do stuff here if the element exists
} else {
    // Do stuff here if the element does not exist
}


2

このコードは私にとってはうまくいき、問題はありませんでした。


    if(document.getElementById("mySPAN")) {
        // If the element exists, execute this code
        alert("Element exists");
    }
    else {
        // If the element does not exist execute this code
        alert("Element does not exists");
    }

1

を使用してjQuery.contains、要素が別の要素の子孫であるかどうかを確認することもできます。documentページDOMに存在するすべての要素はの子孫であるため、検索する親要素として渡しましたdocument

jQuery.contains( document, YOUR_ELEMENT)


1

jQueryを使用した簡単なソリューション:

$('body').find(yourElement)[0] != null

2
...または$(document).find(yourElement).length !== 0
Grinn

1
これはそれを悪用しnull == undefinedます。実際の戻り値はになりますundefined。それと比較することnullは少し奇妙です。
アレックス2013年

1
// This will work prefectly in all :D
function basedInDocument(el) {

    // This function is used for checking if this element in the real DOM
    while (el.parentElement != null) {
        if (el.parentElement == document.body) {
            return true;
        }
        el = el.parentElement; // For checking the parent of.
    } // If the loop breaks, it will return false, meaning
      // the element is not in the real DOM.

    return false;
}

何で?すべてのケース?
Peter Mortensen、

1
  • 要素が DOM、その親も
  • そして最後の祖父母は document

要素のループにループすることを確認するには parentNode、最後の祖父母に到達するまでツリーに

これを使って:

/**
 * @param {HTMLElement} element - The element to check
 * @param {boolean}     inBody  - Checks if the element is in the body
 * @return {boolean}
 */
var isInDOM = function(element, inBody) {
    var _ = element, last;

    while (_) {
        last = _;
        if (inBody && last === document.body) { break;}
        _ = _.parentNode;
    }

    return inBody ? last === document.body : last === document;
};

2
これはDOMでの再レンダリングを引き起こさないため、最良の答えである可能性があります。
Steven Vachon

説明は適切です(ここでコメントではなく、回答を編集して返信してください)。
Peter Mortensen、

0

私はこのアプローチが好きでした:

var elem = document.getElementById('elementID');

if (elem)
    do this
else
    do that

また

var elem = ((document.getElementById('elemID')) ? true:false);

if (elem)
    do this
else
    do that

1
!!ブール値が必要な場合はどうしてですか?
アレックス、2014

では、要素にIDがない場合、その要素はDOMにないと見なされますか?これは間違っていると思います。
Steven Vachon

0

使用するquerySelectorAllforEach

document.querySelectorAll('.my-element').forEach((element) => {
  element.classList.add('new-class');
});

の反対として:

const myElement = document.querySelector('.my-element');
if (myElement) {
  element.classList.add('new-class');
}

0

以下を試してください。これは最も信頼できるソリューションです。

window.getComputedStyle(x).display == ""

例えば、

var x = document.createElement("html")
var y = document.createElement("body")
var z = document.createElement("div")
x.appendChild(y);
y.appendChild(z);

z.style.display = "block";

console.log(z.closest("html") == null); // 'false'
console.log(z.style.display); // 'block'
console.log(window.getComputedStyle(z).display == ""); // 'true'

1
これにより、再レイアウトが発生する可能性があります:gist.github.com/paulirish/5d52fb081b3570c81e3a#getcomputedstyle
Steven Vachon

0

HTML要素を除いて、既存のすべての要素にはparentElementセットがあります!

function elExists (e) { 
    return (e.nodeName === 'HTML' || e.parentElement !== null);
};

常に「HTML」ですか?それは"html"でしょうか?
Peter Mortensen、

x.tagNameまたはx.nodeNameは常に大文字で大文字にしてください。コードでの記述方法
ジョナ

0

この状態はすべてのケースをひよこにします。

function del() {
//chick if dom has this element 
//if not true condition means null or undifind or false .

if (!document.querySelector("#ul_list ")===true){

// msg to user
    alert("click btn load ");

// if console chick for you and show null clear console.
    console.clear();

// the function will stop.
    return false;
}

// if its true function will log delet .
console.log("delet");

}


0

node.isConnectedプロパティの使用を好む(MDNにアクセスする)。

注:要素がShadowRootにも追加されている場合、これはtrueを返します。

例:

const element = document.createElement('div');
console.log(element.isConnected); // Returns false
document.body.append(element);
console.log(element.isConnected); // Returns true
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.