首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >查找第一个可滚动的父级

查找第一个可滚动的父级
EN

Stack Overflow用户
提问于 2016-03-11 20:06:55
回答 8查看 42.9K关注 0票数 74

在这种情况下,我需要将一个元素滚动到视口中。问题是我不知道哪个元素是可滚动的。例如,在Portrait中,body是可滚动的,而在Landscape中,它是另一个元素(并且有更多的情况会改变可滚动元素)

现在的问题是,给定一个需要滚动到视区中的元素,找到它的第一个可滚动父元素的最佳方法是什么?

我已经设置了一个演示here。使用该按钮,您可以在两种不同的情况之间切换

<div class="outer">
    <div class="inner">
        <div class="content"> 
            ...
            <span>Scroll me into view</span>
        </div>
    </div>
</div>

正文是可滚动的或.outer

有什么建议吗?

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2016-03-11 20:26:26

只需检查滚动条是否可见,如果看不到,请查看父级。

function getScrollParent(node) {
  if (node == null) {
    return null;
  }

  if (node.scrollHeight > node.clientHeight) {
    return node;
  } else {
    return getScrollParent(node.parentNode);
  }
}
票数 77
EN

Stack Overflow用户

发布于 2017-03-02 07: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;
}
票数 52
EN

Stack Overflow用户

发布于 2018-03-09 12: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);
票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35939886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档