web-dev-qa-db-ja.com

要素が可視DOMに存在するかどうかを確認する方法

getElementByIdメソッドを使用せずに、要素の存在をどのようにテストしますか?参考のために live demo をセットアップしました。ここにもコードを印刷します。

<!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関数は、変数から要素の存在を確認するための私の試みです。それは機能しますが、同じ結果を達成するためのより簡単な方法があるかどうかを知りたいです。

シモンズ:私はまた誰かが主題に関連したいくつかの良い記事を知っているならJavaScript変数がこのように振る舞う理由にも興味があります。

337
Justin Bull

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

ブラウザの選択方法を使って truthy の値をチェックするのと同じくらい簡単です(一般的に)。

例えば、もし私の要素がid"find-me"を持っていたら、私は単に使うことができます...

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

これは要素への参照またはnullを返すように指定されています。ブール値が必要な場合は、メソッド呼び出しの前に単に!!を投げます。

さらに、(すべてdocumentから生きている)ように、要素を見つけるために存在する他の多くの方法のいくつかを使うことができます。

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

これらのメソッドの中にはNodeListを返すものがあります。lengthはオブジェクトなので truthy なので、必ずそのNodeListプロパティをチェックしてください。


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

あなたはそのようにそれを使用することができます...

document.body.contains(someReferenceToADomElement);
452
alex

利用可能であれば、なぜあなたはgetElementById()を使わないのですか?

また、これはjQueryでそれをする簡単な方法です:

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

サードパーティのライブラリを使用できない場合は、基本のJavaScriptを使用してください。

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

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

document.body.contains(YOUR_ELEMENT_HERE);

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

159
csuwldcat

私は単にします:

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

私のために動作し、それについてまだ問題がありませんでした....

56
Anomaly

Mozilla Developer Network から

この関数は、要素がページの本文にあるかどうかを確認します。 containsは包括的であり、bodyがそれ自体を含むかどうかを判断することはisInPageの意図ではないので、この場合は明示的にfalseを返します。

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

node は、で確認したいノードです。

10
Ekramul Hoque

ParentNodeプロパティがnullかどうかを確認してください。

すなわち.

if(!myElement.parentNode)
{
    //node is NOT on the dom
}
else
{
    //element is on the dom
}
8
mikechambers

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

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>
7
user663031

jQueryソリューション:

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

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

3
Code Buster

csuwldcatの解決策 が最も良い方法のようですが、iframeなど、JavaScriptが実行されているのとは異なるドキュメント内の要素で正しく機能するようにするには、わずかな変更が必要です。

YOUR_ELEMENT.ownerDocument.body.contains(YOUR_ELEMENT);

単なる普通の 'ownerDocument(要素の所有者文書を参照してもしなくてもよい)とは対照的に、要素のdocumentプロパティの使用に注意してください。

torazaburoは さらに単純なメソッド を非ローカル要素でも動作させることを投稿しましたが、残念ながら、現時点ではブラウザ間で統一されていないbaseURIプロパティを使用しています。ベースのもの)。同様の方法で使用できる他の要素やノードのプロパティを見つけることができなかったので、とりあえず上記の解決策はそれが得られるのと同じくらい良いと思います。

3
DoctorDestructo

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

これが以下のコードです:

if ($('#elementId').length > 0) {
    // do stuff here if element exists
}else {
    // do stuff here if element not exists
}
2
Ravi Agrawal

JQueryを使った簡単なソリューション

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

別のオプション element.closest

element.closest('body') === null
1
Brian M. Hunt

親を反復する代わりに、要素がdomから切り離されたときに境界0をすべて0にすることができます。

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

あなたがゼロの上と左のゼロでゼロ幅と高さの要素のEdgeのケースを処理したいなら、あなたは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;
}
1
Erez Pilosof

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

jQuery.contains( document, YOUR_ELEMENT)
1
nitinkhuranas
// this will work prefect in all :D     
function basedInDocument(el) {
        // this function use for checking if this element in a real DOM
        while (el.parentElement != null) {
            if (el.parentElement == document.body) {
                return true;
            }
            el = el.parentElement; // for check parent of 
        } // if loop break will return false mean element not in real DOM
        return false;
    }
1
qandil afa

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

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
Hugh

これを試して、これが最も信頼性の高い解決策です:

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
0
dexiang

Node::contains() を使用して、要素が<html>の子であるかどうかを確認します。

const div = document.createElement('div');
document.documentElement.contains(div); //-> false

document.body.appendChild(div);
document.documentElement.contains(div); //-> true

これについては is-dom-detached で説明しました。

0
Steven Vachon

これを使って:

var isInDOM = function(element, inBody) {
    var _ = element, last;

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

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

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
Rafal Enden