0

当我垂直滚动移动的 div 时,一些内容会冻结。我想知道如何解决这个问题。它也不一致,因为单击开始/停止按钮有时会在几秒钟内解决问题。很困惑。

import { useEffect, useRef, useState } from "https://cdn.skypack.dev/react"
import ReactDOM from "https://cdn.skypack.dev/react-dom"

const Graph = ({ references: { trackerRef, wholeRef } }) => {
    return (
        <div
            ref={wholeRef}
            style={{
                overflow: 'scroll',
                height: '400px',
                backgroundColor: '#333',
                cursor: 'default',
                userSelect: 'none'
            }}
        >
            <div style={{ position: 'relative' }}>
                <div>
                    {(() => {
                        const items = []

                        for (let i = 1; i < 100; i++) {
                            items.push(
                                <div
                                    key={i}
                                    style={{
                                        position: 'absolute',
                                        left: i * 1000,
                                        height: '100%',
                                        display: 'flex',
                                    }}
                                >
                                    <div
                                        style={{
                                            width: '1px',
                                            backgroundColor: '#888',
                                        }}
                                    ></div>
                                    <div style={{ color: '#ddd', marginLeft: 8, fontSize: 14 }}>
                                        {i}s
                                    </div>
                                </div>
                            )
                        }

                        return items
                    })()}
                    {(() => {
                        const items = []

                        for (let i = 1; i < 1000; i++) {
                            if ((i * 100) % 1000 === 0) continue

                            items.push(
                                <div
                                    key={i}
                                    style={{
                                        position: 'absolute',
                                        left: i * 100,
                                        height: '100%',
                                        display: 'flex',
                                    }}
                                >
                                    <div
                                        style={{
                                            width: '1px',
                                            backgroundColor: '#555',
                                        }}
                                    ></div>
                                    <div style={{ color: '#aaa', marginLeft: 5, fontSize: 10 }}>
                                        {i * 100}ms
                                    </div>
                                </div>
                            )
                        }

                        return items
                    })()}
                    <div
                        ref={trackerRef}
                        style={{
                            position: 'absolute',
                            height: '100%',
                            display: 'flex',
                            width: '1px',
                            backgroundColor: 'lightgreen',
                        }}
                    ></div>
                </div>
                <div>
                    <div style={{ height: '2000px', width: '20px' }}></div>
                </div>
            </div>
        </div>
    )
}

const App = () => {
    const trackerRef = useRef(null)
    const wholeRef = useRef(null)
    const [paused, setPaused] = useState(false)
    const animationFrames = useRef([]).current
    const intervals = useRef([]).current
    const time = useRef(0)

    useEffect(() => {
        // Increase time when unpaused
        intervals.push(setInterval(() => !paused && (time.current += 1), 1))
    }, [paused])

    useEffect(() => {
        const refreshTrackbar = () => {
            if (trackerRef.current && wholeRef.current && !paused) {
                trackerRef.current.style.left = time.current + 'px'
                wholeRef.current.scrollLeft = time.current - 100
                requestAnimationFrame(refreshTrackbar)
            }
        }

        animationFrames.push(requestAnimationFrame(refreshTrackbar))
    }, [paused])

    return (
        <>
            <h1>Scrollbug</h1>
            <button
                onClick={() => {
                    if (paused) {
                        setPaused(false)
                    } else {
                        setPaused(true)
                        animationFrames.forEach(frame => cancelAnimationFrame(frame))
                        intervals.forEach(interval => clearInterval(interval))
                    }
                }}
            >
                {paused ? 'Start' : 'Stop'}
            </button>
            <br />
            <br />
            <Graph references={{ trackerRef, wholeRef }} />
        </>
    )
}

ReactDOM.render(<App />, document.getElementById("root"))

这是一个自己测试问题的代码笔

https://codepen.io/springer268/pen/PomjVvw

编辑:所以我在我的 mac 上尝试了这个 codepen,但这个 bug 没有发生,这让我相信这是一个 Chrome 版本/平台特定的问题,而不是我的问题。

4

1 回答 1

-1

我不太确定如何让它停止冻结,但如果你添加了一个比overflow:scroll;#root的横向滚动 div 高度更大的 div,你可以滚动它而不会冻结。

使横向滚动的 div 具有特定的高度,overflow-y: hidden;也可以提供帮助。

一种解决方法,但它有效。

于 2021-07-19T18:12:55.613 回答