2015-09-22 9 views
6

Ho un problema che voglio rilevare se un elemento è coperto da un altro in una pagina.Come rilevare se un elemento è coperto/sovrapposto da un altro?

es:

DOM elements 
<div class="ele ele1"><p>A</p></div> 
<div class="ele ele2"><p>B</p></div> 
<div class="ele ele3"><p>C</p></div> 
<div class="cover"><p>D</p></div> 


CSS style 
.ele{ 
    display: inline-block; 
    width: 100px; 
    height: 100px; 
    position: relative; 
} 
p{ 
    width: 100%; 
    text-align: center; 
} 
.ele1{ 
    background-color: red; 
} 
.ele2{ 
    background-color: blue; 
} 
.ele3{ 
    background-color: green; 
} 
.cover{ 
    position: absolute; 
    width: 100px; 
    height: 100px; 
    left: 300px; 
    top: 10px; 
    background: grey; 
} 

http://jsfiddle.net/veraWei/6v89b1fy/

Come rilevare elemento A non è stato coperto ma elemento C è coperto da ele D? Un'altra cosa: il numero di "D" è incerto. Forse ci sono E/F/G ... nella pagina. Apprezzo tutti i pensieri o esempi esistenti/plugin jQuery/CSS/ecc.

Grazie a tutte le risposte dettagliate dei tuoi ragazzi. Ma ho bisogno di una spiegazione più breve forse di un attributo che indica che A non è coperto da alcun elemento e C è coperto dal rendering. C'è qualche plugin o attributo esistente?

+1

violino non corretto –

+0

non capire la domanda. cosa intendi per coperto? intendi sovrapporre l'elemento? –

+1

vuoi dire c è coperto da d? – guradio

risposta

1

Stai cercando qualcosa di simile?

http://jsfiddle.net/6v89b1fy/4/

var coverElem = $(".cover"); 
var elemArray = []; 
elemArray.push($(".ele1"), $(".ele2"), $(".ele3")); 

for(i=0; i< elemArray.length; i++) 
{ 
    var currElemOffset = elemArray[i].offset(); 
    var currElemWidth = elemArray[i].width(); 

    var currElemStPoint = currElemOffset.left ; 
    var currElemEndPoint = currElemStPoint + currElemWidth; 


    if(currElemStPoint <= coverElem.offset().left && coverElem.offset().left <= currElemEndPoint) 
    { 
     elemArray[i].append("<span>Covered</span>"); 
    } 
    else 
    { 
     elemArray[i].append("<span>Not covered</span>"); 
    } 
} 
+0

Grazie mille, per il numero determinato di elementi, il codice sopra è funzionante. Ma penso che la mia richiesta sia incerta: gli elementi del numero. –

+0

In questo caso dovrai raggruppare gli elementi base in una raccolta e coprire gli elementi in un'altra raccolta. Ora ogni elemento del 1 ° gruppo deve essere controllato contro ogni singolo elemento presente nella raccolta degli elementi coperti. Puoi modificare il codice sopra molto facilmente per abilitarlo. Per favore fatemi sapere se avete bisogno di ulteriore aiuto. – vijayP

+0

Questo metodo non cattura tutti i modi possibili per "coprire" qualcosa, ad esempio https://jsfiddle.net/2kr1s5r5/ Quello a destra è etichettato erroneamente come non coperto. – DrunkWolf

0

OK. Ho attraversato tutti i casi di sovrapposizione e hanno creato questo fiddle. Ho usato getBoundintClientRect() e l'ho usato per ottenere top, left, bottom, right valori di due div s su cui è necessario verificare la sovrapposizione e quindi ho confrontato gli offset utilizzando varie istruzioni condizionali e condizioni anch'esse che troverete sotto. Nel violino tutti i tuoi quattro elementi stanno avendo position: absolute, modifica i loro valori top e left per farli sovrapporre l'un l'altro e per verificare se due elementi si sovrappongono o no? passare i due elementi nella funzione -

checkElements(elA, elB); // pass two elements to check 

che è nell'ultimo.

Vedrete le lunghe condizioni ifelse nel violino, sono solo per testare tutte le possibilità di sovrapposizione. Qui è che tutte le condizioni possibili utilizzati per controllare la sovrapposizione -

if((eleB.top >= eleA.top && eleB.top <= eleA.bottom) || (eleB.bottom >= eleA.top && eleB.bottom <= eleA.bottom)) { 
    if((eleB.left >= eleA.left && eleB.left <= eleA.right) || (eleB.right >= eleA.left && eleB.right <= eleA.right)) { 
     el1.innerHTML = '<p>covered</p>'; 
    } 
    else { 
     el1.innerHTML = '<p>not covered</p>'; 
    } 
} 
else { 
    el1.innerHTML = '<p>not covered</p>'; 
} 

Si vedrà anche se B si sovrappone Un'allora scriverà un è coperto perché l'ho confrontato con coordinate x e y di A e B In questo caso, verrà utilizzata una condizione aggiuntiva per il controllo di z-index. Non l'ho creato per quello.

Controllare il fiddle e regolare top e left valore delle diverse componenti e quindi passare due elementi nella funzione checkElements() e vedere il risultato è corretto o meno.

si può anche fare tutto il controllo simultaneamente come -

checkElements(elA, elB); // check if A is overlapped by B 
checkElements(elB, elC); // check if B is overlapped by C 
checkElements(elC, elD); // check if C is overlapped by D 

Vedere questo fiddle utilizzando il controllo multiplo.

EDIT: Se looping è il problema, allora è possibile combinare tutti i loop di ifelse in un unico ifelse come questo -

if(((eleB.top >= eleA.top && eleB.top <= eleA.bottom) || (eleB.bottom >= eleA.top && eleB.bottom <= eleA.bottom)) && ((eleB.left >= eleA.left && eleB.left <= eleA.right) || (eleB.right >= eleA.left && eleB.right <= eleA.right))) { 
    el1.innerHTML = '<p>covered</p>'; // or your code of adding true to the attribute that tells about overlapping 
} 
else { 
    el1.innerHTML = '<p>not covered</p>'; 
} 

Updated fiddle

+0

Ok, capisco. è male che non ci sia un attributo così incorporato. Forse dovrei considerare un altro modo per risolvere il problema nel vero progetto. Grazie mille. –

1

Ecco un un rapido esempio di come si può fare per farlo. Ciò verificherebbe il sia lo sovrapposizione verticale che orizzontale. Questo è un po 'generico e non così generico poiché si basa sull'HTML nella tua domanda. Regola i valori superiore/sinistro dello .cover per vederlo funzionare per tutti i casi possibili.

var $cover = $(".cover"), 
 
    cWidth = $cover.width(), 
 
    cHeight = $cover.height(), 
 
    cLeft = $cover.offset().left, 
 
    cRight = $(window).width() - (cLeft + cWidth), 
 
    cTop = $cover.offset().top, 
 
    cBtm = $(window).height() - (cTop + cHeight); 
 

 
$("div:not(.cover)").each(function() { 
 

 
    var $this = $(this), 
 
    eleWidth = $this.width(), 
 
    eleHeight = $this.height(), 
 
    eleLeft = $this.offset().left, 
 
    eleTop = $this.offset().top, 
 
    eleRight = $(window).width() - (eleLeft + eleWidth), 
 
    eleBtm = $(window).height() - (eleTop + eleHeight); 
 

 
    if (
 
    cLeft < (eleLeft + eleWidth) && 
 
    cRight < (eleRight + eleWidth) && 
 
    cTop < (eleTop + eleHeight) && 
 
    cBtm < (eleBtm + eleHeight) 
 
) { 
 
    alert($this.text() + " is covered by " + $cover.text()); 
 
    } 
 
});
.ele { 
 
    display: inline-block; 
 
    width: 100px; 
 
    height: 100px; 
 
    position: relative; 
 
    margin-top: 40px; 
 
} 
 
p { 
 
    width: 100%; 
 
    text-align: center; 
 
} 
 
.ele1 { 
 
    background-color: red; 
 
} 
 
.ele2 { 
 
    background-color: blue; 
 
} 
 
.ele3 { 
 
    background-color: green; 
 
} 
 
.cover { 
 
    position: absolute; 
 
    width: 100px; 
 
    height: 100px; 
 
    left: 60px; 
 
    top: 110px; 
 
    background: grey; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<div class="ele ele1"> 
 
    <p>A</p> 
 
</div> 
 
<div class="ele ele2"> 
 
    <p>B</p> 
 
</div> 
 
<div class="ele ele3"> 
 
    <p>C</p> 
 
</div> 
 
<div class="ele ele3"> 
 
    <p>D</p> 
 
</div> 
 
<div class="ele ele3"> 
 
    <p>E</p> 
 
</div> 
 
<div class="ele ele3"> 
 
    <p>F</p> 
 
</div> 
 
<div class="ele ele3"> 
 
    <p>G</p> 
 
</div> 
 
<div class="cover"> 
 
    <p>COVER</p> 
 
</div>

+0

Grazie per la codifica qui. Ma penso che tutto il ciclo non sia il modo più appropriato. Nel caso reale, ci saranno molti elementi e tutti sono dinamici. Quindi ho bisogno di più è se il loro è un attributo che indica che l'elemento è coperto o meno, e l'attributo restituirà vero o falso? –

2

perché non provare la seguente:

1) Trovare la posizione dell'elemento rispetto al viewport:

rect=elt.getBoundingClientRect(); 
x=rect.left; 
y=rect.top; 

(o possono essere considerare i punti medi coordinate)

2) Trova la t elemento op alla posizione x, y:

topElt=document.elementFromPoint(x,y); 

3) Verificare se l'elemento superiore è lo stesso di quello dell'elemento originale:

if(elt.isSameNode(topElt)) console.log('no overlapping'); 
+0

Penso che questa sia la risposta efficiente, moderna ed efficiente della cpu. – Laimis

+0

Dopo alcune ricerche lo stato 'document.elementFromPoint()' è ancora tecnologia sperimentale. Fonte: https://developer.mozilla.org/en-US/docs/Web/API/DocumentOrShadowRoot/elementFromPoint – Bayu

+0

Anche l'uso di 'isSameNode()' non sembra davvero compatibile con i browser. Fonte: https://developer.mozilla.org/en-US/docs/Web/API/Node/isSameNode – Bayu

Problemi correlati