Kaydırma işleminden sonra öğenin görünür olup olmadığı nasıl kontrol edilir?


1170

AJAX ile eleman yüklüyorum. Bazıları yalnızca sayfayı aşağı kaydırırsanız görünür.
Bir öğenin artık sayfanın görünür kısmında olup olmadığını bilmemin bir yolu var mı?


42
tarayıcı penceresinde belirli bir öğenin görüntülenip görüntülenmediğini veya kullanıcının öğeyi görmek için kaydırması gerekip gerekmediğini bilmek istediği anlamına gelir.
Romain Linsolas

1
Bir öğenin bir kapta tamamen görünür olup olmadığını kontrol etmek için, fazladan bir seçici parametre ekleyin ve bunun için elem kodunu tekrar kullanın. Library.IsElementVisibleInContainer = function (elementSelector, containerSelector) { var containerViewTop = $(containerSelector).offset().top; var containerViewBottom = containerViewTop + $(containerSelector).height();
Yaşamları



1
Tüm cevaplar yeniden doldurmayı tetikleyecek, böylece şişe boynu olabilir, destekleniyorsa IntersectionObserver kullanmalısınız . Modern tarayıcılarda daha iyi performans gösterecek,
jcubic

Yanıtlar:


1258

Bu hile yapmalı:

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
}

Basit Yardımcı Program İşlevi Bu, aradığınız öğeyi kabul eden ve öğenin tamamen görüntülenmesini veya kısmen görünmesini istiyorsanız bir yardımcı program işlevini çağırmanıza olanak tanır.

function Utils() {

}

Utils.prototype = {
    constructor: Utils,
    isElementInView: function (element, fullyInView) {
        var pageTop = $(window).scrollTop();
        var pageBottom = pageTop + $(window).height();
        var elementTop = $(element).offset().top;
        var elementBottom = elementTop + $(element).height();

        if (fullyInView === true) {
            return ((pageTop < elementTop) && (pageBottom > elementBottom));
        } else {
            return ((elementTop <= pageBottom) && (elementBottom >= pageTop));
        }
    }
};

var Utils = new Utils();

kullanım

var isElementInView = Utils.isElementInView($('#flyout-left-container'), false);

if (isElementInView) {
    console.log('in view');
} else {
    console.log('out of view');
}

52
Bunun yalnızca belge kaydırılan öğe ise işe yaradığını, yani kayan bir iç bölmedeki bazı öğelerin görünürlüğünü kontrol etmediğinizi unutmayın.
Andrew B.

8
biraz ofset nasıl eklenir?
Jürgen Paul

5
Sadece window.innerHeightonun yerine kullandığımda çalıştı
Christian Schnorr

2
Çünkü elemTopkullandım $(elem).position().topve elemBottomkullandım elemTop + $(elem).outerHeight(true).
Sarah Vessels

13
İçin: "Görünümdeki öğenin herhangi bir kısmı" için kullandım: (((elemTop> = docViewTop) && (elemTop <= docViewBottom)) || ((elemBottom> = docViewTop) && (elemBottom <= docViewBottom)))
Grizly

415

Vanilla'daki bu cevap :

function isScrolledIntoView(el) {
    var rect = el.getBoundingClientRect();
    var elemTop = rect.top;
    var elemBottom = rect.bottom;

    // Only completely visible elements return true:
    var isVisible = (elemTop >= 0) && (elemBottom <= window.innerHeight);
    // Partially visible elements return true:
    //isVisible = elemTop < window.innerHeight && elemBottom >= 0;
    return isVisible;
}

27
bu olmamalı isVisible = elementTop < window.innerHeight && elementBottom >= 0mı? Aksi takdirde, ekranın yarısı bir öğe false değerini döndürür.
gman

7
Hayır. bazı öğelerin sayfada tamamen görünür olup olmadığını kontrol ediyorum. bazı parçaların görünürlüğünü kontrol etmek istiyorsanız - bu snippet'i özelleştirebilirsiniz.
bravedick

15
Bu cevabı seçilen cevaptan daha iyi performans göstermek için buluyorum. Çok daha basit.
Adam Venezia

12
Onaylanan cevaba kıyasla, bu yüzlerce öğe ile çok daha iyi bir performans sergiliyor.
ncla

5
burada gösteren küçük bir keman görmek - jsfiddle.net/shaaraddalvi/4rp09jL0
upInCloud

122

Güncelleme: IntersectionObserver kullanın


Şimdiye kadar bulduğum en iyi yöntem jQuery görünür eklentisidir . Tıkır tıkır çalışıyor.

Bir öğe görünüme kaydırıldığında veya kullanıcı tarafından başka bir şekilde görünür hale geldiğinde tetiklenen özel bir "görünür" olayı taklit eder.

$('#foo').appear(function() {
  $(this).text('Hello world');
});

Bu eklenti, gizlenen veya görüntülenebilir alanın dışındaki içerik için gereksiz istekleri önlemek için kullanılabilir.


30
Bu harika bir eklenti, şüphesiz, ama soruyu cevaplamıyor.
Jon Adams

5
JQuery-görünen eklentisi ana sayfa alanındaki içerik için iyi olsa da, ne yazık ki taşma ile sabit boyutlu kaydırma div ile ilgili sorunlar var. Ciltli öğe sayfanın görüntülenebilir alanında, ancak div'ın görüntülenebilir alanının dışında olduğunda etkinlik erken tetiklenebilir ve öğe div'de görüntülendiğinde beklendiği gibi tetiklenemez.
Peter

17
Kaybolan bir eklenti var mı?
Shamoon

3
@Shamoon kaynağı kontrol edin ve appear pluginmuhtemelen !bir disappeareklenti almak için bir yere eklemeniz gerekecektir .
Şanslı Soni

5
Not olarak, bu jQuery 1.11.X ile çalışmaz github.com/morr/jquery.appear/issues/37
Jason Parham

86

İşte kaydırılabilir bir kapsayıcıya da gizlenmişse çalışan saf JavaScript çözümüm.

Burada demo yapın (pencereyi yeniden boyutlandırmayı da deneyin)

var visibleY = function(el){
  var rect = el.getBoundingClientRect(), top = rect.top, height = rect.height, 
    el = el.parentNode
  // Check if bottom of the element is off the page
  if (rect.bottom < 0) return false
  // Check its within the document viewport
  if (top > document.documentElement.clientHeight) return false
  do {
    rect = el.getBoundingClientRect()
    if (top <= rect.bottom === false) return false
    // Check if the element is out of view due to a container scrolling
    if ((top + height) <= rect.top) return false
    el = el.parentNode
  } while (el != document.body)
  return true
};

EDIT 2016-03-26: Öğeyi kaydırmayı hesaba katarak çözümü kaydırılabilir kabın üst kısmına gizlenecek şekilde güncelledim. DÜZENLE 2018-10-08: Ekranın üstünden görünüm dışına kaydırıldığında işlemek için güncellendi.


teşekkürler, belki daha iyi ol return top <= document.documentElement.clientHeight && top >= 0;
Yousef Salimpour

16
+1 Bu, öğelerin özyinelemeli özelliğini dikkate alan tek kodlu (yani üçüncü taraf değil) cevaptı. Yatay, dikey ve sayfa kaydırma işlemlerini gerçekleştirmek için genişlettim: jsfiddle.net/9nuqpgqa
Pebbl

3
Bu çözüm yalnızca öğenin üstünü kontrol eder. İlk üst piksel görünürse, öğenin geri kalanı görünmese bile true değerini döndürür. Tüm öğenin görünür olup olmadığını kontrol etmek için bottom özelliğini de kontrol etmeniz gerekir.
Wojciech Jakubas

2
Evet, temiz! Bu yanıtı yazmaya yardımcı olmak için kullanılır (js yorumu olarak kredi ile).
Roamer-1888

Eksik ; döngüde ikinci "dönüş yanlış" sonra
Mikhail Ramendik

45

IntersectionObserver API'sini kullanma (modern tarayıcılarda yerel)

Bir öğenin bir gözlemci kullanarak vizörde veya kaydırılabilir herhangi bir kapta görünür olup olmadığını belirlemek kolay ve etkilidir .

Bir scrollolay ekleme ve olay geri aramasını manuel olarak kontrol etme gereği ortadan kalkar, böylece verimlilik:

// this is the target which is observed
var target = document.querySelector('div');

// configure the intersection observer instance
var intersectionObserverOptions = {
  root: null,
  rootMargin: '150px',
  threshold: 1.0
}
    
var observer = new IntersectionObserver(onIntersection, intersectionObserverOptions);

// provide the observer with a target
observer.observe(target);

function onIntersection(entries){
  entries.forEach(entry => {
    console.clear();
    console.log(entry.intersectionRatio)
    target.classList.toggle('visible', entry.intersectionRatio > 0);
    
    // Are we in viewport?
    if (entry.intersectionRatio > 0) {
      // Stop watching 
      // observer.unobserve(entry.target);
    }
  });
}
.box{ width:100px; height:100px; background:red; margin:1000px; }
.box.visible{ background:green; }
Scroll both Vertically & Horizontally...
<div class='box'></div>


Tarayıcılar destek tablosunu görüntüle (IE / Safari'de desteklenmez)


4
Teşekkürler! Bu benim için çalışıyor ve ayrıca IE11'de github.com/w3c/IntersectionObserver
Matt Wilson ile

Şimdiye kadar en iyi çözüm. Çok dolgu olmadan IE11'de çalıştı!
Fabian von Ellerts

Bu STILL'in maalesef iOS / macOS Safari'de desteklenmediğini unutmayın. Çoklu doldurmayı seçerseniz mükemmel sorunları kontrol ettiğinizden emin olun, bu büyük bir kullanıcı grubudur
Leland

@Leland - projeye bağlı. tüm projelerim için bu mutlak bir 0 kullanıcı grubudur. Web siteleri oluşturmuyorum ama web sistemi;)
vsync

i birkaç element üzerinde bir döngüde bu çalışıyorum, ama çalışmıyor. Herhangi bir fikir? Bu döngüde hedef öğe ekliyorum.
Sascha Grindau

42

jQuery Waypoints eklentisi burada çok güzel gidiyor.

$('.entry').waypoint(function() {
   alert('You have scrolled to an entry.');
});

Eklentinin sitesinde bazı örnekler var .


3
Benim için sadece bir $('#my-div').waypoint(function() { console.log('Hello there!'); }, { offset: '100%' });
ofsetle

21

Peki ya

function isInView(elem){
   return $(elem).offset().top - $(window).scrollTop() < $(elem).height() ;
}

Bundan sonra, eleman bu şekilde görüntülendiğinde istediğiniz her şeyi tetikleyebilirsiniz

$(window).scroll(function(){
   if (isInView($('.classOfDivToCheck')))
      //fire whatever you what 
      dothis();
})

Bu benim için işe yarıyor


1
Bu benim için çalışıyor, ama görünüşe göre daha eksiksiz, fonksiyon isScrolledIntoView, stackoverflow.com/questions/487073/… :)
Meetai.com

3
Bence $ (window) .scrollTop () <$ (elem) .offset (). Top + $ (elem) .height ();
Genç

Değişikliğim şu şekilde olurdu: `return $ (window) .scrollTop () + $ (window) .height ()> $ (elem) .offset (). Top + $ (elem) .height (); `
bubencode

15

WebResourcesDepot , bir süre önce jQuery kullanan kaydırma sırasında yüklenecek bir komut dosyası yazdı . Canlı Demolarını buradan görüntüleyebilirsiniz . İşlevlerinin sığır eti şuydu:

$(window).scroll(function(){
  if  ($(window).scrollTop() == $(document).height() - $(window).height()){
    lastAddedLiveFunc();
  }
});

function lastAddedLiveFunc() { 
  $('div#lastPostsLoader').html('<img src="images/bigLoader.gif">');
  $.post("default.asp?action=getLastPosts&lastPostID="+$(".wrdLatest:last").attr("id"),
    function(data){
        if (data != "") {
          $(".wrdLatest:last").after(data);         
        }
      $('div#lastPostsLoader').empty();
    });
};

15

Tweeked Scott Dowding'in gereksinimim için harika işlevi - bu, öğenin ekrana yeni kaydırılmış olup olmadığını bulmak için kullanılır, yani üst kenardır.

function isScrolledIntoView(elem)
{
    var docViewTop = $(window).scrollTop();
    var docViewBottom = docViewTop + $(window).height();
    var elemTop = $(elem).offset().top;
    return ((elemTop <= docViewBottom) && (elemTop >= docViewTop));
}

12

elKaydırılabilir div ( holder) öğesinde ( ) öğesinin görünür olup olmadığını kontrol etmek için düz vanilya

function isElementVisible (el, holder) {
  holder = holder || document.body
  const { top, bottom, height } = el.getBoundingClientRect()
  const holderRect = holder.getBoundingClientRect()

  return top <= holderRect.top
    ? holderRect.top - top <= height
    : bottom - holderRect.bottom <= height
},

JQuery ile kullanım:

var el = $('tr:last').get(0);
var holder = $('table').get(0);
isVisible =  isScrolledIntoView(el, holder);

2
Bu Tek Sayfa Uygulamaları çağında, bir öğenin pencere dışında başka bir öğede görünür olup olmadığını kontrol etmek daha yaygın hale gelmiştir . Bu yüzden bu benim oyumu alır.
H Dog

8

isScrolledIntoView çok gerekli bir işlevdir, bu yüzden denedim, görünüm penceresinden daha yüksek olmayan öğeler için çalışır, ancak öğe görünüm penceresi olarak daha büyükse işe yaramaz. Bunu düzeltmek için durumu kolayca değiştirin

return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));

buna:

return (docViewBottom >= elemTop && docViewTop <= elemBottom);

Demoyu buradan görebilirsiniz: http://jsfiddle.net/RRSmQ/


8

Buradaki yanıtların çoğu, bir öğenin yalnızca tüm sayfanın değil, bir div'ın görünümünden kaydırıldığı için de gizlenebileceğini dikkate almaz.

Bu olasılığı karşılamak için, temel olarak öğenin ebeveynlerinin her birinin sınırları içine yerleştirilip yerleştirilmediğini kontrol etmeniz gerekir.

Bu çözüm tam olarak bunu yapar:

function(element, percentX, percentY){
    var tolerance = 0.01;   //needed because the rects returned by getBoundingClientRect provide the position up to 10 decimals
    if(percentX == null){
        percentX = 100;
    }
    if(percentY == null){
        percentY = 100;
    }

    var elementRect = element.getBoundingClientRect();
    var parentRects = [];

    while(element.parentElement != null){
        parentRects.push(element.parentElement.getBoundingClientRect());
        element = element.parentElement;
    }

    var visibleInAllParents = parentRects.every(function(parentRect){
        var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left);
        var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top);
        var visiblePercentageX = visiblePixelX / elementRect.width * 100;
        var visiblePercentageY = visiblePixelY / elementRect.height * 100;
        return visiblePercentageX + tolerance > percentX && visiblePercentageY + tolerance > percentY;
    });
    return visibleInAllParents;
};

Ayrıca, her yönde görünmesi gereken yüzdeyi belirlemenizi sağlar.
Gibi diğer faktörler nedeniyle gizlenmiş olma olasılığını kapsamaz display: hidden.

Bu, yalnızca kullandığı için tüm büyük tarayıcılarda çalışmalıdır getBoundingClientRect. Kişisel olarak Chrome ve Internet Explorer 11'de test ettim.


Bu kod için teşekkürler. Bu durumda birden fazla iç içe kaydırılabilir öğeye sahip olmanız durumunda olay dinleyiciyi nasıl kaydırma ekleyeceğinizi merak ediyorum. Dinleyiciyi pencereye tek başına eklemek yeterli değil gibi görünüyor, dinleyiciyi her kaydırılabilir kapsayıcıya eklemek için üst ebeveyne geri dönmemiz gerekiyor mu?
mr1031011

@ mr1031011 İşleyiciyi pencereye eklemek ve ardından kaydırılan kapsayıcıyı tanımlamak için hedefin kontrol edilmesi mümkün olmalıdır.
Domysee

doğru, @vanowm tarafından verilen örnekle çalışmaz,
mr1031011

7
function isScrolledIntoView(elem) {
    var docViewTop = $(window).scrollTop(),
        docViewBottom = docViewTop + $(window).height(),
        elemTop = $(elem).offset().top,
     elemBottom = elemTop + $(elem).height();
   //Is more than half of the element visible
   return ((elemTop + ((elemBottom - elemTop)/2)) >= docViewTop && ((elemTop + ((elemBottom - elemTop)/2)) <= docViewBottom));
}

7

İşte http://web-profile.com.ua/ adresinden başka bir çözüm

<script type="text/javascript">
$.fn.is_on_screen = function(){
    var win = $(window);
    var viewport = {
        top : win.scrollTop(),
        left : win.scrollLeft()
    };
    viewport.right = viewport.left + win.width();
    viewport.bottom = viewport.top + win.height();

    var bounds = this.offset();
    bounds.right = bounds.left + this.outerWidth();
    bounds.bottom = bounds.top + this.outerHeight();

    return (!(viewport.right < bounds.left || viewport.left > bounds.right ||    viewport.bottom < bounds.top || viewport.top > bounds.bottom));
 };

if( $('.target').length > 0 ) { // if target element exists in DOM
    if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
        $('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info       
    } else {
        $('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
    }
}
$(window).scroll(function(){ // bind window scroll event
if( $('.target').length > 0 ) { // if target element exists in DOM
    if( $('.target').is_on_screen() ) { // if target element is visible on screen after DOM loaded
        $('.log').html('<div class="alert alert-success">target element is visible on screen</div>'); // log info
    } else {
        $('.log').html('<div class="alert">target element is not visible on screen</div>'); // log info
    }
}
});
</script>

JSFiddle'da görün


7

Bu, öğenin sahip olduğu herhangi bir dolgu, kenarlık veya kenar boşluğunun yanı sıra görünüm penceresinin kendisinden daha büyük öğeleri de dikkate alır.

function inViewport($ele) {
    var lBound = $(window).scrollTop(),
        uBound = lBound + $(window).height(),
        top = $ele.offset().top,
        bottom = top + $ele.outerHeight(true);

    return (top > lBound && top < uBound)
        || (bottom > lBound && bottom < uBound)
        || (lBound >= top && lBound <= bottom)
        || (uBound >= top && uBound <= bottom);
}

Bunu aramak için şöyle bir şey kullanın:

var $myElement = $('#my-element'),
    canUserSeeIt = inViewport($myElement);

console.log(canUserSeeIt); // true, if element is visible; false otherwise

7

JQuery için inview adında yeni bir "inview" olayı ekleyen bir eklenti var .


Olayları kullanmayan bir jQuery eklentisi için bazı kodlar şunlardır:

$.extend($.expr[':'],{
    inView: function(a) {
        var st = (document.documentElement.scrollTop || document.body.scrollTop),
            ot = $(a).offset().top,
            wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();
        return ot > st && ($(a).height() + ot) < (st + wh);
    }
});

(function( $ ) {
    $.fn.inView = function() {
        var st = (document.documentElement.scrollTop || document.body.scrollTop),
        ot = $(this).offset().top,
        wh = (window.innerHeight && window.innerHeight < $(window).height()) ? window.innerHeight : $(window).height();

        return ot > st && ($(this).height() + ot) < (st + wh);
    };
})( jQuery );

Bunu James adlı bir adam tarafından burada bir yorumda ( http://remysharp.com/2009/01/26/element-in-view-event-plugin/ ) buldum


Ne yazık ki, jQuery inview artık korunmaz ve jQuery'nin geçerli sürümleriyle çalışmaz.
mikemaccana

1
JQuery 1 eski tarayıcı desteği içindir, yeni özellikler jQuery 2'de.
mikemaccana

Sayfa güncellendiğinden bağlantı örneği göstermiyor.
programlama profesörü

6

Kaydırılabilir DIV kabı içindeki elemanların görünürlüğünü kontrol etmem gerekiyordu

    //p = DIV container scrollable
    //e = element
    function visible_in_container(p, e) {
        var z = p.getBoundingClientRect();
        var r = e.getBoundingClientRect();

        // Check style visiblilty and off-limits
        return e.style.opacity > 0 && e.style.display !== 'none' &&
               e.style.visibility !== 'hidden' &&
               !(r.top > z.bottom || r.bottom < z.top ||
                 r.left > z.right || r.right < z.left);
    }

Ben değiştirirseniz bu benim için çalışıyor e.style.opacity > 0için (!e.style.opacity || e.style.opacity > 0)varsayılan olarak FF benim için boş bir dize çünkü.
Brett Zamir

6

Bu harika cevabı temel alarak, ES2015 + 'ı kullanarak biraz daha basitleştirebilirsiniz:

function isScrolledIntoView(el) {
  const { top, bottom } = el.getBoundingClientRect()
  return top >= 0 && bottom <= window.innerHeight
}

Üst kısmın pencereden dışarı çıkmasını ve sadece alt kısmın görüntülenmesini önemsiyorsanız, bu basitleştirilebilir

function isSeen(el) {
  return el.getBoundingClientRect().bottom <= window.innerHeight
}

hatta tek astarlı

const isSeen = el => el.getBoundingClientRect().bottom <= window.innerHeight

4

Kaydırdığınızda öğenin geçerli görünüm penceresinde olup olmadığını kontrol etmek için "onScreen" jquery eklentisini kullanabilirsiniz. Eklenti, seçici ekranda göründüğünde seçicinin ": onScreen" değerini true olarak ayarlar. Bu, projenize ekleyebileceğiniz eklentinin bağlantısıdır. " http://benpickles.github.io/onScreen/jquery.onscreen.min.js "

Benim için çalışan aşağıdaki örneği deneyebilirsiniz.

$(document).scroll(function() {
    if($("#div2").is(':onScreen')) {
        console.log("Element appeared on Screen");
        //do all your stuffs here when element is visible.
    }
    else {
        console.log("Element not on Screen");
        //do all your stuffs here when element is not visible.
    }
});

HTML Kodu:

<div id="div1" style="width: 400px; height: 1000px; padding-top: 20px; position: relative; top: 45px"></div> <br>
<hr /> <br>
<div id="div2" style="width: 400px; height: 200px"></div>

CSS:

#div1 {
    background-color: red;
}
#div2 {
    background-color: green;
}

3

Benim uygulamada böyle bir yöntem var, ama jQuery kullanmaz:

/* Get the TOP position of a given element. */
function getPositionTop(element){
    var offset = 0;
    while(element) {
        offset += element["offsetTop"];
        element = element.offsetParent;
    }
    return offset;
}

/* Is a given element is visible or not? */
function isElementVisible(eltId) {
    var elt = document.getElementById(eltId);
    if (!elt) {
        // Element not found.
        return false;
    }
    // Get the top and bottom position of the given element.
    var posTop = getPositionTop(elt);
    var posBottom = posTop + elt.offsetHeight;
    // Get the top and bottom position of the *visible* part of the window.
    var visibleTop = document.body.scrollTop;
    var visibleBottom = visibleTop + document.documentElement.offsetHeight;
    return ((posBottom >= visibleTop) && (posTop <= visibleBottom));
}

Düzenleme: Bu yöntem IE için iyi çalışır (en az sürüm 6). FF ile uyumluluk için yorumları okuyun.


2
Herhangi bir nedenle document.body.scrollTop her zaman 0 değerini döndürür (ff3'te). Bunu visibleTop = (document.documentElement.scrollTop? Document.documentElement.scrollTop: document.body.scrollTop) olarak değiştirin;
09:40

Bunun için özür dilerim. Uygulamam sadece IE 6'da çalışmalıdır (evet, şanslı değilim :(), bu yüzden bunu FF'de hiç test
etmedim

Doğru olsaydı buradaki en iyi cevap olurdu. Satırlarınızdan birini şu şekilde düzeltin: var visibleBottom = visibleTop + window.innerHeight;jQuery kullanmıyorum ve doğru cevabı bulmama yardımcı oldunuz.
Bitterblue

3

Başka bir div içindeki öğeyi kaydırmak için bunu değiştirmek isterseniz,

function isScrolledIntoView (elem, divID) 

{

    var docViewTop = $('#' + divID).scrollTop();


    var docViewBottom = docViewTop + $('#' + divID).height();

    var elemTop = $(elem).offset().top;
    var elemBottom = elemTop + $(elem).height();

    return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop)); 
}

3

Kabul edilen yanıtı, öğenin display özelliğinin görünür nitelikte "none" dışında bir değere ayarlanmış olması için değiştirildi.

function isScrolledIntoView(elem) {
   var docViewTop = $(window).scrollTop();
  var docViewBottom = docViewTop + $(window).height();

  var elemTop = $(elem).offset().top;
  var elemBottom = elemTop + $(elem).height();
  var elemDisplayNotNone = $(elem).css("display") !== "none";

  return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop) && elemDisplayNotNone);
}

3

İşte aynı şeyi yatay, dikey veya her ikisinde de Mootools kullanarak elde etmenin bir yolu.

Element.implement({
inVerticalView: function (full) {
    if (typeOf(full) === "null") {
        full = true;
    }

    if (this.getStyle('display') === 'none') {
        return false;
    }

    // Window Size and Scroll
    var windowScroll = window.getScroll();
    var windowSize = window.getSize();
    // Element Size and Scroll
    var elementPosition = this.getPosition();
    var elementSize = this.getSize();

    // Calculation Variables
    var docViewTop = windowScroll.y;
    var docViewBottom = docViewTop + windowSize.y;
    var elemTop = elementPosition.y;
    var elemBottom = elemTop + elementSize.y;

    if (full) {
        return ((elemBottom >= docViewTop) && (elemTop <= docViewBottom)
            && (elemBottom <= docViewBottom) && (elemTop >= docViewTop) );
    } else {
        return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop));
    }
},
inHorizontalView: function(full) {
    if (typeOf(full) === "null") {
        full = true;
    }

    if (this.getStyle('display') === 'none') {
        return false;
    }

    // Window Size and Scroll
    var windowScroll = window.getScroll();
    var windowSize = window.getSize();
    // Element Size and Scroll
    var elementPosition = this.getPosition();
    var elementSize = this.getSize();

    // Calculation Variables
    var docViewLeft = windowScroll.x;
    var docViewRight = docViewLeft + windowSize.x;
    var elemLeft = elementPosition.x;
    var elemRight = elemLeft + elementSize.x;

    if (full) {
        return ((elemRight >= docViewLeft) && (elemLeft <= docViewRight)
            && (elemRight <= docViewRight) && (elemLeft >= docViewLeft) );
    } else {
        return ((elemRight <= docViewRight) && (elemLeft >= docViewLeft));
    }
},
inView: function(full) {
    return this.inHorizontalView(full) && this.inVerticalView(full);
}});

3

Bir öğenin% 75 görünür olup olmadığını kontrol etmek için bu cevabı temel alan bir örnek (yani% 25'inden daha azı ekran dışında).

function isScrolledIntoView(el) {
  // check for 75% visible
  var percentVisible = 0.75;
  var elemTop = el.getBoundingClientRect().top;
  var elemBottom = el.getBoundingClientRect().bottom;
  var elemHeight = el.getBoundingClientRect().height;
  var overhang = elemHeight * (1 - percentVisible);

  var isVisible = (elemTop >= -overhang) && (elemBottom <= window.innerHeight + overhang);
  return isVisible;
}

3

Bu soruya 30'dan fazla cevap var ve hiçbiri kullandığım inanılmaz basit, saf JS çözümünü kullanmıyor. Diğerleri ittiği gibi, sadece bunu çözmek için jQuery yüklemeye gerek yoktur.

Elemanın görünüm portu içinde olup olmadığını söylemek için önce elemanların gövde içindeki pozisyonunu belirlemeliyiz. Bir zamanlar düşündüğüm gibi bunu tekrar tekrar yapmamız gerekmiyor. Bunun yerine kullanabiliriz element.getBoundingClientRect().

pos = elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top;

Bu değer, nesnenin üstü ile gövdenin üstü arasındaki Y farkıdır.

Ardından, öğenin görünümde olup olmadığını söylemeliyiz. Çoğu uygulama, tam öğenin görünüm alanında olup olmadığını sorar, bu yüzden bu konuya değineceğiz.

Her şeyden önce, pencerenin üst konumudur: window.scrollY.

Pencerenin yüksekliğini en üst konumuna ekleyerek pencerenin alt konumunu elde edebiliriz:

var window_bottom_position = window.scrollY + window.innerHeight;

Öğenin en üst konumunu elde etmek için basit bir işlev oluşturalım:

function getElementWindowTop(elem){
    return elem && typeof elem.getBoundingClientRect === 'function' ? elem.getBoundingClientRect().top - document.body.getBoundingClientRect().top : 0;
}

Bu işlev, öğenin pencere içindeki en üst konumunu döndürür veya 0öğeyi.getBoundingClientRect() yöntemle . Bu yöntem uzun zamandır var, bu yüzden tarayıcınızın desteklememesi konusunda endişelenmenize gerek yok.

Şimdi, elementimizin en üst pozisyonu:

var element_top_position = getElementWindowTop(element);

Ve veya elemanın alt konumu:

var element_bottom_position = element_top_position + element.clientHeight;

Şimdi, öğenin alt konumunun görünüm alanının üst konumundan daha düşük olup olmadığını ve öğenin üst konumunun görünüm alanının alt konumundan daha yüksek olup olmadığını kontrol ederek öğenin görünüm alanında olup olmadığını belirleyebiliriz:

if(element_bottom_position >= window.scrollY 
&& element_top_position <= window_bottom_position){
    //element is in view
else
    //element is not in view

Oradan, öğenize bir in-viewsınıf eklemek veya kaldırmak için mantığı gerçekleştirebilir ve daha sonra CSS'nizdeki geçiş efektleriyle daha sonra işleyebilirsiniz.

Bu çözümü başka hiçbir yerde bulamadığım için kesinlikle şaşırdım, ancak bunun en temiz ve en etkili çözüm olduğuna inanıyorum ve jQuery yüklemenizi gerektirmiyor!


Çok güzel bir açıklama! Ancak,
Ally'in

1
@Domysee Hmm, bir şekilde bunu atladım. Yeterince adil. Buna dikkat çektiğin için teşekkürler. Bunun başka bir yolla yapıldığını görmek güzel.
WebWanderer

3

Bu cevabın daha verimli bir versiyonu :

 /**
 * Is element within visible region of a scrollable container
 * @param {HTMLElement} el - element to test
 * @returns {boolean} true if within visible region, otherwise false
 */
 function isScrolledIntoView(el) {
      var rect = el.getBoundingClientRect();
      return (rect.top >= 0) && (rect.bottom <= window.innerHeight);
 }

2

Öğenin herhangi bir kısmı sayfada görünürse bu yöntem true değerini döndürür. Benim durumumda daha iyi çalıştı ve başka birine yardımcı olabilir.

function isOnScreen(element) {
  var elementOffsetTop = element.offset().top;
  var elementHeight = element.height();

  var screenScrollTop = $(window).scrollTop();
  var screenHeight = $(window).height();

  var scrollIsAboveElement = elementOffsetTop + elementHeight - screenScrollTop >= 0;
  var elementIsVisibleOnScreen = screenScrollTop + screenHeight - elementOffsetTop >= 0;

  return scrollIsAboveElement && elementIsVisibleOnScreen;
}

2

Kaydırılabilir div (konteyner) için basit değişiklik

var isScrolledIntoView = function(elem, container) {
    var containerHeight = $(container).height();
    var elemTop = $(elem).position().top;
    var elemBottom = elemTop + $(elem).height();
    return (elemBottom > 0 && elemTop < containerHeight);
}

NOT: eleman kaydırılabilir div'den büyükse bu çalışmaz.


2

Kullanmaktan çekinmeyin (MIT lisansı) bu kısa jQuery işlev uzantısını uyarladım.

/**
 * returns true if an element is visible, with decent performance
 * @param [scope] scope of the render-window instance; default: window
 * @returns {boolean}
 */
jQuery.fn.isOnScreen = function(scope){
    var element = this;
    if(!element){
        return;
    }
    var target = $(element);
    if(target.is(':visible') == false){
        return false;
    }
    scope = $(scope || window);
    var top = scope.scrollTop();
    var bot = top + scope.height();
    var elTop = target.offset().top;
    var elBot = elTop + target.height();

    return ((elBot <= bot) && (elTop >= top));
};

2

Görev için, çok sayıda öğeyi son derece hızlı işlemek için tasarlanmış bir bileşen yazdım ( yavaş bir mobil cihazda 1000 öğe için <10ms ayarına kadar) ).

Pencere, HTML öğeleri, gömülü iframe, spawned child window - erişim sağladığınız her türlü kaydırma konteyneri ile çalışır ve algıladığı şeyde çok esnektir ( tam veya kısmi görünürlük , sınır kutusu veya içerik kutusu , özel tolerans bölgesi , vb. ).

Büyük, çoğunlukla otomatik olarak oluşturulan bir test paketi, reklamı yapılan, çapraz tarayıcı olarak çalışmasını sağlar .

İsterseniz bir şans verin: jQuery.isInView . Aksi takdirde, kaynak kodda ilham bulabilirsiniz, örneğin burada .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.