我想获得屏幕上最明显的一个元素(占用最多的空间)。我在下面添加了一个示例图片,以便更多地了解我的问题。
两个黑色边框是屏幕的两侧。如您所见,绿色框(div2)在屏幕上最明显 - 我想知道如何获得该元素。最明显的元素不应该完全可见。
我做了一个快速(它不是那么快)的搜索,但无济于事,如果我错过了 - 我的道歉。
答案 0 :(得分:8)
受到这个问题的启发以及我自己项目中类似功能的必要性,我根据下面的代码撰写了module/jQuery plugin。如果您对' how'不感兴趣,只需下载或安装您最喜爱的软件包管理器即可。
answer provided by exabyssus在大多数情况下效果很好,除非元素的顶部或底部都不可见,例如当元素高度大于窗口高度时。
此处有一个更新版本,该版本会考虑该方案并使用getBoundingClientRect
supported right the way down to 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);
&#13;
.top {
height: 900px;
background-color: #999
}
.middle {
height: 200px;
background-color: #eee
}
.bottom {
height: 600px;
background-color: #666
}
&#13;
<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>
&#13;
答案 1 :(得分:2)
是的,这个问题太宽泛了。但我有兴趣解决它。 以下是如何实现它的粗略示例。
我试着解释一下评论的内容。肯定可以做得更好,但我希望它有所帮助。
// 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;
}
答案 2 :(得分:1)
遍历选中的元素并检查
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>
答案 3 :(得分:0)
<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]);