Получить элемент, который является наиболее видимым на экране

Я хотел бы получить один элемент, который является наиболее видимым на экране (занимает больше всего места). Я добавил пример изображения ниже, чтобы понять мой вопрос немного больше.

Две черные границы являются сторонами экрана. Как видите, зеленое поле (div2) наиболее заметно на экране - я хотел бы знать, как я могу получить этот элемент. Наиболее видимый элемент не должен быть полностью видимым.

Я сделал быстрый (это был НЕ ТАК быстрый) поиск, но безрезультатно, если я пропустил это - мои извинения.

 Rachel Gallen13 июл. 2016 г., 22:30
 showdev13 июл. 2016 г., 23:14
Вы можете найтиjQuery.fracs полезно.
 Yates13 июл. 2016 г., 22:29
@VanyaAvchyan Я не совсем уверен, что вы имеете в виду. Забота, предоставляющая больше информации шаг за шагом?
 Yates13 июл. 2016 г., 22:32
@RachelGallen Код, указанный в ссылке, - это способ получить самый высокий элемент в div. Проблема в том, что у меня мог быть огромный div, который не виден на экране, поэтому он не самый видимый.
 Yates13 июл. 2016 г., 22:29
@charlietfl У меня нет кода, потому что я не могу придумать способ получить желаемый результат. Есть много вопросов от многих людей, которые не предоставили код, потому что они не знают возможного способа решить свою проблему или приблизиться к нему, и эти вопросы все еще существуют.
 Yates13 июл. 2016 г., 23:26
@showdev это может быть более практичным использованием того, чего я в конечном итоге хочу достичь. Я пометил ответ exabyssus как правильный, так как он полностью отвечает на мой вопрос, но я сразу же погрузлюсь в кодекс фракций! Спасибо.
 CrazyPaste13 июл. 2016 г., 22:36
Мне интересно посмотреть, какой ответ ты получишь. Я тоже не уверен, как это сделать. Тем, кто хочет, чтобы этот вопрос был закрыт: я не понимаю, «вам нужен код, чтобы отправить вопрос в SO». Широкий вопрос, может быть, просто нужен широкий ответ?
 bhspencer13 июл. 2016 г., 22:27
Вы пробовали что-нибудь? опубликовать свой код ТАК не сервис написания кода.
 Yates13 июл. 2016 г., 22:30
@bhspencer Действительно, ТАК не так. Но ничто не сдерживает никого, предоставляя пошаговую основу для решения проблемы. Я полностью способен писать код, но я не знаю, с чего начать. В моем посте также говорится, что я хочу знать, как, я никогда не просил преднамеренно полный набор кода.
 charlietfl13 июл. 2016 г., 22:17
Это не тривиально и без вашего кода делает этот вопрос слишком широким. Этот сайт работает благодаря тому, что вы предоставляете некоторый код, который не выполняет то, что ожидается, а другие помогают исправить этот код .... не писать код с нуля или предоставить учебник о том, что делать
 charlietfl13 июл. 2016 г., 22:35
@ThomasYates начинают с выяснения того, как получить положение области просмотра относительно документа вместе с его размерами, которые являются размером окна. затем вам нужно перебрать dom и начать сравнение на основе смещения, высоты и ширины элемента, чтобы определить видимую область
 Vanya Avchyan13 июл. 2016 г., 22:17
Вы можете получить их высоту клиента, вычтя их разницу и сделать снимок, высота которого больше
 Rachel Gallen13 июл. 2016 г., 22:35
@ThomasYates код перебирает все элементы и может быть легко адаптирован для ваших целей. Как уже говорилось, SO - это руководство, а не услуга. Вы должны начать учиться когда-нибудь!

Ответы на вопрос(4)

<style>
    .block{
        padding: 20px;
        border:2px solid #000;
        height: 200px;
        overflow:hidden;
    }
    .green{
        border: 1px solid green;
        height: 150px;
        margin:20px 0px;
    }
    .red{
        border: 1px solid red;
        height: 100px;
    }
</style>
<div class="block">
    <div class="example green"></div>
    <div class="example red"></div>
</div>


var divs = $('.example');
var obj = {};
var heights = [];

$.each(divs,function (key, val)
{
    heights.push($(val).outerHeight());
    obj[$(val).outerHeight()] = $(val);
});
var max = Math.max.apply(null, heights);

console.log(obj[max]);
 Philipp22 апр. 2017 г., 22:08
Некоторое описание или объяснение было бы полезно ...
Решение Вопроса
TLDR:

сти в моих собственных проектах, я написалмодуль / плагин jQuery на основе кода ниже. Если вас не интересует «как», просто скачайте его или установите с вашим любимым менеджером пакетов.

Оригинальный ответ:

ответ предоставлен exabyssus работает хорошо в большинстве случаев, за исключением случаев, когда ни верх, ни низ элемента не видны, например, когда высота элемента больше, чем высота окна.

Вот обновленная версия, которая учитывает этот сценарий и используетgetBoundingClientRect которыйподдерживается вплоть до IE8:

// Usage: var $element = getMostVisible( $( '.elements' ) );
function getMostVisible( $elements ) {
    var $element = $(),
        viewportHeight = $( window ).height(),
        max = 0;

    $elements.each( function() {
        var visiblePx = getVisibleHeightPx( $( this ), viewportHeight );

        if ( visiblePx > max ) {
            max = visiblePx;
            $element = $( this );
        }
    } );

    return $element;
}

function getVisibleHeightPx( $element, viewportHeight ) {
    var rect = $element.get( 0 ).getBoundingClientRect(),
        height = rect.bottom - rect.top,
        visible = {
            top: rect.top >= 0 && rect.top < viewportHeight,
            bottom: rect.bottom > 0 && rect.bottom < viewportHeight
        },
        visiblePx = 0;

    if ( visible.top && visible.bottom ) {
        // Whole element is visible
        visiblePx = height;
    } else if ( visible.top ) {
        visiblePx = viewportHeight - rect.top;
    } else if ( visible.bottom ) {
        visiblePx = rect.bottom;
    } else if ( height > viewportHeight && rect.top < 0 ) {
        var absTop = Math.abs( rect.top );

        if ( absTop < height ) {
            // Part of the element is visible
            visiblePx = height - absTop;
        }
    }

    return visiblePx;
}

Это возвращает наиболее видимый элемент на основе пикселей, а не в процентах от высоты элемента, что было идеально для моего варианта использования. Это может быть легко изменено, чтобы вернуть процент при желании.

Вы также можете использовать это как плагин jQuery, чтобы вы могли получить наиболее видимый элемент с$('.elements').mostVisible() вместо передачи элементов в функцию. Для этого вам просто нужно включить это с двумя функциями выше:

$.fn.mostVisible = function() {
    return getMostVisible( this );
};

Имея это в виду, вы можете связывать вызовы вашего метода вместо того, чтобы сохранять элемент в переменную:

$( '.elements' ).mostVisible().addClass( 'most-visible' ).html( 'I am most visible!' );

Вот все это, завернутый в небольшую демонстрацию, которую вы можете попробовать прямо здесь, на SO:

(function($) {
  'use strict';

  $(function() {
    $(window).on('scroll', function() {
      $('.the-divs div').html('').removeClass('most-visible').mostVisible().addClass('most-visible').html('I am most visible!');
    });
  });

  function getMostVisible($elements) {
    var $element = $(),
      viewportHeight = $(window).height(),
      max = 0;

    $elements.each(function() {
      var visiblePx = getVisibleHeightPx($(this), viewportHeight);

      if (visiblePx > max) {
        max = visiblePx;
        $element = $(this);
      }
    });

    return $element;
  }

  function getVisibleHeightPx($element, viewportHeight) {
    var rect = $element.get(0).getBoundingClientRect(),
      height = rect.bottom - rect.top,
      visible = {
        top: rect.top >= 0 && rect.top < viewportHeight,
        bottom: rect.bottom > 0 && rect.bottom < viewportHeight
      },
      visiblePx = 0;

    if (visible.top && visible.bottom) {
      // Whole element is visible
      visiblePx = height;
    } else if (visible.top) {
      visiblePx = viewportHeight - rect.top;
    } else if (visible.bottom) {
      visiblePx = rect.bottom;
    } else if (height > viewportHeight && rect.top < 0) {
      var absTop = Math.abs(rect.top);

      if (absTop < height) {
        // Part of the element is visible
        visiblePx = height - absTop;
      }
    }

    return visiblePx;
  }

  $.fn.mostVisible = function() {
    return getMostVisible(this);
  }

})(jQuery);
.top {
  height: 900px;
  background-color: #999
}
.middle {
  height: 200px;
  background-color: #eee
}
.bottom {
  height: 600px;
  background-color: #666
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="the-divs">
  <div class="top"></div>
  <div class="middle"></div>
  <div class="bottom"></div>
</div>

getBoundingClientRect ()

добавлен плагин jQuery

Перебирайте выбранные элементы и проверяйте

элемент находится в области просмотра?Какова видимая высота элемента?элемент самый видимый?

function getMostVisibleElement(selector) {
    var clientRect = null;
    var clientRectTop = 0;
    var maxVisibleHeight = 0;
    var visibleHeightOfElem = 0;
    var mostVisibleElement = null;
    var skipRest = false;

    var visibleElems = $(selector).each(function(i, element) {
        if (skipRest === false) {
            clientRect = element.getBoundingClientRect();
            clientRectTop = Math.abs(clientRect.top);

            if (clientRect.top >= 0) {
                visibleHeightOfElem = window.innerHeight - clientRectTop;
            } else {
                visibleHeightOfElem = clientRect.height - clientRectTop;
            }

            if (visibleHeightOfElem >= clientRect.height) {
                mostVisibleElement = element;
                skipRest = true;
            } else {

                if (visibleHeightOfElem > maxVisibleHeight) {
                    maxVisibleHeight = visibleHeightOfElem;
                    mostVisibleElement = element;
                }
            }

        }
    });
    return mostVisibleElement;
}

$(window).on('click', function() {
    var mostVisible = getMostVisibleElement('.my-container');
    $(mostVisible).addClass('highlighted');
    
    setTimeout(function() {
      $(mostVisible).removeClass('highlighted');
    }, 200);
    // alert(mostVisible.id)
});
.my-container {
  height: 100vh;
}

#a {
  background: #007bff;
}

#b {
  background: #28a745;
  height: 70vh;
}

#c {
  background: #ffc107;
}

#d {
  background: #17a2b8;
}

.highlighted ,{
  background: #dc3545 !important; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="my-container" id="a"></div>
<div class="my-container" id="b"></div>
<div class="my-container" id="c"></div>
<div class="my-container" id="d"></div>

этот вопрос слишком широк. Но я был заинтересован в решении этого. Вот грубый пример того, как этого добиться.

Я пытался объяснить, что происходит с комментариями. Конечно, это можно сделать лучше, но я надеюсь, что это поможет.

// init on page ready
$(function() {
    // check on each scroll event
    $(window).scroll(function(){
        // elements to be tested
        var _elements = $('.ele');

        // get most visible element (result)
        var ele = findMostVisible(_elements);
    });
});


function findMostVisible(_elements) {

    // find window top and bottom position.
    var wtop = $(window).scrollTop();
    var wbottom = wtop + $(window).height();


    var max = 0; // use to store value for testing
    var maxEle = false; // use to store most visible element

    // find percentage visible of each element
    _elements.each(function(){

        // get top and bottom position of the current element
        var top = $(this).offset().top;
        var bottom = top + $(this).height();

        // get percentage of the current element
        var cur = eleVisible(top, bottom, wtop, wbottom);

        // if current element is more visible than previous, change maxEle and test value, max 
        if(cur > max) {
            max = cur;
            maxEle = $(this);
        }
    });

    return maxEle;
}

// find visible percentage
function eleVisible(top, bottom, wtop, wbottom) {

    var wheight = wbottom - wtop;

    // both bottom and top is vissible, so 100%
    if(top > wtop && top < wbottom && bottom > wtop && bottom < wbottom)
    {
        return 100;
    }

    // only top is visible
    if(top > wtop && top < wbottom)
    {
        return  100 + (wtop - top) / wheight * 100;
    }

    // only bottom is visible
    if(bottom > wtop && bottom < wbottom)
    {
        return  100 + (bottom - wbottom) / wheight * 100;
    }

    // element is not visible
    return 0;
}

Рабочий пример -https://jsfiddle.net/exabyssus/6o30sL24/

 Yates13 июл. 2016 г., 23:25
Это идеально и абсолютно то, что я собирался. Большое спасибо!
 exabyssus13 июл. 2016 г., 23:12
@bhspencer - ошибка, maxEle - false, если элементы не видны иэлемент Если там есть
 exabyssus13 июл. 2016 г., 23:35
@ThomasYates Добро пожаловать! Удачи!
 Andy19 сент. 2016 г., 16:44
Я знаю, что этот ответ старый, но для любого, кто наткнулся на него из Google, как я:eleVisible функция некорректно возвращает0 для любых элементов, где не видны ни верх, ни низ (т.е. элементы, высота которых превышает высоту окна)
 bhspencer13 июл. 2016 г., 23:07
Иногда maxEle - это логическое значение, а иногда - элемент. Это то, что вы хотели?
 Yates13 июл. 2016 г., 23:11
Позвольте мне начать с того, что я люблю тебя - ты был так добр, и я никогда не ожидал, что кто-нибудь полностью напишет ЛЮБОЙ код. Но я получаю то же, что упомянуто выше. Я использую это в разделах и всякий раз, когда два видны на экране, он возвращает оба, но не более двух.
 exabyssus13 июл. 2016 г., 23:20
Я добавил рабочий пример, надеюсь, это поможет.jsfiddle.net/exabyssus/6o30sL24

Ваш ответ на вопрос