多条文字切换滚动实现(React、JS)

多条文字切换滚动实现(React、JS)constructor内部主要记录了滚动文字的基本信息,重要的两个参数是sloganIndex,sign。 希望互相学习,非常感谢。

一、需求

1、一条或者多条滚动文字,有序切换
2、循环滚动

二、原理

setInterval:控制循环
requestAnimationFrame:动画效果

三、实现

多条文字切换滚动实现(React、JS)

 constructor() {
    super();
    this.state = {
        sloganList: [
            "横向滚动文字1横向滚动文字1横向滚动文字1横向滚动文字1",
            "横向滚动文字2",
            "横向滚动文字3",
        ],
        sloganIndex: 0,//展示的文本下标
    }
    this.sign = true;//定时器判断是否要进行文字滚动动画
    this.textWidth = 0;//文字的宽度
    this.textLeft = 0;
    this.offsetStep = 3;//每次移动的步长
}

constructor内部主要记录了滚动文字的基本信息,重要的两个参数是sloganIndex,sign。 sloganIndex控制目前需要展示的数据下标 sign则是判断是否调用文字滚动控制方法,值为true则调用,进入新一轮的滚动动画

componentDidMount() {
    let sloganContainer = this.container.clientWidth;
    this.text.style.left = sloganContainer + "px";
    this.timer = setInterval(() => {
        if (this.sign) {
            if(Array.isArray(this.state.sloganList)&&this.state.sloganList.length) {
                this.showSlogan();
            } else {
                clearInterval(this.timer);
            }
        } else {
            this.timer = null;
        }
    }, 1000);
}

componentWillUnmount() {
    clearInterval(this.timer);
}

在组建渲染完成后定时器启动,通过sign信号控制是否执行滚动方法;组件销毁、数据格式错误或是没有数据时清除定时器

showSlogan = () => {
    this.textWidth = this.text.clientWidth;//文字宽度
    this.textLeft = parseInt(this.text.style.left);//相对父元素偏移距离
    if(this.textLeft >= -this.textWidth) this.sign = false;
    if(this.textLeft > -this.textWidth) {
        this.text.style.left = this.textLeft - this.offsetStep + "px";
        requestAnimationFrame(this.showSlogan)
    } else {
        let nextIndex = 
        this.state.sloganIndex != this.state.sloganList.length - 1 ? ++this.state.sloganIndex : 0;
        this.setState({
            sloganIndex: nextIndex
        }, () => {
            this.text.style.left = this.container.clientWidth + "px";
            this.textWidth = this.text.clientWidth;
            this.sign = true;
        })
    }
}

1、开始滚动前,将sign设置为false,滚动期间不会重复调用 2、文字直到最后一个字消失本次任务才算结束,所以文字元素最后的left值为元素宽度的负值 3、本轮动画结束后判断下一个动画文字所在下标,改变sloganIndex 4、待新内容渲染结束后设置新文字元素在内容区的最右边,并获取新的滚动文字宽度 5、设置sign为true,定时器运行时检查到该值为true则调用showSlogan方法

四、完整代码

class Slogan extends Component {
    constructor() {
        super();
        this.state = {
            sloganList: [
                "横向滚动文字1横向滚动文字1横向滚动文字1横向滚动文字1",
                "横向滚动文字2",
                "横向滚动文字3",
            ],
            sloganIndex: 0,
        }
        this.sign = true;//判断是否进行文字滚动动画
        this.textWidth = 0;//文字的宽度
        this.textLeft = 0;
        this.offsetStep = 3;//每次移动的步长
    }

    componentDidMount() {
        let sloganContainer = this.container.clientWidth;
        this.text.style.left = sloganContainer + "px";
        this.timer = setInterval(() => {
            if (this.sign) {
                if(this.state.sloganList&&this.state.sloganList.length) {
                    this.showSlogan();
                } else {
                    clearInterval(this.timer);
                }
            } else {
                this.timer = null;
            }
        }, 1000);
    }

    componentWillUnmount() {
        clearInterval(this.timer);
    }

    render() {
        const { sloganList, sloganIndex } = this.state;
        return (
            <div ref={(ref) => this.container = ref} className="container"> <span ref={(ref) => this.text = ref} className="slogan"> {sloganList[sloganIndex]} </span> </div>
        )
    }

    showSlogan = () => {
        this.textWidth = this.text.clientWidth;//文字宽度
        this.textLeft = parseInt(this.text.style.left);//相对父元素偏移距离
        if(this.textLeft >= -this.textWidth) this.sign = false;
        if(this.textLeft > -this.textWidth) {
            this.text.style.left = this.textLeft - this.offsetStep + "px";
            requestAnimationFrame(this.showSlogan)
        } else {
            let nextIndex = this.state.sloganIndex != this.state.sloganList.length - 1 ? ++this.state.sloganIndex : 0;
            this.setState({
                sloganIndex: nextIndex
            }, () => {
                this.text.style.left = this.container.clientWidth + "px";
                this.textWidth = this.text.clientWidth;
                this.sign = true;
            })
        }
    }
}
.container {
    width: 70%;
    height: 35px;
    line-height: 35px;
    margin: 0 auto;
    border: 1px solid #B0BEC5;
    padding: 0 10px;
    position: relative;
    overflow: hidden;
}

.slogan {
    position: relative;
    display: inline-block;
}

五、总结

主要做个记录,也没用jQuery,原生js的getter/setter操作太麻烦了 希望互相学习,非常感谢。

今天的文章多条文字切换滚动实现(React、JS)分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/22955.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注