【问题标题】:JavaScript - Scroll overflowed list element into viewJavaScript - 将溢出的列表元素滚动到视图中
【发布时间】:2016-10-23 05:38:40
【问题描述】:

所以你有一个很长的可滚动列表,并且想要将特定的 DOM 元素滚动到视图中:

我想出了一个解决方案,想与大家分享,希望对大家有所帮助! (这个QA思路直接取自SO) 我采用了一些我在 SO 上看到的较小的 JS 技巧,并在下面提出了以下功能:

【问题讨论】:

  • 通过什么事件发生在什么元素上?..是的,你可以这样做......但是怎么做?是单击按钮,悬停在 div 上,还是鼠标在表单上输入事件?....您要完成什么..您尝试过任何事情并遇到问题吗?...
  • @repzero 很抱歉让您感到困惑——我问过自己同样的问题,并想出了一个对我很有效的解决方案,所以我已经回答了自己的问题,希望能帮助其他人
  • 我投票决定将此问题作为题外话结束,因为 SO 不是测验托管网站。
  • @HighPerformanceMark 这直接来自 SO:'如果您有一个您已经知道答案的问题,并且您想公开记录该知识,以便其他人(包括您自己)可以找到它稍后,您可以在 Stack Exchange 网站上提出并回答您自己的问题。为了鼓励人们这样做,每次您提出问题时,页面底部都会有一个复选框。'

标签: javascript html css reactjs


【解决方案1】:
 /**
 * scroll an overflowed list so that the elementToView is visible
 *
 * @param      {<NodeList item>}   elementToView     list element to make visible
 * @param      {<NodeList item>}   elementContainer  element containing the elementToView
 * @param      {<NodeList item>}   listElement       actual list (<ul>?) element to scroll (could be the same as container)
 *
 *
 */
function scrollList(elementToView, elementContainer, listElement) {
    let containerHeight, topPos, listItem, temp = null
    if (typeof window !== 'undefined' && elementToView && elementContainer && listElement) {
        temp = window.getComputedStyle(elementContainer, null).getPropertyValue('padding-top')
        temp = parseInt(temp, 10) + parseInt(window.getComputedStyle(elementContainer, null).getPropertyValue('padding-bottom'), 10)
        // temp holds the top and bottom padding
        // usable space is the offsetHeight - padding
        containerHeight = elementContainer.offsetHeight - temp
        // amount of pixels away from the top of the container
        topPos = elementToView.offsetTop
        if (!containerHeight || !topPos) return false
        // get the height of a list item in the list to scroll 
        listItem = listElement.querySelector('li:first-of-type').offsetHeight
        // actually do the scrolling now
        // scroll the top of the list to show the elementToView on the bottom (as the last visible element in the list)
        listElement.scrollTop = (topPos - (containerHeight - listItem))
    }
}

下面是函数的使用示例:

let focusElement = document.getElementsByClassName('focus')[0]
let containerElement = document.getElementsByClassName('modal')[0]
let listElement = document.getElementsByClassName('chapter-list')[0]
// let's check if any selection index has changed, and then scroll to the correct
// positions to make sure the selected elements are in view
if (chapterlistSelectionIndex !== prevState.chapterlistSelectionIndex) {
    scrollList(focusElement, containerElement, listElement)
}

这将使用 focus 类获取 DOM 元素(li 项)并将其滚动到 chapter-list 中的最后一个可见位置(表示位置modal 容器底部的正上方)

这里有几点我想指出:

  • getComputedStyle(连同getPropertyValue)允许我们通过去除使用offsetHeight 计算的填充来计算容器中有多少实际可用空间用于滚动
  • parseInt 的第二个参数很重要,这是我刚刚发现的——这里它确保结果以 10 为底(如果无法解析,则为 NaN)
  • querySelector 抓取与 css 选择器匹配的第一个子元素——在这种情况下,我使用它来测量单个列表项的视觉高度,以确保 elementToView 与最后一个可见列表项完美匹配
  • 最后,我们要将 elementToView 滚动到容器的距离减去列表顶部的列表项(以便滚动列表项看起来附加到容器的底部)。如果您希望该项目位于列表顶部或中间,您可以在此处进行调整
  • 另外,如果您不确定 let 关键字,请参阅this

我希望这会有所帮助!

【讨论】:

  • 你应该在几个月前发布这个:)我已经用我的方式解决了类似的问题,但你的解决方案更优雅,不需要 jQuery :)
  • @Morpheus 感谢您的反馈! :) 是的,我的项目没有使用 jQuery,所以我需要一个普通的解决方案!很高兴你也有一个可行的解决方案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-04
  • 2017-07-29
相关资源
最近更新 更多