要素がDOMに表示されているかどうかの確認

要素が表示されているかどうかを純粋なJS(jQueryなし)で確認する方法はありますか?

例えば、このページではPerformance Bikesでは、トップメニューのDealsにカーソルを置くと、Dealsのウィンドウが表示されますが、最初は表示されていませんでした。HTMLにはあるのですが、表示されていません。

では、DOM要素があって、それが表示されているかどうかを確認するにはどうしたらいいのでしょうか?試してみました。

window.getComputedStyle(my_element)['display']);

を試してみましたが、うまくいっていないようです。 どの属性をチェックすればいいのでしょうか?思い当たることがあります。

display !== 'none'
visibility !== 'hidden'

他に見落としがあるかもしれませんか?

ソリューション

MDNドキュメント]1によると、要素の offsetParent プロパティは、要素またはその親が display style プロパティによって隠されると、null を返します。 ただ、その要素が固定されていないことを確認してください。 ページに position: fixed; 要素がない場合、これを確認するスクリプトは次のようになります。

// Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
    return (el.offsetParent === null)
}

一方で、この検索に引っかかる可能性のある位置固定の要素が*ある場合は、悲しいことに(そしてゆっくりと)window.getComputedStyle()を使用しなければなりません。 その場合の関数は、次のようになるかもしれません。

// Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
    var style = window.getComputedStyle(el);
    return (style.display === 'none')
}

選択肢2は、より多くのエッジケースを考慮しているので、おそらくもう少しわかりやすいと思いますが、きっとかなり遅くなるので、この操作を何度も繰り返さなければならないのであれば、おそらく避けたほうがいいでしょう。

解説 (19)

これは役に立つかもしれません :。 要素を左端に配置して隠し、offsetLeftプロパティを確認してください。jQueryを使用する場合は、単純に:visibleセレクタをチェックして、要素の可視性の状態を取得することができます。

HTML :

<div id="myDiv">Hello</div>

CSS :


#myDiv{
   position:absolute;
   left : -2000px;
}


#myDiv{
    visibility:hidden;
}

javaScript :

var myStyle = document.getElementById("myDiv").offsetLeft;

if(myStyle < 0){
     alert("Div is hidden!!");
}

jQuery :

if(  $("#MyElement").is(":visible") == true )
{  
     alert("Div is hidden!!");        
}

jsFiddle

解説 (7)

視界を確保するための基本的な方法を集めるだけなら、忘れないようにしたい。

opacity > 0.01; // probably more like .1 to actually be visible, but YMMV

また、属性を取得する方法については

element.getAttribute(attributename);

つまり、あなたの例では

document.getElementById('snDealsPanel').getAttribute('visibility');

でも、あれ?ここではうまくいきません。よく見ると、visibilityは要素の属性としてではなく、styleプロパティを使って更新されていることがわかります。これは、あなたがやっていることをやろうとするときの多くの問題の一つです。とりわけ、visibility、display、opacityのすべてが正しい値を持っているからといって、要素の中に実際に見るべきものがあることを保証することはできません。要素にはコンテンツがないかもしれないし、高さや幅がないかもしれません。他のオブジェクトがそれを隠しているかもしれません。詳しくは、Googleで検索すると、thisが見つかり、問題解決のためのライブラリも含まれています。(YMMV)

この質問と重複する可能性のある以下の記事もチェックしてみてください。偉大なJohn Resig氏の洞察を含む、素晴らしい回答があります。しかし、あなたの具体的な使用例は、標準的なものとは若干異なるので、フラグを立てるのは控えます。

(edit: opはページを作成するのではなくスクレイピングしていると言っているので、以下は当てはまりません) もっと良い方法は?Angularがng-showでやっているように、要素の可視性をモデルのプロパティにバインドし、常にそのモデルに依存するようにします。これは好きなツールを使ってできます。AngularでもプレーンなJSでも何でもいいです。さらに良いことに、DOMの実装を変更しても、常にDOMではなくモデルから状態を読み取ることができるのです。DOMから真実を読み取るのは悪いことです。そして遅いです。モデルをチェックして、DOMの状態がモデルを反映していることを確実にするために、自分の実装を信頼する方がずっと良いです。(そして、その仮定を確認するために自動化されたテストを使用します。)

解説 (1)