Kaip patikrinti, ar elementas iš tikrųjų rodomas naudojant „JavaScript“

Kaip patikrinti, ar elementas yra tikrai matomas?

Aš ne tik noriu patikrinti visibility ir display atributus. Aš turiu galvoje, patikrindamas, ar elementas nėra

  • visibility: hidden arba display: none
  • pagal kitą elementą
  • slinkia ekrano kraštą.

Dėl techninių priežasčių negaliu įgalinti jokių scenarijų. Tačiau galiu naudoti Prototipą , kaip jau daroma puslapyje.

112
01 апр. Macha nustatė 01 Bal 2009-04-01 12:28 '09, 12:28, 2009-04-01 12:28
@ 17 atsakymų

2 punktas.

Matau, kad niekas nepasiūlė naudoti document.elementFromPoint(x,y) , man tai yra greičiausias būdas patikrinti, ar elementas yra įdėtas ar paslėptas kito. Tikslinio elemento nuokrypį galite perkelti į funkciją.

Čia yra PPK testavimo puslapis elementeFromPoint .

90
25 мая '09 в 7:41 2009-05-25 07:41 Atsakymas Christophe Eblé gegužės 25 d., 09:41, 2009-05-25 07:41

Nežinau, kiek iš jų yra palaikomos senosios ar ne modernios naršyklės, tačiau naudoju kažką panašaus (be jokių bibliotekų failų):

 function visible(element) { if (element.offsetWidth === 0 || element.offsetHeight === 0) return false; var height = document.documentElement.clientHeight, rects = element.getClientRects(), on_top = function(r) { var x = (r.left + r.right)/2, y = (r.top + r.bottom)/2; document.elementFromPoint(x, y) === element; }; for (var i = 0, l = rects.length; i < l; i++) { var r = rects[i], in_viewport = r.top > 0 ? r.top <= height : (r.bottom > 0  r.bottom <= height); if (in_viewport  on_top(r)) return true; } return false; } 

Ji patikrina, ar elemento plotas yra> 0, ir tada patikrina, ar bet kuri elemento dalis yra žiūrėjimo srityje, ir kad ji nėra paslėpta po „kita“ (iš tikrųjų tik vieną tašką elemento centre, todėl jis nėra 100% garantuotas - bet jūs galite tiesiog pakeisti scenarijų, kad jį kartotumėte visuose elemento taškuose, jei jums tikrai reikia ...).

Atnaujinti

border=0

Pakeista on_top funkcija, kuri tikrina kiekvieną tašką:

 on_top = function(r) { for (var x = Math.floor(r.left), x_max = Math.ceil(r.right); x <= x_max; x++) for (var y = Math.floor(r.top), y_max = Math.ceil(r.bottom); y <= y_max; y++) { if (document.elementFromPoint(x, y) === element) return true; } return false; }; 

Aš nežinau apie našumą :)

36
09 окт. atsakymas pateiktas Tobias 09 okt. 2009-10-09 13:00 '09 13:00 val. 2009-10-09 13:00

Kaip parodė jkl, elemento matomumo ar rodymo tikrinimas nėra pakankamas. Jūs turite patikrinti savo protėvius. Selenas tai daro, kai patikrina elemento matomumą.

Pažvelkite į Selenium.prototype.isVisible metodą selenium-api.js faile.

http://svn.openqa.org/svn/selenium-on-rails/selenium-on-rails/selenium-core/scripts/selenium-api.js

8
17 мая '10 в 9:39 2010-05-17 09:39 Atsakymas Jason Tillery'ui gegužės 17 d. 10 val. 9:39 2010-05-17 09:39

Įdomus klausimas.

Tai bus mano požiūris.

  • Pirmiausia patikrinkite, ar elementas.style.visibility! == 'paslėpta' element.style.display! == „niekas“
  • Tada išbandykite su document.elementFromPoint (elementas.offsetLeft, element.offsetTop), jei grąžintas elementas yra elementas, kurį tikiuosi, sunku nustatyti, ar elementas visiškai sutampa.
  • Galiausiai, jei peržiūros srityje yra offsetTop ir offsetLeft, atsižvelgiant į slinkties poslinkius.

Tikiuosi, kad tai padės.

4
24 мая '09 в 21:33 2009-05-24 21:33 Christophe Eblé atsakymas gegužės 29 d., 09:21, 2009-05-24 21:33

Štai ką aš iki šiol turėjau. Jis apima ir 1, ir 3. Aš vis dar kovoja su 2, nes nesu susipažinęs su prototipu (aš esu labiau panašus į jQuery tipą).

 function isVisible( elem ) { var $elem = $(elem); // First check if elem is hidden through css as this is not very costly: if ($elem.getStyle('display') == 'none' || $elem.getStyle('visibility') == 'hidden' ) { //elem is set through CSS stylesheet or inline to invisible return false; } //Now check for the elem being outside of the viewport var $elemOffset = $elem.viewportOffset(); if ($elemOffset.left < 0 || $elemOffset.top < 0) { //elem is left of or above viewport return false; } var vp = document.viewport.getDimensions(); if ($elemOffset.left > vp.width || $elemOffset.top > vp.height) { //elem is below or right of vp return false; } //Now check for elements positioned on top: //TODO: Build check for this using Prototype... //Neither of these was true, so the elem was visible: return true; } 
4
24 мая '09 в 18:47 2009-05-24 18:47 atsakymą pateikė Pim Jager , gegužės 24 d., 09:18, 2009-05-24 18:47

Prototipo elementų biblioteka yra viena iš galingiausių užklausų bibliotekų metodų požiūriu. Aš rekomenduoju jums patikrinti API.

Kai kurie patarimai:

  • Matomumo patikrinimai gali būti skausmas, tačiau galite naudoti Element.getStyle() ir Element.visible() metodus, sujungtus į pasirinktą funkciją. Su getStyle() galite patikrinti faktinį apskaičiuotą stilių.

  • Aš nežinau, ką reiškia „apačioje“ :) Jei turėjote omenyje, kad jis turi tam tikrą protėvį, pvz., „ Element.up(cssRule) div“, galite naudoti „ Element.up(cssRule) :

     var child = $("myparagraph"); if(!child.up("mywrapper")){ // I lost my mom! } else { // I found my mom! } 

    Jei norite patikrinti vaiko brolius / seserus, taip pat galite tai padaryti:

     var child = $("myparagraph"); if(!child.previous("mywrapper")){ // I lost my bro! } else { // I found my bro! } 
  • Vėlgi, elementas lib gali padėti jums, jei aš teisingai suprantu, ką jūs galvojate :) Jūs galite patikrinti faktinius peržiūros srities matmenis ir elemento poslinkį, kad galėtumėte apskaičiuoti, ar jūsų elementas yra „išjungtas“.

Sėkmės!

Įterpiau prototipų bandymo pavyzdį adresu http://gist.github.com/117125 . Atrodo, kad jūsų atveju mes tiesiog negalime pasitikėti getStyle() . Kad maksimaliai padidintumėte „isMyElementReallyVisible“ funkcijos patikimumą, turite derinti šiuos veiksmus:

  • Kompiuterinio stiliaus tikrinimas (dojo turi puikų įgyvendinimą , kurį galite atlikti)
  • „Viewportoffset“ peržiūros patvirtinimas (paties metodo prototipas)
  • „Z“ indekso tikrinimas „žemiau“ („Internet Explorer“ gali būti klaida)
3
23 мая '09 в 22:47 2009-05-23 22:47 atsakymą pateikė „ Yaanno “ gegužės 23 d. 09 val. 22:47 2009-05-23 22:47

Vienas iš būdų tai padaryti yra:

 isVisible(elm) { while(elm.tagName != 'BODY') { if(!$(elm).visible()) return false; elm = elm.parentNode; } return true; } 

Kreditai: https://github.com/atetlaw/Really-Easy-Field-Validation/blob/master/validation.js#L178

2
12 сент. atsakymas duotas umpirsky 12 sep . 2011-09-12 09:54 '11 at 9:54 2011-09-12 09:54

Nenorėčiau nukreipti jus į jQuery (kaip dažnai daroma), tačiau ši diskusija apie tai, kada elementai yra tikrai matomi, yra labai įžvalgus.

Ir nuo 1.3.2 d. , Tai nebėra problema .

1
01 апр. Atsakymą pateikė Ólafur Waage 01 Bal. 2009-04-01 12:33 '09, 12:33 2009-04-01 12:33

Sugavimo ir nutekėjimo įvykiai ir naršymas (onmouseup, onresize, onscroll).

Baigę vilkti, nuvilkto elemento riba lyginama su visais „dominančiais elementais“ (t. Y. Elementais, turinčiais „dont_hide“ klasės arba identifikatorių masyvo). Darykite tą patį su window.onscroll ir window.onresize. Pažymėkite visus elementus, paslėptus specialiu atributu arba klasės pavadinimu, arba tiesiog atlikite bet kokius veiksmus, kuriuos norite ten.

Paslėpti testai yra gana paprasti. Jei norite „visiškai paslėpti“, norite žinoti, ar visi kampai yra vilkimo elemento ribose arba už peržiūros srities ribų. Dėl dalinio paslėpimo ieškote vieno kampo, kuris atitinka tą patį bandymą.

1
24 мая '09 в 17:13 2009-05-24 17:13 atsakymą pateikė „ SpliFF “ gegužės 29 d., 17:13, 2009-05-24 17:13

Nemanau, kad elemento matomumo ir rodymo savybių tikrinimas yra pakankamai geras reikalui Nr. 1, net jei naudojate currentStyle / getComputedStyle. Taip pat turėtumėte patikrinti elemento protėvius Jei protėvis yra paslėptas, tada elementas.

1
21 сент. atsakymą pateikė vartotojo176652 21 sep . 2009-09-21 19:16 '09 19:16 2009-09-21 19:16

Pabandykite element.getBoundingClientRect() . Jis grąžins objektą su savybėmis.

  • apačioje
  • viršuje
  • į dešinę
  • į kairę
  • plotis - priklauso nuo naršyklės
  • aukštis - priklauso nuo naršyklės

Įsitikinkite, kad elemento „ BoundingClientRect plotis ir aukštis nėra nulis, tai yra paslėptų ar nematomų elementų vertė. Jei vertė yra didesnė už nulį, elementas turi būti matomas kūne. Tada patikrinkite, ar bottom nuosavybė yra mažesnė už screen.height , o tai reiškia, kad elementas yra peržiūros srityje. (Techniškai, jūs taip pat turite apsvarstyti naršyklės >

0
05 июня '14 в 8:13 2014-06-05 08:13 atsakymas pateikiamas j_v_wow_d birželio 05 '14, 8:13 2014-06-05 08:13

Patikrinkite kompensuojamų aukščio elementų savybes. Jei jis yra didesnis nei 0, jis matomas. Pastaba: šis metodas neapima situacijos, kai matomas matomumas: paslėptas stilius. Tačiau šis stilius yra kažkas keista.

0
01 апр. atsakymas duotas Sergejui Ilinskiui 01 Bal. 2009-04-01 12:34 '09 12:34 2009-04-01 12:34

Čia yra pavyzdinis scenarijus ir bandymo pavyzdys. Pastatytų elementų dangteliai, matomi: paslėpta, ekranas: ne. Netikrintas z-indeksas, tarkime, jis veikia.

 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title></title> <style type="text/css"> div { width: 200px; border: 1px solid red; } p { border: 2px solid green; } .r { border: 1px solid #BB3333; background: #EE9999; position: relative; top: -50px; height: 2em; } .of { overflow: hidden; height: 2em; word-wrap: none; } .of p { width: 100%; } .of pre { display: inline; } .iv { visibility: hidden; } .dn { display: none; } </style> <script src="http://www.prototypejs.org/assets/2008/9/29/prototype-1.6.0.3.js"></script> <script> function isVisible(elem){ if (Element.getStyle(elem, 'visibility') == 'hidden' || Element.getStyle(elem, 'display') == 'none') { return false; } var topx, topy, botx, boty; var offset = Element.positionedOffset(elem); topx = offset.left; topy = offset.top; botx = Element.getWidth(elem) + topx; boty = Element.getHeight(elem) + topy; var v = false; for (var x = topx; x <= botx; x++) { for(var y = topy; y <= boty; y++) { if (document.elementFromPoint(x,y) == elem) { // item is visible v = true; break; } } if (v == true) { break; } } return v; } window.onload=function() { var es = Element.descendants('body'); for (var i = 0; i < es.length; i++ ) { if (!isVisible(es[i])) { alert(es[i].tagName); } } } </script> </head> <body id='body'> <div class="s"><p>This is text</p><p>More text</p></div> <div class="r">This is relative</div> <div class="of"><p>This is too wide...</p><pre>hidden</pre> <div class="iv">This is invisible</div> <div class="dn">This is display none</div> </body> </html> 
0
atsakymas pateikiamas p. 25 мая '09 в 18:45 2009-05-25 18:45 Šviesus ir naujas 宇 宇 gegužės 25, '09, 18:45 pm 2009-05-25 18:45
  function isVisible(el, isDeep) { var elIsVisible = true; if("undefined" === typeof isDeep) { isDeep = true; } elIsVisible = elIsVisible  el.offsetWidth > 0  el.offsetHeight > 0; if(isDeep  elIsVisible) { while('BODY' != el.tagName  elIsVisible) { elIsVisible = elIsVisible  'hidden' != window.getComputedStyle(el).visibility; el = el.parentElement; } } return elIsVisible; } 
0
11 февр. Atsakymas pateikiamas Oleksandr knygos 11 vasario mėn. 2014-02-11 19:07 '14, 19:07, 2014-02-11 19:07

Galite naudoti „clientHeight“ arba „clientWidth“ savybes

 function isViewable(element){ return (element.clientHeight > 0); } 
0
13 февр. atsakymas pateikiamas 13 vasario mėn. 2014-02-13 17:33 '14 ne 17:33 2014-02-13 17:33

Čia yra dalis atsakymo, kuriame teigiama, kad elementas yra peržiūros srityje. Gali reikėti patikrinti kažką ant jo, naudodami elementFromPoint, bet tai šiek tiek ilgiau.

 function isInViewport(element) { var rect = element.getBoundingClientRect() var windowHeight = window.innerHeight || document.documentElement.clientHeight var windowWidth = window.innerWidth || document.documentElement.clientWidth return rect.bottom > 0  rect.top < windowHeight  rect.right > 0  rect.left < windowWidth } 
-1
26 авг. atsakymas pateikiamas MoOx 26 d. 2014-08-26 10:56 '14 at 10:56 2014-08-26 10:56

Atsakymas į pirmąjį klausimą yra gana paprastas, jei vis tiek galite naudoti prototipą (prototypejs):

 $('HtmlElementID').visible(); returns: true|false 
-1
19 авг. atsakymas duotas Tr1stan 19 rug . 2009-08-19 17:48 '09 at 17:48 PM 2009-08-19 17:48

Kiti klausimai apie „ žymių arba Užduoti klausimą