React + Ts 实现小球拖拽,交互(通过定义,绑定同一个事件)

将要实现的效果

                                              

                                          

 

 

HTML 代码

 <div className="line" ref={this.limit}>
                <div className="line-ball"></div>
                <div className="line-ball ac"></div>
                <div className="lines" ref={this.line}></div>
            </div>

Css代码

.line {
    position: relative;
    width: 300px;
    height: 8px;
    background: turquoise;
    margin: 100px auto;

    .line-ball {
        position: absolute;
        left: 0;
        top:0;
        bottom: 0;
        margin: auto;
        width: 30px;
        height: 30px;
        background: tomato;
        border-radius: 50%;
        z-index: 77;
    }
    .ac {
        left: 270px;
    }
    .lines{
        position: absolute;
        left: 0;
        width: 300px;
        height: 8px;
        background: tan;
      
    }


}

js代码块

import { Component, createRef } from 'react'
import './index.less'
class Line extends Component {
    // 定义数据
    limit = createRef<HTMLDivElement>();
    line = createRef<HTMLDivElement>();
    Balls?: HTMLDivElement;
    IfBall: boolean = false;
    IfSide: boolean = false;
    DisX: number = 0;
    x: number = 0;
    ParentWidth: number = 0
    BallWidth: number = 0
    // 一组
    childs?: HTMLCollection
    Dis: number = 0


    // 封装元素
    // 父元素
    Limit() {
        return this.limit.current as HTMLDivElement
    }
    // bar
    Line() {
        return this.line.current as HTMLDivElement
    }

    Childs(n: number) {
        return this.Limit().children[n] as HTMLDivElement
    }
    // 页面加载,仅运行一次
    componentDidMount() {
        this.Limit().ontouchstart = this.FnStart.bind(this)
        // 父盒子宽
        this.ParentWidth = this.Limit().offsetWidth
        // 子集
        this.childs = this.Limit().children
    }
    // 事件开始
    FnStart(ev: TouchEvent) {
        this.Balls = ev.target as HTMLDivElement;
        this.IfBall = this.Balls.classList.contains('line-ball')

        if (this.IfBall) {
            // 小球
            this.DisX = ev.changedTouches[0].pageX - this.Balls.offsetLeft;
            this.BallWidth = (this.Balls as HTMLDivElement).offsetWidth;
            document.ontouchmove = this.FnMove.bind(this);

        }


    }
    FnMove(ev: TouchEvent) {
        this.Balls = ev.target as HTMLDivElement
        this.IfBall = this.Balls.classList.contains('line-ball')

        if (this.IfBall) {
            this.x = ev.changedTouches[0].pageX - this.DisX;
            // 区分左右小球
            this.IfSide = this.Balls.classList.contains('ac');

            // 限制小球活动的范围
            if (this.x < 0) this.x = 0;
            if (this.x > this.ParentWidth - this.BallWidth) this.x = this.ParentWidth - this.BallWidth;

            // 给当前小球设置拖拽
            this.Balls.style.left = this.x + 'px';
            // 判断左右
            if (this.IfSide) {
                // 右
                this.Dis = this.x - this.Childs(0).offsetLeft

                if (this.Dis < 0) {
                    this.Line().style.left = this.x + 'px'
                } else {
                    this.Line().style.left = this.Childs(0).offsetLeft + 'px'
                }
            } else {
                // 左
                this.Dis = this.x - this.Childs(1).offsetLeft;
                if (this.Dis < 0) {
                    this.Line().style.left = this.x + 'px'
                } else {
                    this.Line().style.left = this.Childs(1).offsetLeft + 'px'
                }
            }
            this.Line().style.width = Math.abs(this.Dis) + 'px';
        }

    }

    render() {
        return (
            HTML代码
        )
    }
}
export default Line

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值