Проверка дали елементът е видим в DOM

Има ли някакъв начин да проверя дали даден елемент е видим в чист JS (без jQuery) ?

Така например в тази страница: Performance Bikes, ако преминете с мишката върху Сделки (в горното меню), се появява прозорец със сделки, но в началото той не се показваше. Има го в HTML, но не се вижда.

И така, при даден DOM елемент как мога да проверя дали е видим или не? Опитах:

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

но не изглежда да работи. Чудя се кои атрибути трябва да проверя. Идва ми на ум:

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

Има ли други, които може да пропускам?

Решение

Според тази документация на MDN, свойството offsetParent на даден елемент'ще връща null, когато той или някой от родителите му е скрит чрез свойството display style. Просто се уверете, че елементът не е фиксиран. Скрипт за проверка на това, ако на страницата ви няма елементи с позиция: фиксирана;, може да изглежда така:

// 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');

Но какво? Това не работи тук. Вгледайте се по-внимателно и ще установите, че видимостта се актуализира не като атрибут на елемента, а с помощта на свойството style. Това е един от многото проблеми при опитите да се направи това, което правите вие. Наред с другите: не можете да гарантирате, че в елемента действително има нещо, което може да се види, само защото неговите видимост, показване и непрозрачност имат правилните стойности. Той все още може да няма съдържание или да няма височина и ширина. Друг обект може да го закрива. За повече подробности едно бързо търсене в Google разкрива това и дори включва библиотека, с която да се опитате да решите проблема. (YMMV)

Разгледайте следните материали, които са възможни дубликати на този въпрос, с отлични отговори, включително някои прозрения от могъщия Джон Резиг. Вашият специфичен случай на употреба обаче е малко по-различен от стандартния, така че ще се въздържа да го маркирам:

(РЕДАКТИРАНЕ: ОПЕРАТОРЪТ КАЗВА, ЧЕ ОСТЪРГВА СТРАНИЦИ, А НЕ ГИ СЪЗДАВА, ТАКА ЧЕ ДОЛНАТА ЧАСТ НЕ Е ПРИЛОЖИМА) По-добър вариант? Свържете видимостта на елементите със свойствата на модела и винаги поставяйте видимостта в зависимост от този модел, както Angular прави с ng-show. Можете да направите това, като използвате какъвто искате инструмент: Angular, обикновен JS, каквото и да е. Още по-добре е, че можете да променяте реализацията на DOM с течение на времето, но винаги ще можете да четете състоянието от модела, а не от DOM. Четенето на вашата истина от DOM е лошо. И е бавно. Много по-добре е да проверявате модела и да се доверите на вашата имплементация, за да гарантирате, че състоянието на DOM отразява модела. (И използвайте автоматизирано тестване, за да потвърдите това предположение.)

Коментари (1)