#css #reactjs
Вопрос:
Когда я вертикально прокручиваю движущийся 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 amp;amp; (time.current = 1), 1))
}, [paused])
useEffect(() => {
const refreshTrackbar = () => {
if (trackerRef.current amp;amp; wholeRef.current amp;amp; !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, и ошибки не произошло, что заставляет меня думать, что это проблема, связанная с версией/платформой Chrome, а не со мной.
Комментарии:
1. Функция, которую вы написали , является очень дорогой операцией , поверх нее событие прокрутки-это перегрузка , из-за этого она отстает , вот несколько советов , которые могут помочь уменьшить ее , не используйте цикл внутри компонента React, он будет выполняться каждый раз, попробуйте получить значение только один раз, прежде чем compoent отрисовает
2. Хорошая идея. Преобразовали циклы в их собственные компоненты, и производительность действительно кажется лучше. К сожалению, все еще испытываю заморозки.
Ответ №1:
Я не совсем уверен, как заставить его перестать замерзать, но если бы вы добавили overflow:scroll;
в свой #root
div с большей высотой, чем у вашего бокового прокрутки, вы могли бы прокрутить его без замерзания.
Создание боковой прокрутки div определенной высоты также overflow-y: hidden;
может помочь.
Своего рода обходной путь, но он работает.
Комментарии:
1. вопрос не в этом