Сначала пара замечаний:
Я предполагаю, что вы используете Babel для переноса JSX и для использования функций стрелок ES2015.Если нет, обновите свой вопрос, и я обновлю свой ответ.
Далее вам не нужны три элемента класса cursor .Кодекс предлагает вам использовать только два элемента.Синий, который я назову mainCursor , а белый - trailingCursor .
Кроме того, я не реализовал функцию eq из jQuery, но в этомНапример, мы уверены, что document.getElementByClassName вернет 2 элемента, поэтому я не включаю проверки на нулевое значение.
Способ реализации запрошенного поведения в React:
- Создание элемента курсора , который использует положение, сохраненное в состоянии , для визуализации
- Присоединение слушателя onMouseMove к родительскому элементу, внутри которого перемещена мышь
- Когда мышь перемещается, она вызывает функцию-обработчик, внутри которой мы сохраняем положение мыши в состоянии , используя setState , что вызывает повторное отображение * 1033Элемент * cursor , использующий новую позицию мыши
Как говорится, вот перенесенная версия функциональности из вашего вопроса.Я предоставил готовый фрагмент.
class App extends React.Component {
// we keep track of x and y coordinates for the blue circle - the main one
// and the trailing circle - the white one
// for simplicity, they are initialzed to (0, 0), the top left corner of the viewport
state = {
xMain: 0,
yMain: 0,
xTrailing: 0,
yTrailing: 0,
}
handleMouseMove = (e) => {
// Using pageX and pageY will cause glitching when you scroll the window down
// because it measures the distance from the top left rendered corner, not
// top left visible corner
const { clientX, clientY } = e;
// we set the main circle coordinates as soon as the mouse is moved
this.setState({
xMain: clientX,
yMain: clientY,
}, () => {
// this callback is invoked after the first setState finishes
//
// here we schedule saving the trailing coordinates in state 100ms
// after the main coordinates have been set to simulate the trailing
setTimeout(() => {
this.setState({
xTrailing: clientX,
yTrailing: clientY,
})
}, 100);
})
}
render = () => {
// we retrieve coordinates from state
const {
xMain,
yMain,
xTrailing,
yTrailing
} = this.state;
return (
// we need a container that has a definite height, 800px in my example
// this is to make sure it leaves enough room for mouse movement to happen and trigger the event handler
//
// also, you don't need the event listener on both your cursor elements, only on the container
<div
className='container'
onMouseMove={e => this.handleMouseMove(e)}
>
<div className='cursors'>
// this below is the main cursor
// we set its style inline with coordinates from state
<div
className='cursor'
style={{
left: xMain,
top: yMain,
}}
/>
// this below is the trailing cursor
<div
className='cursor'
style={{
left: xTrailing,
top: yTrailing,
}}
/>
</div>
</div>
)
}
}
ReactDOM.render(<App />, document.getElementById('root'));
* {
cursor: none;
}
.container {
background: black;
min-height: 800px;
}
.cursor {
position: fixed;
height: 10px;
width: 10px;
border-radius: 50%;
transform: translateX(-50%) translateY(-50%);
pointer-events:none;
}
.cursors .cursor:nth-child(1) {
background-color: #3a26fd;
z-index: 100002;
}
.cursors .cursor:nth-child(2) {
background-color: #f3f3f3;
z-index: 100001;
height: 9px;
width: 9px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>