我有这种情况需要将元素滚动到视口中。问题是我不知道哪个元素是可滚动的。例如,在Portrait中,body是可滚动的,而在Landscape中它是另一个元素(并且有更多情况可以改变可滚动元素)
现在的问题是,给定一个需要滚动到视口中的元素,找到第一个可滚动父级的最佳方法是什么?
我已经设置了一个演示here。使用按钮,您可以在两种不同的情况之间切换
<div class="outer">
<div class="inner">
<div class="content">
...
<span>Scroll me into view</span>
</div>
</div>
</div>
身体是可滚动的或.outer
有什么建议 ?
只检查滚动条是否可见,如果没有查看父项。
function getScrollParent(node) {
if (node == null) {
return null;
}
if (node.scrollHeight > node.clientHeight) {
return node;
} else {
return getScrollParent(node.parentNode);
}
}
这是scrollParent
的jQuery UI cweston spoke of方法的纯JS端口。我选择了这个而不是接受的答案的解决方案,如果没有内容溢出,它将找不到滚动父级。
与我的端口的一个区别是,如果没有找到具有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;
}
大多数选票的答案在所有情况下都不起作用即使没有滚动条,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);
我想你想要这个。
$('button').click(function() {
$("body").addClass("body");
$('.outer').toggleClass('scroller');
check($(".content"));
});
function check(el) {
var overflowY = el.css("overflow-y");
if (overflowY == "scroll") {
alert(el.attr("class") + " has");
} else {
if(el.parent().length > 0)
check(el.parent());
else
return false;
}
}
body {
height: 450px;
overflow-y: scroll;
}
div.inner {
width: 200px;
height: 400px;
border: 1px solid #000;
}
div.outer {
width: 200px;
height: 200px;
}
div.outer.scroller {
overflow-y: scroll;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button>
toggle
</button>
<div class="outer">
<div class="inner">
<div class="content">
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." adipiscing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
</div>
</div>
</div>
使用谷歌浏览器开发工具,当您部分向下滚动页面时,检查页面,选择您认为可能正在滚动的DOM节点。然后拉起控制台(从开发工具的Elements选项卡中按ESC键)并键入$0.scrollTop
。这将打印出该元素的当前滚动位置。如果它不是0那么你就会知道那是正在滚动的元素。
在@Web_Designer's answer的基础上进一步发展,
如果您为该元素传递jQuery object
并且收到以下错误,
Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'
然后尝试只传递btw驻留在数组键Dom Node element
的0
,如果元素是单个元素。例如。
getScrollParent(jQuery("#" + formid)[0])