2013-04-30 2 views
8

Мне нужно найти хорошее решение для следующей проблемы. Я вижу, что многие люди спрашивают о отслеживании, находится ли элемент в или за пределами порта «Порт» для окна страницы или браузера. Мне нужно реплицировать это действие, но внутри DIV, который прокручивается, с переполнением: например, прокрутка. Кто-нибудь знает хороший пример для этого конкретного действия?Обнаружить, когда элементы в прокручиваемом div находятся вне поля зрения

Заранее спасибо.

ответ

18

У меня была такая же проблема и раньше, у меня закончилась следующая функция. Первый параметр предназначен для проверки элемента, второй - для проверки того, частично ли элемент просматривается. Он предназначен только для вертикальной проверки , вы можете расширить его, чтобы проверить горизонтальную прокрутку.

function checkInView(elem,partial) 
{ 
    var container = $(".scrollable"); 
    var contHeight = container.height(); 
    var contTop = container.scrollTop(); 
    var contBottom = contTop + contHeight ; 

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

    var isTotal = (elemTop >= 0 && elemBottom <=contHeight); 
    var isPart = ((elemTop < 0 && elemBottom > 0) || (elemTop > 0 && elemTop <= container.height())) && partial ; 

    return isTotal || isPart ; 
} 

проверить его на jsFiddle.

+1

Спасибо. Я видел разные решения для этого, и это самый ясный, самый чистый способ сделать это. Благодаря! – Ronny

+0

приятно слышать, что я сделаю для него простой плагин jquery :) –

+0

Я просто делал то же самое. lol – Ronny

0

Я сделал JQuery плагин с последним ответом:

(function($) { 
    $.fn.reallyVisible = function(opt) { 

     var options = $.extend({ 
      cssChanges:[ 
       { name : 'visibility', states : ['hidden','visible'] } 
      ], 
      childrenClass:'mentioners2', 
      partialview : true 
     }, opt); 

     var container = $(this); 
     var contHeight; 
     var contTop; 
     var contBottom; 
     var _this = this; 
     var _children; 

     this.checkInView = function(elem,partial){ 

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

      var isTotal = (elemTop >= 0 && elemBottom <=contHeight); 
      var isPart = ((elemTop < 0 && elemBottom > 0) || (elemTop > 0 && elemTop <= container.height())) && partial ; 

      return isTotal || isPart ; 
     } 

     this.bind('restoreProperties',function(){ 
      $.each(_children,function(i,elem){ 
       $.each(options.cssChanges,function(i,_property){ 
        $(elem).css(_property.name,_property.states[1]);   
       }); 
      }); 
      _children = null; 
     }); 

     return this.each(function(){ 
      contHeight = container.height(); 
      contTop = container.scrollTop(); 
      contBottom = contTop + contHeight ; 

      _children = container.children("."+options.childrenClass); 

      $.each(_children,function(i,elem){ 
       var res = _this.checkInView(elem,options.partialview); 
       if( !res){ 
        $.each(options.cssChanges,function(i,_property){ 
         $(elem).css(_property.name,_property.states[0]);   
        }); 
       } 
      }); 

     }); 
    } 

})(jQuery); 
4

Вот чистый Javascript версия принятого ответа, не полагаясь на JQuery и с некоторыми исправлениями к частичному в выявлении и поддержке зрения для отказа зрения наверху.

function checkInView(container, element, partial) { 

    //Get container properties 
    let cTop = container.scrollTop; 
    let cBottom = cTop + container.clientHeight; 

    //Get element properties 
    let eTop = element.offsetTop; 
    let eBottom = eTop + element.clientHeight; 

    //Check if in view  
    let isTotal = (eTop >= cTop && eBottom <= cBottom); 
    let isPartial = partial && (
     (eTop < cTop && eBottom > cTop) || 
     (eBottom > cBottom && eTop < cBottom) 
    ); 

    //Return outcome 
    return (isTotal || isPartial); 
} 

И в качестве бонуса, эта функция обеспечивает элемент в поле зрения, если это не (частичное или полное):

function ensureInView(container, element) { 

    //Determine container top and bottom 
    let cTop = container.scrollTop; 
    let cBottom = cTop + container.clientHeight; 

    //Determine element top and bottom 
    let eTop = element.offsetTop; 
    let eBottom = eTop + element.clientHeight; 

    //Check if out of view 
    if (eTop < cTop) { 
     container.scrollTop -= (cTop - eTop); 
    } 
    else if (eBottom > cBottom) { 
     container.scrollTop += (eBottom - cBottom); 
    } 
} 
+0

В вашей функции enableInView следует добавить offsetTop '' 'let cTop = container.scrollTop + container.offsetTop''' –

+0

Это не работает для меня, это фактически нарушает функцию в моем случае использования. –

0

Вот чистый Javascript решение.

function elementIsVisible(element, container, partial) { 
    var contHeight = container.offsetHeight, 
    elemTop = offset(element).top - offset(container).top, 
    elemBottom = elemTop + element.offsetHeight; 
    return (elemTop >= 0 && elemBottom <= contHeight) || 
    (partial && ((elemTop < 0 && elemBottom > 0) || (elemTop > 0 && elemTop <= contHeight))) 
} 

// checks window 
function isWindow(obj) { 
    return obj != null && obj === obj.window; 
} 

// returns corresponding window 
function getWindow(elem) { 
    return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView; 
} 

// taken from jquery 
// @returns {{top: number, left: number}} 
function offset(elem) { 

    var docElem, win, 
     box = { top: 0, left: 0 }, 
     doc = elem && elem.ownerDocument; 

    docElem = doc.documentElement; 

    if (typeof elem.getBoundingClientRect !== typeof undefined) { 
     box = elem.getBoundingClientRect(); 
    } 
    win = getWindow(doc); 
    return { 
     top: box.top + win.pageYOffset - docElem.clientTop, 
     left: box.left + win.pageXOffset - docElem.clientLeft 
    }; 
}; 
1

На основании наилучшего ответа. Вместо того, чтобы просто сказать вам, если элемент частично видимый или нет. Я добавил немного дополнительного, чтобы вы могли передать процент (0-100), который говорит вам, является ли элемент более чем на% видимым.

function (container, element, partial) { 
    var cTop = container.scrollTop; 
    var cBottom = cTop + container.clientHeight; 
    var eTop = element.offsetTop; 
    var eBottom = eTop + element.clientHeight; 
    var isTotal = (eTop >= cTop && eBottom <= cBottom); 
    var isPartial; 

    if (partial === true) { 
     isPartial = (eTop < cTop && eBottom > cTop) || (eBottom > cBottom && eTop < cBottom); 
    } else if(typeof partial === "number"){ 
     if (eTop < cTop && eBottom > cTop) { 
      isPartial = ((eBottom - cTop) * 100)/element.clientHeight > partial; 
     } else if (eBottom > cBottom && eTop < cBottom){ 
      isPartial = ((cBottom - eTop) * 100)/element.clientHeight > partial; 
     } 
    } 
    return (isTotal || isPartial); 
} 
+0

Это также jQuery-free. – Rolf

+1

Да, мне нравится избегать jQuery –

Смежные вопросы