elementui中的写法

    1. scrollIntoView (container, selected) {
    2. if (!selected) {
    3. container.scrollTop = 0
    4. return
    5. }
    6. const offsetParents = []
    7. let pointer = selected.offsetParent
    8. // 获取目标节点的上层节点,
    9. // 层层遍历,依次将目标节点的外层节点push到数组中
    10. // Node.contains()返回的是一个布尔值,来表示传入的节点是否为该节点的后代节点
    11. while (pointer && container !== pointer && container.contains(pointer)) {
    12. // 当遍历到上层节点为容器container时终止
    13. offsetParents.push(pointer)
    14. pointer = pointer.offsetParent
    15. }
    16. // reduce出目标节点距离容器的top距离
    17. const top = offsetParents.reduce((prev, curr) => (prev + curr.offsetTop), selected.offsetTop)
    18. // bottom距离即为top距离+目标节点的高度
    19. const bottom = top + selected.offsetHeight
    20. // 容器的已经滚动了的高度,指已经隐藏起来的部分的高度
    21. const viewRectTop = container.scrollTop
    22. // 容器展示的高度 + 容器已经滚动的距离
    23. const viewRectBottom = viewRectTop + container.clientHeight
    24. if (top < viewRectTop) {
    25. container.scrollTop = top
    26. } else if (bottom > viewRectBottom) {
    27. container.scrollTop = bottom - container.clientHeight
    28. }
    29. }

    简单粗暴的版本,直接将目标节点滚动到容器中心

    1. if (!selected) {
    2. container.scrollTop = 0
    3. return
    4. }
    5. const offsetParents = []
    6. let pointer = selected.offsetParent
    7. // 获取目标节点的上层节点,
    8. // 层层遍历,依次将目标节点的外层节点push到数组中
    9. // Node.contains()返回的是一个布尔值,来表示传入的节点是否为该节点的后代节点
    10. while (pointer && container !== pointer && container.contains(pointer)) {
    11. // 当遍历到上层节点为容器container时终止
    12. offsetParents.push(pointer)
    13. pointer = pointer.offsetParent
    14. }
    15. // reduce出目标节点距离容器的top距离
    16. const top = offsetParents.reduce((prev, curr) => (prev + curr.offsetTop), selected.offsetTop)
    17. container.scrollTop = top - (container.clientHeight / 2) + selected.clientHeight
    18. }