在这种情况下,我需要将一个元素滚动到视口中。问题是我不知道哪个元素是可滚动的。例如,在Portrait中,body是可滚动的,而在Landscape中,它是另一个元素(并且有更多的情况会改变可滚动元素)
现在的问题是,给定一个需要滚动到视区中的元素,找到它的第一个可滚动父元素的最佳方法是什么?
我已经设置了一个演示here。使用该按钮,您可以在两种不同的情况之间切换
<div class="outer">
<div class="inner">
<div class="content">
...
<span>Scroll me into view</span>
</div>
</div>
</div>
正文是可滚动的或.outer
有什么建议吗?
发布于 2016-03-11 12:26:26
只需检查滚动条是否可见,如果看不到,请查看父级。
function getScrollParent(node) {
if (node == null) {
return null;
}
if (node.scrollHeight > node.clientHeight) {
return node;
} else {
return getScrollParent(node.parentNode);
}
}
发布于 2017-03-01 23:11:59
这是一个纯JS端口的jQuery UI scrollParent
方法,即cweston spoke of。我选择了这个,而不是接受答案的解决方案,如果还没有内容溢出,它就不会找到滚动父对象。
我的端口的一个不同之处在于,如果找不到具有正确的CSS overflow
属性值的父元素,我将返回<body>
元素。JQuery UI,则返回document
对象。这很奇怪,因为像.scrollTop
这样的值可以从<body>
中检索,但不能从document
中检索。
function getScrollParent(element, includeHidden) {
var style = getComputedStyle(element);
var excludeStaticParent = style.position === "absolute";
var overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/;
if (style.position === "fixed") return document.body;
for (var parent = element; (parent = parent.parentElement);) {
style = getComputedStyle(parent);
if (excludeStaticParent && style.position === "static") {
continue;
}
if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) return parent;
}
return document.body;
}
发布于 2018-03-09 04:38:11
大多数投票的答案并不是在所有情况下都有效,即使没有滚动条,scrollHeight > clientHeight
也可以是true
。
我找到了这个主要的解决方案https://github.com/olahol/scrollparent.js/blob/master/scrollparent.js#L13
^全部归功于编写代码的https://github.com/olahol。
将其重构为es6
export const getScrollParent = (node) => {
const regex = /(auto|scroll)/;
const parents = (_node, ps) => {
if (_node.parentNode === null) { return ps; }
return parents(_node.parentNode, ps.concat([_node]));
};
const style = (_node, prop) => getComputedStyle(_node, null).getPropertyValue(prop);
const overflow = _node => style(_node, 'overflow') + style(_node, 'overflow-y') + style(_node, 'overflow-x');
const scroll = _node => regex.test(overflow(_node));
/* eslint-disable consistent-return */
const scrollParent = (_node) => {
if (!(_node instanceof HTMLElement || _node instanceof SVGElement)) {
return;
}
const ps = parents(_node.parentNode, []);
for (let i = 0; i < ps.length; i += 1) {
if (scroll(ps[i])) {
return ps[i];
}
}
return document.scrollingElement || document.documentElement;
};
return scrollParent(node);
/* eslint-enable consistent-return */
};
您可以像这样使用它:
const $yourElement = document.querySelector('.your-class-or-selector');
getScrollParent($yourElement);
https://stackoverflow.com/questions/35939886
复制