【react+ts】react+ts实现双滑块移动效果(事件委派写法),交叉

这是一个使用React编写的双球滑动组件,通过触摸事件实现小球在滑块上的滑动效果。组件内部绑定了触摸开始和移动事件,根据触摸位置动态调整小球的位置,并更新连接线的长度和位置。样式使用SCSS进行定义,提供了基础的布局和背景颜色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

tsx:

import React, {Component} from 'react';
import './ball.scss';

class DoubleBall extends Component {
    parent: any = React.createRef();
    ballOne: any = React.createRef();
    ballTwo: any = React.createRef();
    lineOne: any = React.createRef();
    lineTwo: any = React.createRef();
    maxWidth: number = 0;
    ballOneStart: number = 0;
    ballTwoStart: number = 0;
    x: number = 0;
    dis: number = 0;

    componentDidMount() {
        this.maxWidth = this.parent.offsetWidth;
        document.ontouchstart = this.touchStart.bind(this);
    }

    touchStart(e: TouchEvent) {
        if ((e.target as HTMLDivElement).className.indexOf('ball') !== -1) {
            if ((e.target as HTMLDivElement).className !== 'ball ac') {
                this.x = e.targetTouches[0].pageX - this.ballOne.offsetLeft;
            } else {
                this.x = e.targetTouches[0].pageX - this.ballTwo.offsetLeft;
            }
            document.ontouchmove = this.touchMove.bind(this);
        }
    }

    touchMove(e: TouchEvent) {
        if ((e.target as HTMLDivElement).className.indexOf('ball') !== -1) {
            this.dis = e.targetTouches[0].pageX - this.x;
            if (this.dis < 0) {
                this.dis = 0;
            }
            if (this.dis > this.maxWidth) {
                this.dis = this.maxWidth;
            }
            if ((e.target as HTMLDivElement).className !== 'ball ac') {
                // 左边小球
                this.lineOne.style.width = this.dis + 'px';
                this.ballOne.style.left = this.dis + 'px';
            } else {
                // 右边小球
                this.ballTwo.style.left = this.dis + 'px';
            }
            this.lineTwo.style.width = Math.abs(this.ballTwo.offsetLeft - this.ballOne.offsetLeft) + 'px';
            this.lineTwo.style.left =
                this.ballTwo.offsetLeft - this.ballOne.offsetLeft >= 0 ? this.ballOne.offsetLeft + 'px' : this.ballTwo.offsetLeft + 'px';
        }
    }

    render() {
        return (
            <div className='double-ball'>
                <div className='slide-bar' ref={(div: HTMLDivElement) => (this.parent = div)}>
                    <div className='line' ref={(div: HTMLDivElement) => (this.lineOne = div)}></div>
                    <div className='line ac' ref={(div: HTMLDivElement) => (this.lineTwo = div)}></div>
                    <div className='ball' ref={(div: HTMLDivElement) => (this.ballOne = div)}></div>
                    <div className='ball ac' ref={(div: HTMLDivElement) => (this.ballTwo = div)}></div>
                </div>
            </div>
        );
    }
}

export default DoubleBall;

scss:

.double-ball {
  .slide-bar {
    width: 700px;
    height: 50px;
    background: #ccc;
    margin: 10px auto;
    position: relative;
    .line{
      position: absolute;
      height: 30px;
      background: #ccc;
      &.ac{
        background: lawngreen;
      }
    }
    .ball {
      position: absolute;
      width: 50px;
      height: 50px;
      background: goldenrod;
      border-radius: 50%;
      transform: translateX(-25px);
      z-index: 5;
      &.ac{
        left: 50px;
      }
    }
  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁星召唤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值