Перевірте, чи елемент видно в DOM


377

Чи я можу перевірити, чи елемент видно в чистому JS (немає jQuery)?

Так, наприклад, на цій сторінці: Велосипеди продуктивності , якщо навести курсор миші на Пропозиції (у верхньому меню), з’явиться вікно угод, але на початку воно не відображалося. Він знаходиться в HTML, але його не видно.

Отже, даючи елемент DOM, як я можу перевірити, чи він видимий чи ні? Я намагався:

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

але це, здається, не працює. Цікаво, які атрибути слід перевірити. Мені спадає на думку:

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

Будь-які інші, які мені можуть бути відсутні?


1
Якщо не використовується дисплей, він використовує видимість, тому перевіряйте видимість (приховану чи видиму). ex:document.getElementById('snDealsPanel').style.visibility
PSL

PSL. Якщо я хотів би зробити це більш загальним, які атрибути слід перевірити: видимість, показ ...?
Хоммер Сміт

Ви можете зробити це загальним по-своєму, але я кажу, що він використовує видимість для перевірки елемента.
ПСЛ

Ось мій код (без jquery) для цього питання stackoverflow.com/a/22969337/2274995
Алеко

Посилання порушено, що робить ваше запитання непростим для розуміння. Будь ласка, перекройте її.
йогіхостінг

Відповіді:


617

Згідно з цією документацією MDN , offsetParentвластивість елемента повертатиметься 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, мабуть, трохи простіший, оскільки він припадає на більшу кількість крайових випадків, але, маю надію, його справа також повільніше, тому якщо вам доведеться повторювати цю операцію багато разів, краще, ймовірно, її уникнути.


Нічого не жартую. Імо не повинно бути причин використовувати другий метод як універсальне рішення; жодна сторінка не повинна мати фіксованих елементів, про які її творець явно не знає, і їх можна просто перевірити вручну, використовуючи метод getComputedStyle () після запуску методу offsetParent спочатку на всіх елементах.
AlexZ

6
Також FYI, щойно виявив, що el.offsetParentне працює на IE9 для нефіксованих елементів. Або так здається, все одно. (Гаразд для IE11, однак.) Тож пішло getComputedStyleзрештою.
Нік

1
@AlexZ Я не впевнений, чи справді offsetParent справді працює в сучасних браузерах, але так, пару років тому, як раніше, це я розумію з доповідей. Зауважте, що jsPerf згадує лише про швидкість виконання, а поповнення - про дисплей. А поповнення робить інтерфейс користувача бідним. Я особисто не буду їхати за швидкістю для рутини, яку, мабуть, називають 5/6 разів на сторінці.
Етан

2
на жаль! getComputedStyleне працює належним чином: plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview Однак, так чи не так offsetParent- можливо, слід використовувати комбінацію двох?
хлопець mograbi

2
для ie9 + ie10 ви можете перевірити, чи є offsetParent = body для не видимих ​​елементів.
SuperUberDuper

99

Всі інші рішення зламали для мене якусь ситуацію ..

Дивіться виграшну відповідь на розрив:

http://plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview

Врешті-решт я вирішив, що найкращим рішенням є $(elem).is(':visible')- однак, це не чистий JavaScript. це jquery ..

тому я зазирнув до їх джерела і знайшов те, що хотів

jQuery.expr.filters.visible = function( elem ) {
    return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};

Це джерело: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js


11
Це повернеться trueза елемент ізvisibility:hidden
Ювал А.

9
@YuvalA: Так, оскільки елемент все ще видно. Встановлення елемента visibility:hiddenбільше не показує вміст, але все-таки займає ширину та висоту елемента!
Якоб ван Лінген

4
@Michael ви можете легко переглядати код jQuery, і якщо ви використовуєте будь-який сучасний IDE (спробуйте його, якщо ні), ви можете перейти до виправлення деталей коду під час використання jQuery або будь-якої іншої ліб. Ви можете багато чого навчитися переглядати кодові бази проектів з відкритим кодом.
Лукас Лейсіс

53

Якщо ви зацікавлені у тому, щоб користувач бачив:

function isVisible(elem) {
    if (!(elem instanceof Element)) throw Error('DomUtil: elem is not an element.');
    const style = getComputedStyle(elem);
    if (style.display === 'none') return false;
    if (style.visibility !== 'visible') return false;
    if (style.opacity < 0.1) return false;
    if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height +
        elem.getBoundingClientRect().width === 0) {
        return false;
    }
    const elemCenter   = {
        x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
        y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
    };
    if (elemCenter.x < 0) return false;
    if (elemCenter.x > (document.documentElement.clientWidth || window.innerWidth)) return false;
    if (elemCenter.y < 0) return false;
    if (elemCenter.y > (document.documentElement.clientHeight || window.innerHeight)) return false;
    let pointContainer = document.elementFromPoint(elemCenter.x, elemCenter.y);
    do {
        if (pointContainer === elem) return true;
    } while (pointContainer = pointContainer.parentNode);
    return false;
}

Тестовано на (з використанням термінології мока ):

describe.only('visibility', function () {
    let div, visible, notVisible, inViewport, leftOfViewport, rightOfViewport, aboveViewport,
        belowViewport, notDisplayed, zeroOpacity, zIndex1, zIndex2;
    before(() => {
        div = document.createElement('div');
        document.querySelector('body').appendChild(div);
        div.appendChild(visible = document.createElement('div'));
        visible.style       = 'border: 1px solid black; margin: 5px; display: inline-block;';
        visible.textContent = 'visible';
        div.appendChild(inViewport = visible.cloneNode(false));
        inViewport.textContent = 'inViewport';
        div.appendChild(notDisplayed = visible.cloneNode(false));
        notDisplayed.style.display = 'none';
        notDisplayed.textContent   = 'notDisplayed';
        div.appendChild(notVisible = visible.cloneNode(false));
        notVisible.style.visibility = 'hidden';
        notVisible.textContent      = 'notVisible';
        div.appendChild(leftOfViewport = visible.cloneNode(false));
        leftOfViewport.style.position = 'absolute';
        leftOfViewport.style.right = '100000px';
        leftOfViewport.textContent = 'leftOfViewport';
        div.appendChild(rightOfViewport = leftOfViewport.cloneNode(false));
        rightOfViewport.style.right       = '0';
        rightOfViewport.style.left       = '100000px';
        rightOfViewport.textContent = 'rightOfViewport';
        div.appendChild(aboveViewport = leftOfViewport.cloneNode(false));
        aboveViewport.style.right       = '0';
        aboveViewport.style.bottom       = '100000px';
        aboveViewport.textContent = 'aboveViewport';
        div.appendChild(belowViewport = leftOfViewport.cloneNode(false));
        belowViewport.style.right       = '0';
        belowViewport.style.top       = '100000px';
        belowViewport.textContent = 'belowViewport';
        div.appendChild(zeroOpacity = visible.cloneNode(false));
        zeroOpacity.textContent   = 'zeroOpacity';
        zeroOpacity.style.opacity = '0';
        div.appendChild(zIndex1 = visible.cloneNode(false));
        zIndex1.textContent = 'zIndex1';
        zIndex1.style.position = 'absolute';
        zIndex1.style.left = zIndex1.style.top = zIndex1.style.width = zIndex1.style.height = '100px';
        zIndex1.style.zIndex = '1';
        div.appendChild(zIndex2 = zIndex1.cloneNode(false));
        zIndex2.textContent = 'zIndex2';
        zIndex2.style.left = zIndex2.style.top = '90px';
        zIndex2.style.width = zIndex2.style.height = '120px';
        zIndex2.style.backgroundColor = 'red';
        zIndex2.style.zIndex = '2';
    });
    after(() => {
        div.parentNode.removeChild(div);
    });
    it('isVisible = true', () => {
        expect(isVisible(div)).to.be.true;
        expect(isVisible(visible)).to.be.true;
        expect(isVisible(inViewport)).to.be.true;
        expect(isVisible(zIndex2)).to.be.true;
    });
    it('isVisible = false', () => {
        expect(isVisible(notDisplayed)).to.be.false;
        expect(isVisible(notVisible)).to.be.false;
        expect(isVisible(document.createElement('div'))).to.be.false;
        expect(isVisible(zIndex1)).to.be.false;
        expect(isVisible(zeroOpacity)).to.be.false;
        expect(isVisible(leftOfViewport)).to.be.false;
        expect(isVisible(rightOfViewport)).to.be.false;
        expect(isVisible(aboveViewport)).to.be.false;
        expect(isVisible(belowViewport)).to.be.false;
    });
});

крайній випадок, якщо елем розташований поза вікном перегляду, може бути спійманий "if (! pointContainer) return false;" перевірка першого пунктуКонтейнер
Джеррі Денг

Якщо ви хочете перевірити, чи може користувач це бачити, вам доведеться скористатися scrollIntoViewправом ?! Це досить дорого. Чи є інший розумний спосіб?
Кім Керн

36

Це може допомогти: приховати елемент, розташувавши його в крайньому лівому положенні, а потім перевірити властивість offsetLeft. Якщо ви хочете використовувати jQuery, ви можете просто перевірити : видимий селектор видимості та отримати стан видимості елемента.

HTML:

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

CSS:

<!-- for javaScript-->
#myDiv{
   position:absolute;
   left : -2000px;
}

<!-- for jQuery -->
#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 visible!!");        
}

jsFiddle


12
ОП вимагає відповіді без jQuery.
Стівен Куан

Це було відредаговано пізніше, я думаю. Коли я відповів, це не було зазначено в потоці.
Пані Ашадуццаман

2
@StephenQuan, я оновив відповідь як рішеннями jQuery, так і javaScript.
Пані Ашадуццаман

6
для прикладу jQuery, чи не повинно сповіщення говорити "Div видно?"
Андрій Базанов

Я не хотів би зробити висновок, що елемент повністю прихований лише тому, що його offsetLeft становить менше 0: що робити, якщо це лише невелика кількість пікселів менше 0 і видно його праву частину? (Я згоден, це здасться дурним дизайном, але ви ніколи не знаєте з веб-дизайнерами в наші дні.) Мабуть, краще додати ширину до офсетного ліворуч і побачити, чи результат все-таки менший за 0. Про всяк випадок.
Сілас С. Браун

31

Використовуйте той же код, що і jQuery:

jQuery.expr.pseudos.visible = function( elem ) {
    return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};

Отже, у функції:

function isVisible(e) {
    return !!( e.offsetWidth || e.offsetHeight || e.getClientRects().length );
}

Працює як шарм у моїх Win / IE10, Linux / Firefox.45, Linux / Chrome.52 ...

Велике спасибі jQuery без jQuery!


Приємно, але не охоплює елементи, приховані від переливу.
Alph.Dev

приємно, але що чому !! (подвійне заперечення)?
Суніл Гарг

3
Змусити результат бути булевим. Як e.offsetWidthціле число, !e.offsetWidthповернеться, falseякщо e.offsetWidthвін більший за нуль (елемент видно). Таким чином, додавання іншого !як in !!e.offsetWidthповернеться, trueякщо e.offsetWidthвін перевищує нуль. Це скорочення return e.offsetWidth > 0 ? true : falseабо очевидно return e.offsetWidth > 0.
Іван

16

Поєднавши пару відповідей вище:

function isVisible (ele) {
    var style = window.getComputedStyle(ele);
    return  style.width !== "0" &&
    style.height !== "0" &&
    style.opacity !== "0" &&
    style.display!=='none' &&
    style.visibility!== 'hidden';
}

Як сказав AlexZ, це може бути повільніше, ніж деякі інші варіанти, якщо ви знаєте більш конкретно, що ви шукаєте, але це повинно вловлювати всі основні способи прихованості елементів.

Але це також залежить від того, що для вас вважається видимим. Наприклад, для висоти div можна встановити 0px, але вміст все ще видно залежно від властивостей переповнення. Або вміст div може бути такого ж кольору, як і фон, щоб його не було видно користувачам, але все одно відображали на сторінці. Або div можна перенести з екрана або заховати за іншими дивами, або його вміст може бути невидимим, але межа все ще видно. Певною мірою "видимий" є суб'єктивним терміном.


1
Приємно, але style.opacity, style.height і style.width повертають рядок, щоб з нею не працювати! ==
Маслоу

Інший спосіб, що елемент можна приховати за допомогою стилю, - це те, що його колір може відповідати кольорові фону, або ж z-індекс може бути нижчим, ніж інші елементи.
nu everest

додавання display:noneдо цього було б чудово. Правильне робоче рішення!
Gijo Varghese

7

У мене є більш ефективне рішення порівняно з рішенням getComputedStyle () AlexZ, коли у нього є позиції "фіксованих" елементів, якщо він бажає ігнорувати деякі крайні випадки (перевірити коментарі):

function isVisible(el) {
    /* offsetParent would be null if display 'none' is set.
       However Chrome, IE and MS Edge returns offsetParent as null for elements
       with CSS position 'fixed'. So check whether the dimensions are zero.

       This check would be inaccurate if position is 'fixed' AND dimensions were
       intentionally set to zero. But..it is good enough for most cases.*/
    if (!el.offsetParent && el.offsetWidth === 0 && el.offsetHeight === 0) {
        return false;
    }
    return true;
}

Побічна примітка: Власне кажучи, спочатку слід визначити "видимість". У моєму випадку я розглядаю елемент, видимий, якщо я можу без проблем запускати всі методи / властивості DOM на ньому (навіть якщо непрозорість дорівнює 0 або властивість видимості CSS "приховано" тощо).


6

Якщо елемент регулярно видимий (display: block та visibillity: видимий), але якийсь батьківський контейнер прихований, ми можемо використовувати clientWidth та clientHeight для перевірки цього.

function isVisible (ele) {
  return  ele.clientWidth !== 0 &&
    ele.clientHeight !== 0 &&
    ele.style.opacity !== 0 &&
    ele.style.visibility !== 'hidden';
}

Plunker (натисніть тут)


ele.style.visibility !== 'hidden'тут зайве. У такому випадку ширина клієнта та висота клієнта становитимуть 0.
subdavis

5

Якщо ми просто збираємо основні способи виявлення видимості, дозвольте мені не забувати:

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. Це можна зробити за допомогою будь-якого потрібного вам інструмента: кутовий, звичайний JS, будь-який. Ще краще, ви можете змінити реалізацію DOM з часом, але ви завжди зможете читати стан із моделі, а не DOM. Читання вашої правди з ДОМ погано. І повільно. Набагато краще перевірити модель та довіряти своїй реалізації, щоб переконатися, що стан DOM відображає модель. (І використовуйте автоматичне тестування для підтвердження цього припущення.)


Я розбираю сайти, це не для мого власного сайту ... :)
Hommer Smith

4

Прийнята відповідь не спрацювала для мене. Відповідь року 2020 :

1) Метод (elem.offsetParent! == null) відмінно працює в Firefox, але не в Chrome. Для Chrome "позиція: виправлено;" також зробить offsetParent return "null" навіть елемент, якщо його видно на сторінці.

Демонстрація:

//different results in Chrome and Firefox
console.log(document.querySelector('#hidden1').offsetParent); //null Chrome & Firefox
console.log(document.querySelector('#fixed1').offsetParent); //null in Chrome, not null in Firefox
    <div id="hidden1" style="display:none;"></div>
    <div id="fixed1" style="position:fixed;"></div>

ви можете побачити цього хлопця на мегатесті https://stackoverflow.com/a/11639664/4481831 (запустіть його у кількох браузерах, щоб побачити відмінності).

2) (getComputedStyle (elem) .display! == 'none') не працюють, тому що елемент може бути невидимим, оскільки для одного з батьківських властивостей відображення встановлено значення none, getComputedStyle цього не сприймає.

Демонстрація:

var child1 = document.querySelector('#child1');
console.log(getComputedStyle(child1).display);
//child will show "block" instead of "none"
<div id="parent1" style="display:none;">
  <div id="child1" style="display:block"></div>
</div>

3) The (elem.clientHeight! == 0) . На цей метод не впливає фіксована позиція, і він також перевіряє, чи батьки елементів не видно. Але у нього є проблеми з простими елементами, які не мають css макет, докладніше див. Тут

Демонстрація:

console.log(document.querySelector('#div1').clientHeight); //not zero
console.log(document.querySelector('#span1').clientHeight); //zero
<div id="div1">test1 div</div>
<span id="span1">test2 span</span>

4) (elem.getClientRects (). Length! == 0), який, здається, перевершує проблеми попередніх 3-х методів. Однак у нього є проблеми з елементами, які використовують хитрості CSS (інші тоді "display: none"), щоб ховатися на сторінці.

console.log(document.querySelector('#notvisible1').getClientRects().length);
console.log(document.querySelector('#notvisible1').clientHeight);
console.log(document.querySelector('#notvisible2').getClientRects().length);
console.log(document.querySelector('#notvisible2').clientHeight);
console.log(document.querySelector('#notvisible3').getClientRects().length);
console.log(document.querySelector('#notvisible3').clientHeight);
<div id="notvisible1" style="height:0; overflow:hidden; background-color:red;">not visible 1</div>

<div id="notvisible2" style="visibility:hidden; background-color:yellow;">not visible 2</div>

<div id="notvisible3" style="opacity:0; background-color:blue;">not visible 3</div>

ВИСНОВОК: Отже, я вам показав, що жоден метод не є ідеальним. Щоб правильно перевірити видимість, ви повинні використовувати комбінацію останніх трьох методів.


3

Тільки для довідки слід зазначити, що getBoundingClientRect()може працювати в певних випадках.

Наприклад, проста перевірка того, що елемент прихований за допомогою, display: noneможе виглядати приблизно так:

var box = element.getBoundingClientRect();
var visible = box.width && box.height;

Це також зручно, оскільки воно також охоплює нульову ширину, нульову висоту та position: fixedкорпуси. Однак він не повинен повідомляти про елементи, приховані opacity: 0або visibility: hidden(але ні з тим offsetParent).


Найкраща відповідь для мене ... проста та ефективна. І жодного оновлення після 3 років! Продовжує демонструвати вартість "мудрості натовпу". Моя версія: var isVisible = el => (r => r.width && r.height)(el.getBoundingClientRect());. Тоді я можу фільтрувати масиви елементів наступним чином: $$(sel).filter(isVisible).
7vujy0f0hy


Це не працює, коли видно користувачеві .... якщо ви прокрутитесь, це залишиться правдою
Ray Foss

3

Тож, що я знайшов, це найбільш здійсненний метод:

function visible(elm) {
  if(!elm.offsetHeight && !elm.offsetWidth) { return false; }
  if(getComputedStyle(elm).visibility === 'hidden') { return false; }
  return true;
}

Це ґрунтується на цих фактах:

  • display: noneЕлемент (навіть вкладений один) не має ширину , ні висоту.
  • visiblityце hiddenнавіть для вкладених елементів.

Тому не потрібно тестувати offsetParentчи циклічно записуватись у дереві DOM, щоб перевірити, який з батьків є visibility: hidden. Це має працювати навіть у IE 9.

Ви можете заперечити, якщо opacity: 0і згорнуті елементи (має ширину, але не висоту - чи навпаки) теж не видно. Але знову ж таки вони не скажуться прихованими.


3

Невелике доповнення до відповіді ohad navon.

Якщо центр елемента належить іншому елементу, ми його не знайдемо.

Отже, щоб переконатися, що одна з точок елемента виявляється видимою

function isElementVisible(elem) {
    if (!(elem instanceof Element)) throw Error('DomUtil: elem is not an element.');
    const style = getComputedStyle(elem);
    if (style.display === 'none') return false;
    if (style.visibility !== 'visible') return false;
    if (style.opacity === 0) return false;
    if (elem.offsetWidth + elem.offsetHeight + elem.getBoundingClientRect().height +
        elem.getBoundingClientRect().width === 0) {
        return false;
    }
    var elementPoints = {
        'center': {
            x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
            y: elem.getBoundingClientRect().top + elem.offsetHeight / 2
        },
        'top-left': {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().top
        },
        'top-right': {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().top
        },
        'bottom-left': {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().bottom
        },
        'bottom-right': {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().bottom
        }
    }

    for(index in elementPoints) {
        var point = elementPoints[index];
        if (point.x < 0) return false;
        if (point.x > (document.documentElement.clientWidth || window.innerWidth)) return false;
        if (point.y < 0) return false;
        if (point.y > (document.documentElement.clientHeight || window.innerHeight)) return false;
        let pointContainer = document.elementFromPoint(point.x, point.y);
        if (pointContainer !== null) {
            do {
                if (pointContainer === elem) return true;
            } while (pointContainer = pointContainer.parentNode);
        }
    }
    return false;
}

3

Удосконалення відповіді на @Guy Messika вище , розбиття та повернення хибного, якщо центральна точка 'X є <0 неправильна, оскільки права частина елемента може перейти у вигляд. ось виправлення:

private isVisible(elem) {
    const style = getComputedStyle(elem);

    if (style.display === 'none') return false;
    if (style.visibility !== 'visible') return false;
    if ((style.opacity as any) === 0) return false;

    if (
        elem.offsetWidth +
        elem.offsetHeight +
        elem.getBoundingClientRect().height +
        elem.getBoundingClientRect().width === 0
    ) return false;

    const elementPoints = {
        center: {
            x: elem.getBoundingClientRect().left + elem.offsetWidth / 2,
            y: elem.getBoundingClientRect().top + elem.offsetHeight / 2,
        },
        topLeft: {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().top,
        },
        topRight: {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().top,
        },
        bottomLeft: {
            x: elem.getBoundingClientRect().left,
            y: elem.getBoundingClientRect().bottom,
        },
        bottomRight: {
            x: elem.getBoundingClientRect().right,
            y: elem.getBoundingClientRect().bottom,
        },
    };

    const docWidth = document.documentElement.clientWidth || window.innerWidth;
    const docHeight = document.documentElement.clientHeight || window.innerHeight;

    if (elementPoints.topLeft.x > docWidth) return false;
    if (elementPoints.topLeft.y > docHeight) return false;
    if (elementPoints.bottomRight.x < 0) return false;
    if (elementPoints.bottomRight.y < 0) return false;

    for (let index in elementPoints) {
        const point = elementPoints[index];
        let pointContainer = document.elementFromPoint(point.x, point.y);
        if (pointContainer !== null) {
            do {
                if (pointContainer === elem) return true;
            } while (pointContainer = pointContainer.parentNode);
        }
    }
    return false;
}

2

Код jQuery з http://code.jquery.com/jquery-1.11.1.js має параметр "Схований"

var isHidden = function( elem, el ) {
    // isHidden might be called from jQuery#filter function;
    // in that case, element will be second argument
    elem = el || elem;
    return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
};

Так виглядає, що є додаткова перевірка, пов’язана з документом власника

Цікаво, чи справді це сприймає такі випадки:

  1. Елементи, приховані за іншими елементами на основі zIndex
  2. Елементи з прозорістю повні роблять їх непомітними
  3. Елементи, розташовані на екрані (тобто зліва: -1000px)
  4. Елементи з видимістю: приховано
  5. Елементи з дисплеєм: жодні
  6. Елементи без видимого тексту чи піделементів
  7. Елементи висотою або шириною встановлені на 0

0

Ось код, який я написав, щоб знайти єдиний видимий серед кількох подібних елементів і повернути значення його атрибута "class" без jQuery:

  // Build a NodeList:
  var nl = document.querySelectorAll('.myCssSelector');

  // convert it to array:
  var myArray = [];for(var i = nl.length; i--; myArray.unshift(nl[i]));

  // now find the visible (= with offsetWidth more than 0) item:
  for (i =0; i < myArray.length; i++){
    var curEl = myArray[i];
    if (curEl.offsetWidth !== 0){
      return curEl.getAttribute("class");
    }
  }

0

Ось що я зробив:

HTML і CSS: зроблено елемент прихованим за замовчуванням

<html>
<body>

<button onclick="myFunction()">Click Me</button>

<p id="demo" style ="visibility: hidden;">Hello World</p> 

</body>
</html> 

JavaScript: Додано код, щоб перевірити, чи видимість прихована чи ні:

<script>
function myFunction() {
   if ( document.getElementById("demo").style.visibility === "hidden"){
   document.getElementById("demo").style.visibility = "visible";
   }
   else document.getElementById("demo").style.visibility = "hidden";
}
</script>

-1

Це спосіб визначити його для всіх властивостей css, включаючи видимість:

html:

<div id="element">div content</div>

css:

#element
{
visibility:hidden;
}

javascript:

var element = document.getElementById('element');
 if(element.style.visibility == 'hidden'){
alert('hidden');
}
else
{
alert('visible');
}

Він працює для будь-яких властивостей css і є дуже універсальним і надійним.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.