获取屏幕上最明显的元素

我想获得屏幕上最明显的一个元素(占用最多的空间)。 我在下面添加了一个示例图片,以便更多地了解我的问题。

例

两个黑色边框是屏幕的两侧。 如您所见,绿色框(div2)是屏幕上最明显的 – 我想知道如何获得该元素。 最明显的元素不应该是完全可见的。

我做了一个快速(它不是那么快)的搜索,但无济于事,如果我错过了 – 我的道歉。

TLDR:

受到这个问题的启发以及我自己项目中类似function的必要性,我根据下面的代码编写了一个模块/ jQuery插件 。 如果您对“如何”不感兴趣,只需下载或安装您喜欢的包管理器即可。

原答案:

exabyssus提供的答案在大多数情况下都很有效,除非元素的顶部或底部都不可见,例如当元素高度大于窗口高度时。

这是一个更新版本,它考虑了这个场景并使用了直接支持IE8的 getBoundingClientRect

 // 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 } 
  

是的,这个问题太宽泛了。 但我有兴趣解决它。 这是如何实现它的粗略示例。

我试着通过评论来解释发生了什么。 它肯定可以做得更好,但我希望它有所帮助。

 // 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/

可以使用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; } 
  
  
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]);