Czy jest jakiś sposób, aby sprawdzić, czy element jest widoczny w czystym JS (bez jQuery)?
Na przykład na tej stronie: Rowery wyczynowe , jeśli najedziesz kursorem na Oferty (w górnym menu), pojawi się okno ofert, ale na początku nie zostało wyświetlone. Jest w HTML, ale nie jest widoczny.
Zatem, biorąc pod uwagę element DOM, jak mogę sprawdzić, czy jest widoczny, czy nie? Próbowałem:
window.getComputedStyle(my_element)['display']);
ale wydaje się, że nie działa. Zastanawiam się, które atrybuty powinienem sprawdzić. Przychodzi mi na myśl:
display !== 'none'
visibility !== 'hidden'
Jakieś inne, za którymi mogę tęsknić?
javascript
dom
Hommer Smith
źródło
źródło
document.getElementById('snDealsPanel').style.visibility
Odpowiedzi:
Zgodnie z tą dokumentacją MDN
offsetParent
właściwość elementu zwróci sięnull
za każdym razem, gdy on lub którykolwiek z jego rodziców zostanie ukryty za pośrednictwem właściwości stylu wyświetlania. Upewnij się tylko, że element nie jest naprawiony. Skrypt do sprawdzenia tego, jeśli nie masz żadnychposition: fixed;
elementów na stronie, może wyglądać następująco:Z drugiej strony, jeśli nie mają pozycji stałych elementów, które mogą się złapać w tej kategorii, będzie niestety (i powoli) mają do użytku
window.getComputedStyle()
. W takim przypadku funkcją może być:Opcja nr 2 jest prawdopodobnie nieco prostsza, ponieważ uwzględnia więcej przypadków przewagi, ale założę się, że jest również znacznie wolniejsza, więc jeśli musisz powtarzać tę operację wiele razy, najlepiej tego uniknąć.
źródło
el.offsetParent
nie działa na IE9 dla nie naprawionych elementów. A przynajmniej tak się wydaje. (OK dla IE11.) Tak więc poszło wgetComputedStyle
końcu.getComputedStyle
nie działa poprawnie: plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview Jednak tak też jestoffsetParent
- być może należy zastosować kombinację tych dwóch?Dla mnie wszystkie inne rozwiązania się zepsuły.
Zobacz zwycięską odpowiedź w podziale na:
http://plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview
W końcu zdecydowałem, że najlepszym rozwiązaniem jest
$(elem).is(':visible')
- jednak nie jest to czysty JavaScript. to jquery ..więc zerknąłem na ich źródło i znalazłem to, czego chciałem
To jest źródło: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js
źródło
true
do elementu ovisibility:hidden
visibility:hidden
nie wyświetlał już żadnej zawartości, ale nadal przyjmuje szerokość i wysokość elementu!Jeśli jesteś zainteresowany tym, co widzi użytkownik:
Testowane na (przy użyciu terminologii mokka ):
źródło
scrollIntoView
prawa ?! To jest dość drogie. Czy istnieje inny sprytny sposób?Może to pomóc: Ukryć element, ustawiając go na skrajnie lewej pozycji, a następnie sprawdzając właściwość offsetLeft. Jeśli chcesz użyć jQuery, możesz po prostu sprawdzić : widoczny selektor i uzyskać stan widoczności elementu.
HTML:
CSS:
javaScript:
jQuery:
jsFiddle
źródło
Użyj tego samego kodu, co robi jQuery:
Tak więc w funkcji:
Działa jak urok w moim Win / IE10, Linux / Firefox.45, Linux / Chrome.52 ...
Wielkie podziękowania dla jQuery bez jQuery!
źródło
e.offsetWidth
jest liczbą całkowitą,!e.offsetWidth
zwróci,false
jeślie.offsetWidth
jest wyższa od zera (element jest widoczny). Tak więc dodanie kolejnego!
jak w!!e.offsetWidth
zwróci,true
jeślie.offsetWidth
jest większe od zera. Jest to skrót odreturn e.offsetWidth > 0 ? true : false
lub oczywiściereturn e.offsetWidth > 0
.Łącząc kilka odpowiedzi powyżej:
Jak powiedział AlexZ, może to być wolniejsze niż niektóre inne opcje, jeśli wiesz bardziej dokładnie, czego szukasz, ale to powinno uchwycić wszystkie główne sposoby ukrywania elementów.
Ale zależy to również od tego, co dla Ciebie jest widoczne. Na przykład wysokość div może być ustawiona na 0 pikseli, ale zawartość jest nadal widoczna w zależności od właściwości przepełnienia. Lub zawartość div może być w tym samym kolorze co tło, aby nie była widoczna dla użytkowników, ale nadal renderowana na stronie. Lub element div może zostać przeniesiony poza ekran lub ukryty za innymi elementami div lub jego zawartość może być niewidoczna, ale ramka nadal widoczna. Do pewnego stopnia „widoczny” jest pojęciem subiektywnym.
źródło
display:none
do tego byłoby świetne. Właściwe działające rozwiązanie!Mam bardziej wydajne rozwiązanie w porównaniu do rozwiązania getComputedStyle () AlexZ, gdy ktoś ma elementy „ustalone” pozycji, jeśli chce zignorować niektóre przypadki krawędzi (sprawdź komentarze):
Uwaga dodatkowa: Ściśle mówiąc, „widoczność” musi zostać zdefiniowana w pierwszej kolejności. W moim przypadku rozważam element widoczny, o ile mogę bez problemu uruchomić na nim wszystkie metody / właściwości DOM (nawet jeśli krycie wynosi 0 lub właściwość widoczności CSS jest „ukryta” itp.).
źródło
Jeśli element jest regularnie widoczny (display: block and visibillity: visible), ale jakiś kontener nadrzędny jest ukryty, możemy to sprawdzić za pomocą clientWidth i clientHeight .
Plunker (kliknij tutaj)
źródło
ele.style.visibility !== 'hidden'
jest tutaj zbędny. W takim przypadku clientWidth i clientHeight będą wynosić 0.Jeśli tylko zbieramy podstawowe sposoby wykrywania widoczności, nie zapomnę:
A jak uzyskać atrybuty:
W twoim przykładzie:
Ale co? Tu nie działa. Przyjrzyj się bliżej, a zobaczysz, że widoczność jest aktualizowana nie jako atrybut elementu, ale za pomocą
style
właściwości. Jest to jeden z wielu problemów z próbami robienia tego, co robisz. Między innymi: nie możesz zagwarantować, że w elemencie jest coś do zobaczenia, tylko dlatego, że jego widoczność, wyświetlanie i krycie mają prawidłowe wartości. Wciąż może brakować treści lub może mieć wysokość i szerokość. Inny obiekt może to zasłonić. Aby uzyskać więcej informacji, szybkie wyszukiwanie Google ujawnia to , a nawet zawiera bibliotekę, aby spróbować rozwiązać problem. (YMMV)Sprawdź poniższe, które są możliwymi duplikatami tego pytania, z doskonałymi odpowiedziami, w tym wglądem potężnego Johna Resiga. Jednak konkretny przypadek użycia różni się nieco od standardowego, więc powstrzymam się od oznaczania:
(EDYCJA: OP MÓWI, ŻE STRONY ZŁOMU, NIE TWORZYCIE SIĘ, A PONIŻEJ NIE MA ZASTOSOWANIA) Lepsza opcja? Powiąż widoczność elementów z właściwościami modelu i zawsze uzależnij widoczność od tego modelu, podobnie jak Angular z ng-show. Możesz to zrobić za pomocą dowolnego narzędzia: kątowego, zwykłego JS, cokolwiek. Co więcej, możesz zmieniać implementację DOM w miarę upływu czasu, ale zawsze będziesz w stanie odczytać stan z modelu zamiast DOM. Czytanie swojej prawdy z DOM jest złe. I powoli. Znacznie lepiej sprawdzić model i zaufać implementacji, aby upewnić się, że stan DOM odzwierciedla model. (I użyj automatycznych testów, aby potwierdzić to założenie).
źródło
Przyjęta odpowiedź nie działała dla mnie. Odpowiedź na rok 2020 :
1) Metoda (elem.offsetParent! == null) działa poprawnie w przeglądarce Firefox, ale nie w przeglądarce Chrome. W przypadku Chrome „pozycja: stała;” spowoduje również, że offsetParent zwróci „null” nawet element, jeśli jest widoczny na stronie.
Próbny:
możesz zobaczyć tego największego faceta https://stackoverflow.com/a/11639664/4481831 (uruchom go z wieloma przeglądarkami, aby zobaczyć różnice).
2) Funkcja (getComputedStyle (elem) .display! == 'none') nie działa, ponieważ element może być niewidoczny, ponieważ jedna z właściwości display rodzica jest ustawiona na none, getComputedStyle tego nie złapie.
Próbny:
3) (elem.clientHeight! == 0) . Ta metoda nie ma wpływu na ustaloną pozycję, a także sprawdza, czy rodzice elementów nie są widoczni. Ale ma problemy z prostymi elementami, które nie mają układu css, zobacz więcej tutaj
Próbny:
4) (elem.getClientRects (). Length! == 0), które wydają się przekraczać problemy poprzednich 3 metod. Ma jednak problemy z elementami wykorzystującymi sztuczki CSS (inne niż „display: none”) do ukrywania się na stronie.
WNIOSEK: Więc pokazałem wam, że żadna metoda nie jest idealna. Aby właściwie sprawdzić widoczność, musisz użyć kombinacji 3 ostatnich metod.
źródło
Tylko w celach informacyjnych należy zauważyć, że
getBoundingClientRect()
może działać w niektórych przypadkach.Na przykład proste sprawdzenie, czy element jest ukryty,
display: none
może wyglądać mniej więcej tak:Jest to również przydatne, ponieważ obejmuje również zerową szerokość, zerową wysokość i
position: fixed
przypadki. Jednak nie zgłasza elementów ukrytych za pomocąopacity: 0
lubvisibility: hidden
(ale nie maoffsetParent
).źródło
var isVisible = el => (r => r.width && r.height)(el.getBoundingClientRect());
. Następnie można filtrować tablice elementów w następujący sposób:$$(sel).filter(isVisible)
.Znalazłem więc najbardziej wykonalną metodę:
Opiera się to na następujących faktach:
display: none
Elementem (również zagnieżdżonego jeden) nie ma szerokość ani wysokość.visiblity
jesthidden
nawet dla elementów zagnieżdżonych.Nie ma więc potrzeby testowania
offsetParent
ani zapętlania drzewa DOM w celu sprawdzenia, który rodzic mavisibility: hidden
. Powinno to działać nawet w IE 9.Można się spierać, czy
opacity: 0
zwinięte elementy (ma szerokość, ale nie ma wysokości - lub odwrotnie) nie są tak naprawdę widoczne. Ale znowu nie są ukryte.źródło
Mały dodatek do odpowiedzi Ohada Navona.
Jeśli środek elementu należy do innego elementu, nie znajdziemy go.
Aby upewnić się, że jeden z punktów elementu jest widoczny
źródło
Poprawianie powyższej odpowiedzi @Guy Messika , łamanie i zwracanie wartości false, jeśli punkt środkowy „X jest <0” jest błędny, ponieważ prawy element elementu może przejść do widoku. oto poprawka:
źródło
Kod jQuery z http://code.jquery.com/jquery-1.11.1.js ma parametr isHidden
Wygląda więc na to, że istnieje dodatkowa kontrola związana z dokumentem właściciela
Zastanawiam się, czy to naprawdę łapie następujące przypadki:
źródło
Oto kod, który napisałem, aby znaleźć jedyny widoczny spośród kilku podobnych elementów i zwrócić wartość jego atrybutu „class” bez jQuery:
źródło
Oto co zrobiłem:
HTML i CSS: domyślnie ukryto element
JavaScript: Dodano kod sprawdzający, czy widoczność jest ukryta, czy nie:
źródło
Jest to sposób na określenie tego dla wszystkich właściwości css, w tym widoczności:
HTML:
css:
javascript:
Działa z każdą właściwością css i jest bardzo wszechstronny i niezawodny.
źródło