Проверьте, отображается ли элемент на экране

Возможный дубликат:
jQuery - проверьте, видим ли элемент после прокрутки

Я пытаюсь определить, является ли элемент видимым на экране. Для этого я пытаюсь найти вертикальное положение элемента с помощью offsetTop, но возвращаемое значение неверно. В этом случае элемент не отображается, если вы не прокрутите вниз. Но несмотря на это, offsetTop возвращает значение 618, когда высота экрана равна 703, поэтому согласно offsetTop элемент должен быть видимым.

Используемый мной код выглядит следующим образом:

function posY(obj)
{
  var curtop = 0;

  if( obj.offsetParent )
  {
    while(1)
    {
      curtop += obj.offsetTop;

      if( !obj.offsetParent )
      {
        break;
      }

      obj = obj.offsetParent;
    }
  } else if( obj.y )
    {
     curtop += obj.y;
    }

  return curtop;
}

Заранее благодарю вас!

Ответы

Ответ 1

Хорошо, что BenM сказал, вам нужно определить высоту области просмотра + положение прокрутки, чтобы соответствовать вашему верхнему поситону. Функция, используемая вами, подходит и выполняет эту работу, хотя ее задача более сложна, чем ей нужно.

Если вы не используете jQuery, тогда script будет примерно таким:

function posY(elm) {
    var test = elm, top = 0;

    while(!!test && test.tagName.toLowerCase() !== "body") {
        top += test.offsetTop;
        test = test.offsetParent;
    }

    return top;
}

function viewPortHeight() {
    var de = document.documentElement;

    if(!!window.innerWidth)
    { return window.innerHeight; }
    else if( de && !isNaN(de.clientHeight) )
    { return de.clientHeight; }

    return 0;
}

function scrollY() {
    if( window.pageYOffset ) { return window.pageYOffset; }
    return Math.max(document.documentElement.scrollTop, document.body.scrollTop);
}

function checkvisible( elm ) {
    var vpH = viewPortHeight(), // Viewport Height
        st = scrollY(), // Scroll Top
        y = posY(elm);

    return (y > (vpH + st));
}

Использование jQuery намного проще:

function checkVisible( elm, evalType ) {
    evalType = evalType || "visible";

    var vpH = $(window).height(), // Viewport Height
        st = $(window).scrollTop(), // Scroll Top
        y = $(elm).offset().top,
        elementHeight = $(elm).height();

    if (evalType === "visible") return ((y < (vpH + st)) && (y > (st - elementHeight)));
    if (evalType === "above") return ((y < (vpH + st)));
}

Это даже дает второй параметр. С "видимым" (или без второго параметра) он строго проверяет, находится ли элемент на экране. Если он установлен на "выше", он вернет true, когда элемент находится на экране или над экраном.

Смотрите в действии: http://jsfiddle.net/RJX5N/2/

Надеюсь, это ответит на ваш вопрос.

- УЛУЧШЕННАЯ ВЕРСИЯ -

Это намного короче, и он должен это сделать:

function checkVisible(elm) {
  var rect = elm.getBoundingClientRect();
  var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
  return !(rect.bottom < 0 || rect.top - viewHeight >= 0);
}

со скрипкой, чтобы доказать это: http://jsfiddle.net/t2L274ty/1/

И версия с threshold и mode включала:

function checkVisible(elm, threshold, mode) {
  threshold = threshold || 0;
  mode = mode || 'visible';

  var rect = elm.getBoundingClientRect();
  var viewHeight = Math.max(document.documentElement.clientHeight, window.innerHeight);
  var above = rect.bottom - threshold < 0;
  var below = rect.top - viewHeight + threshold >= 0;

  return mode === 'above' ? above : (mode === 'below' ? below : !above && !below);
}

и со скрипкой, чтобы это доказать: http://jsfiddle.net/t2L274ty/2/

Ответ 2

Не могли бы вы использовать jQuery, так как он совместим с кросс-браузером?

function isOnScreen(element)
{
    var curPos = element.offset();
    var curTop = curPos.top;
    var screenHeight = $(window).height();
    return (curTop > screenHeight) ? false : true;
}

И затем вызовите функцию, используя что-то вроде:

if(isOnScreen($('#myDivId'))) { /* Code here... */ };

Ответ 3

Вы хотите использовать scrollTop, чтобы затем сравнить верхнюю позицию элементов с страницами.