Получите высоту непереполненной части div
Скажем, что у меня есть обертка div с overflow:hidden
на ней и div внутри, которая находится далеко ниже видимой части. Как получить видимую высоту внутреннего div?
<div id="wrapper" style="overflow: hidden; height:400px;">
<div id="inner">
<!--Lots of content in here-->
</div>
<div>
Каждый метод, который я пытаюсь получить высоту внутреннего div, возвращает всю высоту, включая скрытые части, то есть 2000px. Я хочу, чтобы получить высоту только видимой части, поэтому 400px в этом примере.
Я знаю, что могу просто получить высоту parentNode
, но в производстве внутренний div может не быть первым ребенком. Таким образом, могут быть другие divs, разделяющие их, и поэтому высота #inner
будет равна 400 - независимо от смещений элементов между ним и #wrapper
.
Ответы
Ответ 1
В качестве базового алгоритма это может работать:
var offset = 0;
var node = document.getElementById("inner");
while (node.offsetParent && node.offsetParent.id != "wrapper")
{
offset += node.offsetTop;
node = node.offsetParent;
}
var visible = node.offsetHeight - offset;
Но если вы делаете такие вещи, возможно, вы уже используете jQuery, который может быть сервисом с его функциями .height()
и .offset()
:
$("#wrapper").height()-
$("#inner").offset()['top']+
$("#wrapper").offset()['top'];
Ответ 2
Быстрый алгоритм, который идет вверх по дереву DOM, смотря на window.getComputedStyle
для overflow: hidden
function visibleArea(node){
var o = {height: node.offsetHeight, width: node.offsetWidth}, // size
d = {y: (node.offsetTop || 0), x: (node.offsetLeft || 0), node: node.offsetParent}, // position
css, y, x;
while( null !== (node = node.parentNode) ){ // loop up through DOM
css = window.getComputedStyle(node);
if( css && css.overflow === 'hidden' ){ // if has style && overflow
y = node.offsetHeight - d.y; // calculate visible y
x = node.offsetWidth - d.x; // and x
if( node !== d.node ){
y = y + (node.offsetTop || 0); // using || 0 in case it doesn't have an offsetParent
x = x + (node.offsetLeft || 0);
}
if( y < o.height ) {
if( y < 0 ) o.height = 0;
else o.height = y;
}
if( x < o.width ) {
if( x < 0 ) o.width = 0;
else o.width = x;
}
return o; // return (modify if you want to loop up again)
}
if( node === d.node ){ // update offsets
d.y = d.y + (node.offsetTop || 0);
d.x = d.x + (node.offsetLeft || 0);
d.node = node.offsetParent;
}
}
return o; // return if no hidden
}
example скрипка (посмотрите на консоль).
Ответ 3
Единственный способ, которым я нашел это в каждом случае, в том числе при переполнении, transform: translate()
, и есть другие вложенные контейнеры между элементом и элементом, который скрывает его переполнение, состоит в объединении .getBoundingClientRect()
со ссылкой на предка, который скрывает переполнение элемента:
function getVisibleDimensions(node, referenceNode) {
referenceNode = referenceNode || node.parentNode;
var pos = node.getBoundingClientRect();
var referencePos = referenceNode.getBoundingClientRect();
return {
"width": Math.min(
node.clientWidth,
referencePos.left + referenceNode.clientWidth - pos.left,
node.clientWidth - (referencePos.left - pos.left)
),
"height": Math.min(
node.clientHeight,
referencePos.top + referenceNode.clientHeight - pos.top,
node.clientHeight - (referencePos.top - pos.top)
)
}
}
Если ссылка node не указана, предполагается родительский node: Demo.
Обратите внимание, что это не учитывает, является ли элемент видимым в окне просмотра, просто видимым (не скрытым из-за переполнения). Если вам нужны оба варианта, вы можете объединить функциональные возможности с этим ответом. Он также не проверяет visibility: hidden
, поэтому, если вам нужно, вам нужно проверить свойство style.visibility
node и всех его предков.
Ответ 4
Я думаю, держась рядом с ним, вычисляя его scrollTop и элемент переполнения scrollTop, а затем вычитая его из братьев и сестер, scroolTop может работать
Ответ 5
Приведенный ниже код вычисляет видимую часть элемента. Под видимой частью я подразумеваю часть, которая видна в окне , но я думаю, что вы можете легко изменить ее, чтобы основать вычисление на произвольном элементе контейнера.
function computeVisibleHeight ($t) {
var top = $t.position().top;
var windowHeight = $(window).height();
var scrollTop = $(window).scrollTop();
var height = $t.height();
if (top < scrollTop && height - scrollTop >= windowHeight) {
// first case: the top and the bottom of the element is outside of the window
return windowHeight;
} else if (top < scrollTop) {
// second: the top is outside of the viewport but the bottom is visible
return height - (scrollTop - top);
} else if (top > scrollTop && top + height < windowHeight) {
// the whole element is visible
return height;
} else {
// the top is visible but the bottom is outside of the viewport
return windowHeight - (top - scrollTop);
}
}
В коде используется jquery.