2012-01-17 6 views
65

Devo verificare con jQuery se un elemento DIV non sta cadendo fuori dallo schermo. Gli elementi sono visibili e visualizzati secondo attributi CSS, ma potrebbero essere intenzionalmente posizionati off-screen:Come verificare se un elemento è fuori dallo schermo

position: absolute; 
left: -1000px; 
top: -1000px; 

non ho potuto usare il :visible selettore jQuery come elemento ha un diverso da zero altezza e larghezza.

Non sto facendo niente di speciale. Questo posizionamento in posizione assoluta è il modo in cui il mio framework Ajax implementa il nascondiglio/spettacolo di alcuni widget.

+0

ho dato una risposta a questa e su questa questione 'duplicato': http://stackoverflow.com/ domande/5353934/check-if-element-is-visible-on-screen/5354536 # 5354536 – Tokimon

risposta

101

dipende da ciò che la tua definizione di "fuori campo" è. È all'interno del viewport o all'interno dei limiti definiti della tua pagina?

Usando Element.getBoundingClientRect() si può facilmente rilevare o meno il vostro elemento è entro i boundries della vostra finestra (vale a dire su schermo o fuori campo):

jQuery.expr.filters.offscreen = function(el) { 
    var rect = el.getBoundingClientRect(); 
    return (
      (rect.x + rect.width) < 0 
      || (rect.y + rect.height) < 0 
      || (rect.x > window.innerWidth || rect.y > window.innerHeight) 
     ); 
}; 

È quindi possibile utilizzare che in diversi modi:

// returns all elements that are offscreen 
$(':offscreen'); 

// boolean returned if element is offscreen 
$('div').is(':offscreen'); 
+1

Mi è piaciuto, ma si interrompe se il tuo elemento si trova all'interno di un contenitore scorrevole: un elemento nella parte inferiore di un DIV alto due schermi sarà sempre "disattivato" poiché l'altezza della finestra è inferiore all'offsetTop dell'elemento. – Coderer

+0

@scurker Non ho potuto farlo funzionare. Ecco la mia domanda SO (con jsFiddle) sul problema: http://stackoverflow.com/questions/26004098/extend-jquery-to-create-custom-filter-re-element-outside-viewport – crashwap

+0

ho sbagliato qui a pensa che questo non succederà se el ha posizionato il genitore (assoluto o relativo) davanti al corpo? –

-1

Si potrebbe verificare la posizione del div con $(div).position() e verificare se le proprietà dei margini sinistro e superiore sono meno di 0:

if($(div).position().left < 0 && $(div).position().top < 0){ 
    alert("off screen"); 
} 
+2

Cosa succede se il div non è negativo fuori dalla vista? – dude

16

C'è uno jQuery plugin here che consente agli utenti di verificare se un elemento rientra nella vista visibile del browser, tenendo conto della posizione di scorrimento del browser.

$('#element').visible(); 

Si può anche verificare la presenza di una visibilità parziale:

$('#element').visible(true); 

Uno svantaggio è che funziona solo con il posizionamento verticale/scorrimento, anche se dovrebbe essere abbastanza facile da aggiungere posizionamento orizzontale nel mix.

+0

Questo è un plugin MOLTO leggero. Sono stato in grado di ottenere una barra di navigazione fissa su per scorrere e lavorare in modo reattivo entro pochi minuti dall'aggiunta. Grande suggerimento. – Nappstir

+0

Questo plugin è molto leggero e abbastanza facile da implementare. Risolto il problema che avevo con i sottomenu. –

3

ho creato a small plugin that does this, e ha alcune opzioni flessibili (funziona anche quando si ridimensiona la finestra del browser).

+0

Come rimuovere la classe 'right-edge'? su questo sito di test [link] http://archeo.ecrc.pl/ element '.sub-menu', una volta applicata la classe' right-edge' non viene rimossa dopo il ridimensionamento della finestra del browser. – Daniel

+0

@Daniel Ci scusiamo per la risposta follemente in ritardo. Ma ora è risolto :) –

7

Non è necessario un plug-in per verificare se al di fuori della porta di visualizzazione.

var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0) 
var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0) 
var d = $(document).scrollTop(); 

$.each($("div"),function(){ 
    p = $(this).position(); 
    //vertical 
    if (p.top > h + d || p.top > h - d){ 
     console.log($(this)) 
    } 
    //horizontal 
    if (p.left < 0 - $(this).width() || p.left > w){ 
     console.log($(this)) 
    } 
}); 
+0

Funzionerebbe se si usasse '$ (this) .offset' invece di' $ this.position'. In questo momento sta solo calcolando la distanza dal suo genitore, che potrebbe essere un div che lo avvolge perfettamente. –

1

Bene ... Ho trovato alcuni problemi in ogni soluzione proposta qui.

  • Si dovrebbe essere in grado di scegliere se intero elemento di essere sullo schermo o solo una parte di esso
  • soluzioni proposte non riesce se elemento è più alta/più larga finestra e un pò copre la finestra del browser.

Qui è la mia soluzione che includono jQuery.fn funzione di istanza e expression. Ho creato più variabili all'interno della mia funzione di quanto avrei potuto, ma per problemi logici complessi mi piace dividerlo in parti più piccole e chiaramente denominate.

sto usando getBoundingClientRect metodo che restituisce posizione elemento relativamente alla finestra quindi non ho bisogno di preoccuparsi posizione di scorrimento

Usage:

$(".some-element").filter(":onscreen").doSomething(); 
$(".some-element").filter(":entireonscreen").doSomething(); 
$(".some-element").isOnScreen(); // true/false 
$(".some-element").isOnScreen(true); // true/false (partially on screen) 
$(".some-element").is(":onscreen"); // true/false (partially on screen) 
$(".some-element").is(":entireonscreen"); // true/false 

Fonte:

$.fn.isOnScreen = function(partial){ 

    //let's be sure we're checking only one element (in case function is called on set) 
    var t = $(this).first(); 

    //we're using getBoundingClientRect to get position of element relative to viewport 
    //so we dont need to care about scroll position 
    var box = t[0].getBoundingClientRect(); 

    //let's save window size 
    var win = { 
     h : $(window).height(), 
     w : $(window).width() 
    }; 

    //now we check against edges of element 

    //firstly we check one axis 
    //for example we check if left edge of element is between left and right edge of scree (still might be above/below) 
    var topEdgeInRange = box.top >= 0 && box.top <= win.h; 
    var bottomEdgeInRange = box.bottom >= 0 && box.bottom <= win.h; 

    var leftEdgeInRange = box.left >= 0 && box.left <= win.w; 
    var rightEdgeInRange = box.right >= 0 && box.right <= win.w; 


    //here we check if element is bigger then window and 'covers' the screen in given axis 
    var coverScreenHorizontally = box.left <= 0 && box.right >= win.w; 
    var coverScreenVertically = box.top <= 0 && box.bottom >= win.h; 

    //now we check 2nd axis 
    var topEdgeInScreen = topEdgeInRange && (leftEdgeInRange || rightEdgeInRange || coverScreenHorizontally); 
    var bottomEdgeInScreen = bottomEdgeInRange && (leftEdgeInRange || rightEdgeInRange || coverScreenHorizontally); 

    var leftEdgeInScreen = leftEdgeInRange && (topEdgeInRange || bottomEdgeInRange || coverScreenVertically); 
    var rightEdgeInScreen = rightEdgeInRange && (topEdgeInRange || bottomEdgeInRange || coverScreenVertically); 

    //now knowing presence of each edge on screen, we check if element is partially or entirely present on screen 
    var isPartiallyOnScreen = topEdgeInScreen || bottomEdgeInScreen || leftEdgeInScreen || rightEdgeInScreen; 
    var isEntirelyOnScreen = topEdgeInScreen && bottomEdgeInScreen && leftEdgeInScreen && rightEdgeInScreen; 

    return partial ? isPartiallyOnScreen : isEntirelyOnScreen; 

}; 

$.expr.filters.onscreen = function(elem) { 
    return $(elem).isOnScreen(true); 
}; 

$.expr.filters.entireonscreen = function(elem) { 
    return $(elem).isOnScreen(true); 
}; 
+0

Ottengo make_footer_down.js: 8 Uncaught TypeError: Impossibile leggere la proprietà 'getBoundingClientRect' di undefined quando si tenta di utilizzare le sue funzioni lì. – Lurr

+0

Ciao Lurr ... Ho provato con $ ("# divId"). IsOnScreen (true); dove 'divId' era fuori schermo e mi restituiva 'falso'; quindi, sento che funziona – Anirban

0
  • Ottenere la distanza dalla parte superiore dell'elemento specificato
  • Aggiungere l'altezza dello stesso elemento specificato. Questo ti dirà il numero totale dalla parte superiore dello schermo fino alla fine dell'elemento specificato.
  • Poi tutto quello che dovete fare è sottrarre tale da altezza totale documento

    jQuery(function() { 
        var documentHeight = jQuery(document).height(); 
        var element = jQuery('#you-element'); 
        var distanceFromBottom = documentHeight - (element.position().top + element.outerHeight(true)); 
        alert(distanceFromBottom) 
    });