Există vreo modalitate prin care pot verifica dacă un element este vizibil în pură JS (nu jQuery) ?
Astfel, de exemplu, în această pagină: Performanță Biciclete, dacă treceți peste Oferte (din meniul de sus), o fereastră de oferte apar, dar la început nu a fost demonstrat. Este în HTML, dar nu este vizibil.
Deci, având un element de DOM, cum pot verifica dacă acesta este vizibil sau nu? Am incercat:
window.getComputedStyle(my_element)['display']);
dar nu't par a fi de lucru. Mă întreb ce atribute ar trebui să verific. Imi vine in minte:
display !== 'none'
visibility !== 'hidden'
Altele care mi-ar fi lipsit?
În conformitate cu acest MDN documentația, un element's offsetParent de proprietate va reveni
nullori de câte ori el, sau oricare dintre părinții săi, este ascuns, prin stilul de afișare de proprietate. Doar asigurați-vă că elementul este't fix. Un script pentru a verifica acest lucru, dacă nu aveți nici o
position: fixed;` elemente de pe pagina ta, s-ar putea arata ca:
// Where el is the DOM element you'd like to test for visibility
function isHidden(el) {
return (el.offsetParent === null)
}
Pe de alta parte, daca nu au poziție fixă elemente care ar putea fi prins în această căutare, veți trist (și, încet), trebuie să utilizați fereastră.getComputedStyle()
. Funcția în acest caz ar putea fi:
// 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')
}
Opțiunea #2 este, probabil, un pic mai simplă, deoarece conturile pentru mai mult de margine de cazuri, dar pun pariu sale o afacere bună mai lent, de asemenea, deci, dacă va trebui să repetați această operație de mai multe ori, cel mai probabil să-l evite.
Toate celelalte soluții rupt pentru unele situații pentru mine..
Vezi câștigătoare răspunde de rupere la:
http://plnkr.co/edit/6CSCA2fe4Gqt4jCBP2wu?p=preview
În cele din urmă, am decis că cea mai bună soluție a fost $(elem).e(':vizibil')
- cu toate acestea, acest lucru nu este pur javascript. este jquery..
deci m-am uitat la sursa lor si am gasit ce am vrut
jQuery.expr.filters.visible = function( elem ) {
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};
Aceasta este sursa: https://github.com/jquery/jquery/blob/master/src/css/hiddenVisibleSelectors.js
Daca're interesat în vizibil de catre utilizator:
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;
}
Testat pe (folosind moca terminologie):
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;
});
});
Acest lucru poate ajuta : Ascunde elementul de poziționare este pe departe cel mai din stânga poziție și apoi verificați offsetLeft proprietate. Dacă doriți să utilizați jQuery puteți verifica pur și simplu :vizibil selector și pentru a obține starea de vizibilitate a elementului.
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 hidden!!");
}
Utilizați același cod ca și jQuery face:
jQuery.expr.pseudos.visible = function( elem ) {
return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
};
Deci, într-o funcție:
function isVisible(e) {
return !!( e.offsetWidth || e.offsetHeight || e.getClientRects().length );
}
Funcționează ca un farmec în a Câștiga/IE10, Linux/Firefox.45, Linux/Chrome.52...
Multe mulțumiri pentru jQuery fără jQuery!
Combinând câteva răspunsuri de mai sus:
function isVisible (ele) {
var style = window.getComputedStyle(ele);
return style.width !== "0" &&
style.height !== "0" &&
style.opacity !== "0" &&
style.display!=='none' &&
style.visibility!== 'hidden';
}
Ca AlexZ spus, acest lucru poate fi mai lentă decât alte opțiuni, dacă știi mai exact ce ai're în căutarea pentru, dar acest lucru ar trebui să prinde toate modalitățile principale elemente sunt ascunse.
Dar, depinde, de asemenea, ceea ce contează la fel de vizibil pentru tine. De exemplu, un div's înălțimea poate fi setat pentru a 0px dar conținutul încă vizibile în funcție de preaplin proprietăți. Sau un div's, conținutul ar putea fi făcute de aceeași culoare ca fundal, astfel încât nu este vizibil pentru utilizatori, dar încă prestate pe pagina. Sau un div poate fi mutat pe ecran sau ascunse în spatele altor divs, sau's, conținutul ar putea fi non-vizibile, dar frontieră încă vizibile. Într-o anumită măsură "vizibil" este un termen subiectiv.
Dacă elementul este regulat vizibile (display:block și visibillity:vizibil), dar unele container părinte este ascuns, atunci putem folosi clientWidth și clientHeight pentru a verifica asta.
function isVisible (ele) {
return ele.clientWidth !== 0 &&
ele.clientHeight !== 0 &&
ele.style.opacity !== 0 &&
ele.style.visibility !== 'hidden';
}
Am'am luat-o mai performante soluții în comparație cu AlexZ's getComputedStyle (soluție) atunci când unul are poziția 'fix' elemente, dacă este dispus să ignore unele cazuri de margine (verificați comentarii):
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;
}
Notă: Strict vorbind, "vizibilitate" trebuie să fie definite în primul rând. În cazul meu, am în vedere un element vizibil, atâta timp cât eu pot rula toate metodele DOM/properties pe el fara probleme (chiar dacă opacitatea este 0 sau CSS vizibilitate proprietate este 'ascuns' etc).
Dacă ne-am're doar colectarea de bază moduri de detectare vizibilitate, să nu uit:
opacity > 0.01; // probably more like .1 to actually be visible, but YMMV
Și cum să obțină atribute:
element.getAttribute(attributename);
Deci, in exemplul tau:
document.getElementById('snDealsPanel').getAttribute('visibility');
Dar ce? Nu't de lucru aici. Uită-te mai aproape și te'll găsi că vizibilitatea este în curs de actualizare nu ca un atribut pe element, dar folosind "stil" de proprietate. Aceasta este una dintre multele probleme cu care încearcă să faci ceea ce ai're face. Printre altele: puteți't garanta că nu's, de fapt, ceva pentru a vedea într-un element, doar pentru că vizibilitatea, afișare, și opacitatea toate au valorile corecte. S-ar putea ca lipsa de conținut, sau poate lipsa o înălțime și lățime. Un alt obiect s-ar putea să-l acopere. Pentru mai multe detalii, o căutare rapidă pe Google dezvăluie acest, și include chiar și o bibliotecă pentru a încerca rezolvarea problemei. (YMMV)
A verifica afară de următoarele, care sunt posibile duplicate de această întrebare, cu raspunsuri excelente, inclusiv o perspectivă de la puternicul John Resig. Cu toate acestea, dvs. specifice de caz de utilizare este ușor diferită de cea standard, așa că am'll să se abțină de la semnalare:
(EDIT: OP, SPUNE EL'S DECOPERTAREA PAGINI, NU O CREEAZĂ, DECI, MAI JOS ESTE'T ESTE CAZUL) O opțiune mai bună? Lega vizibilitate de elemente de la modelul de proprietăți și de a face întotdeauna vizibilitate depinde de modelul asta, mai mult ca Unghiulare cu ng-show. Puteți face asta folosind orice instrument vrei: Unghiulare, simplu JS, orice. Mai bine încă, puteți schimba DOM punerea în aplicare de-a lungul timpului, dar'll fi întotdeauna în măsură de a citi de stat de la model, în loc de DOM. Citind adevărul de DOM este Rău. Și lent. Mult mai bine să verificați modelul și încredere în aplicare pentru a se asigura că DOM stat reflectă modelul. (Și de a folosi automat de testare pentru a confirma aceasta ipoteza.)
Doar pentru referință ar trebui să fie remarcat faptul că getBoundingClientRect()
pot lucra în anumite cazuri.
De exemplu, o verificare simplă că elementul este ascuns folosind display: none
ar putea arata ceva de genul asta:
var box = element.getBoundingClientRect();
var visible = box.width && box.height;
Acest lucru este, de asemenea, util, deoarece acesta acoperă, de asemenea, zero-width, zero-înălțimea și poziția: fixcazuri. Cu toate acestea, ea nu trebuie să raporteze elemente ascunse cu opacitate: 0 " sau " visibility: hidden
(dar nici nu ar offsetParent
).
Deci, ceea ce am găsit este cel mai fezabile metode:
function visible(elm) {
if(!elm.offsetHeight && !elm.offsetWidth) { return false; }
if(getComputedStyle(elm).visibility === 'hidden') { return false; }
return true;
}
Acest lucru este de a construi pe aceste fapte:
display: none
element (chiar o imbricate una) nu't au o lățime nici înălțimea.vizibilitate
este "ascuns" chiar de elemente imbricate.Deci, nu este nevoie pentru testare offsetParent
sau looping în DOM copac pentru a testa care dintre părinți a visibility: hidden
. Acest lucru ar trebui să funcționeze chiar și în IE 9.
Ai putea argumenta dacă opacitate: 0
și s-a prăbușit elemente (are o lățime dar nici înălțimea - sau viceversa) nu este într-adevăr vizibil, fie. Dar, apoi, din nou, acestea nu sunt per spun ascunse.
Un mic plus față de ohad navon's a răspunde.
În cazul în care centrul de elementul aparține un alt element nu vom't găsi.
Deci, pentru a face sigur că unul dintre punctele de elementul este găsit pentru a fi vizibil
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;
}
Îmbunătățirea pe @Tip Messika's raspuns mai sus, de rupere și se întoarce false dacă punctul central' X < 0 este greșit ca element de dreapta poate merge în vedere. aici's un fix:
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;
}
Codul jQuery de la http://code.jquery.com/jquery-1.11.1.js are o isHidden param
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 );
};
Deci, se pare ca acolo este o verificare suplimentară referitoare la proprietarul document
Mă întreb dacă într-adevăr prinde următoarele cazuri:
Aceasta returnează valoarea true dacă și numai dacă elementul și toți strămoșii săi sunt vizibile. Se pare doar la "display" și vizibilitatea'style proprietăți:
var isVisible = function(el){
// returns true iff el and all its ancestors are visible
return el.style.display !== 'none' && el.style.visibility !== 'hidden'
&& (el.parentElement? isVisible(el.parentElement): true)
};
Aici's codul l-am scris pentru a găsi vizibile doar între câteva elemente similare, și să se întoarcă valoarea "clasa" atribut fără 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");
}
}
Aceasta este ceea ce am făcut:
HTML & CSS: a Făcut element ascuns în mod implicit
<html>
<body>
<button onclick="myFunction()">Click Me</button>
<p id="demo" style ="visibility: hidden;">Hello World</p>
</body>
</html>
JavaScript: Adăugat un cod pentru a verifica dacă vizibilitatea este ascuns sau nu:
<script>
function myFunction() {
if ( document.getElementById("demo").style.visibility === "hidden"){
document.getElementById("demo").style.visibility = "visible";
}
else document.getElementById("demo").style.visibility = "hidden";
}
</script>
Aceasta este o modalitate de a determina pentru toate proprietățile css inclusiv vizibilitatea:
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');
}
Acesta funcționează pentru orice proprietate css și este foarte versatil și de încredere.