【问题标题】:How to scroll both X and Y smoothly at the same time in Javascript如何在Javascript中同时平滑滚动X和Y
【发布时间】:2021-12-22 10:13:55
【问题描述】:

对于具有scroll-behavior: smooth; 的父元素,我试图在单击子元素时滚动它,以便子元素在父元素中完全可见。如果它只需要水平或垂直滚动​​,这可以正常工作,但当它必须同时进行时失败(例如,孩子在右下角并且仅部分可见)。单击处理程序正在确定要添加/减去父级的 scrollTopscrollLeft 属性的值。我注意到,如果我在设置scrollLeft(但不是scrollTop)周围放置一个延迟大于滚动转换时间的setTimeout(),那么它就可以工作(但它看起来很奇怪)。有什么方法可以同时进行 X 和 Y 平滑滚动?

这里有一些伪代码,所以你可以了解我正在做的事情:

HTML

<div id="grid">
    <div class="row">
        <div id="cell-1" class="cell"> 1 </div>
        <div id="cell-2" class="cell"> 2 </div>
        ...
    </div>
    ...
</div>

CSS

#grid {
    height: 100vh;
    overflow: scroll;
    scroll-behavior: smooth;
}
.row {
    display: flex;
}
.cell {
    flex: 1 0 auto;
    border: 2px dashed gray;
    width: 250px;
    height: 100px;
    margin: 5px;
    padding: 10px;
}

JS

let grid = document.querySelector('#grid');

document.addEventListener('click', function (e) {
    if (e.target.classList.contains('cell')) {

        ... (omitted a bunch of code to obtain cell/grid X/Y bounds) ...

        if (cellRightBound > gridRightBound) {
            let scroll = cellRightBound - gridRightBound + halfCellWidth;
            grid.scrollLeft += scroll;
            console.log('scrolled right ' + scroll);
        } else if (cellLeftBound < gridLeftBound) {
            let scroll = gridLeftBound - cellLeftBound + halfCellWidth;
            if (scroll > 0) {
                grid.scrollLeft -= scroll;
                console.log('scrolled left ' + scroll);
            }
        }

        if (cellBottomBound > gridBottomBound) {
            let scroll = cellBottomBound - gridBottomBound + halfCellHeight;
            grid.scrollTop += scroll;
            console.log('scrolled down ' + scroll);
        } else if (cellTopBound < gridTopBound) {
            let scroll = gridTopBound - cellTopBound + halfCellHeight;
            if (scroll > 0) {
                grid.scrollTop -= scroll;
                console.log('scrolled up ' + scroll);
            }
        }
    }
});

【问题讨论】:

    标签: javascript scroll css-transitions


    【解决方案1】:

    所以答案是使用grid.scrollTo({left: scrollLeft, top: scrollTop}),并将变量scrollLeftscrollTop 设置为与grid.scrollLeftgrid.scrollTop 相同。例如:

            let scrollLeft, scrollTop;
    
            if (cellRightBound > gridRightBound) {
                let scroll = cellRightBound - gridRightBound + halfCellWidth;
                scrollLeft = grid.scrollLeft + scroll;
                console.log('scrolled right ' + scroll);
            } else if (cellLeftBound < gridLeftBound) {
                let scroll = gridLeftBound - cellLeftBound + halfCellWidth;
                if (scroll > 0) {
                    scrollLeft = grid.scrollLeft - scroll;
                    console.log('scrolled left ' + scroll);
                }
            }
    
            if (cellBottomBound > gridBottomBound) {
                let scroll = cellBottomBound - gridBottomBound + halfCellHeight;
                scrollTop = grid.scrollTop + scroll;
                console.log('scrolled down ' + scroll);
            } else if (cellTopBound < gridTopBound) {
                let scroll = gridTopBound - cellTopBound + halfCellHeight;
                if (scroll > 0) {
                    scrollTop -= grid.scrollTop - scroll;
                    console.log('scrolled up ' + scroll);
                }
            }
    
            if (scrollLeft !== undefined || scrollTop !== undefined) {
                if (scrollLeft === undefined)
                    scrollLeft = grid.scrollLeft;
                if (scrollTop === undefined)
                    scrollTop = grid.scrollTop;
                grid.scrollTo({left: scrollLeft, top: scrollTop, behavior: 'smooth'});
            }
    

    【讨论】:

      猜你喜欢
      • 2011-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-03
      • 1970-01-01
      • 2019-01-12
      相关资源
      最近更新 更多