首页IT科技bootstrap轮播图居中(react组件实现无缝轮播示例详解)

bootstrap轮播图居中(react组件实现无缝轮播示例详解)

时间2025-04-29 13:44:41分类IT科技浏览3172
导读:正文 需求是做一个无缝轮播图,我说这不是有很多现成的轮子吗?后来了解到他有一个特殊的需求,他要求小圆点需要在轮播图外面,因为现在大部分插件都是将小圆点写在轮播图内部的,这对于不了解插件内部结构的小伙伴确实不知道如何修改。...

正文

需求是做一个无缝轮播图          ,我说这不是有很多现成的轮子吗?后来了解到他有一个特殊的需求               ,他要求小圆点需要在轮播图外面      ,因为现在大部分插件都是将小圆点写在轮播图内部的     ,这对于不了解插件内部结构的小伙伴确实不知道如何修改          。

很久没有写插件的我准备写一个插件(react)

无缝轮播

无缝轮播从最后一张到第一张的过程中不会原路返回               ,它就像轮子似的           ,从结束到开始是无缝连接的     ,非常自然地循环下去               。

实现思路

轮播图的实现思路有很多               ,我们这里采用的是最简单的轮播图方案           ,如上图,即当轮播图轮播到第x张图片时               ,当前整个轮播图列表中只保留第x张图片                ,其余图片dom全部隐藏掉即可      。

那么大家有一个疑问,这样不会导致切换时不连贯吗?这个大家不必担心          ,我们可以在上一个轮播图小时和下一个轮播图展现时增加动画效果                ,来达到连贯的感觉     。

构思使用时代码结构

参考了大部分轮播图组件      ,得出来下面的这种使用结构               。

import Carousel,{ Item } from 组件 render(){ return ( <Carousel> <Item><img src="https://www.jb51.net/article/xxx" /></Item> <Item><img src="https://www.jb51.net/article/xxx" /></Item> <Item><img src="https://www.jb51.net/article/xxx" /></Item> </Carousel> ) }

Carousel组件

新建Carousel组件          ,这个组件是组件的整体框架文件           。

内部增加inner div 来充当当前展示轮播图的视口

const Carousel=()=>{ return ( <div className={carousel}> <div className={carousel-inner}> {xxx轮播图xxx} </div> </div> ) }

overflow:hidden是关键

.inner{ width:100%; height:100%; position: relative; overflow: hidden; }

CarouselItem组件

新建CarouselItem组件               ,这个组件是Carousel组件的子组件      ,是轮播图列表每一项的容器     。

const CarouselItem=(props)=>{ return ( <div className={carousel-item}> {props.children} </div> ) }

注意 这里需要使用top0 left0 不然显示的时候会从上往上偏移 导致错误显示

.carousel-item{ position: absolute; left:0; top:0; width: 100%; height:100%; }

完善组件

如何显示当前轮播图元素

之前我们说过这次我们轮播图的核心思路是显示当前元素     ,那么什么情况下显示当前元素呢?

carousel组件内有一个state表示当前轮播到第几张图 我们这里叫current               ,而根据传入carousel的元素排序           ,我们可以在item内部拿到当前是第几张图片     ,然后2者如果是相等的,就显示当图片               。

我们如何获取元素当前的index呢?我们可以利用react提供的解析children的api

// util import React from "react"; export function injecteIndex(children:React.ElementType,current):any{ let result:React.ReactElement[]=[]; React.Children.forEach(children,(item,index)=>{ result.push(React.cloneElement((item as any),{ //selfIndex即为轮播图的index selfIndex:index, key:index, current })) }); return result; } //carousel组件 //initial 为传入配置 默认为0 即默认展示第一张图 const Carousel=()=>{ const { initial }=props; const [current,setCurrent]=useState<number>(initial); return ( <div className={carousel}> <div className={carousel-inner}> {injecteIndex(children,current)} </div> </div> ) } //carousel-item组件 const CarouselItem=(props)=>{ const { selfIndex,current }=props; const visible=selfIndex===current return ( {visible && <div className={carousel-item}> {props.children} </div>} ) }
实现autoPlay

上面我们其实已经实现了第一张图的展示               ,那么我们如何让他动起来呢?其实也很简单           ,我们一起来实现一下

//useLatest import { useEffect, useRef } from "react" export default (params:any)=>{ const latest=useRef(); useEffect(()=>{ latest.current=params; }) return latest; } //carousel组件 const Carousel=(props)=>{ const { //initial 为传入配置 默认为0 即默认展示第一张图 initial=0, //是否自动轮播 默认为是 autoplay=true, //时间间隔 默认为3秒 interval=3000 }=props; //新建定时器存储变量 const timer:any=useRef(null); const [current,setCurrent]=useState<number>(initial); const [itemLength]=useState<number>(React.Children.count(children)); //解决闭包问题 const latest:any=useLatest(current); const autoPlay=()=>{ //设置定时器 每隔3s切换到下一张图片 timer.current=setInterval(()=>{ setStep(next); },interval); } const setStep=(direction:prev|next)=>{ switch(direction){ case prev: let prevStep:number=latest.current-1; //当为第一张时 跳到第5张 if(prevStep===-1){ prevStep=itemLength-1; } setCurrent(prevStep); break; case next: let nextStep:number=latest.current+1; //当为最后一张时 跳到第1张 if(nextStep===itemLength){ nextStep=0; } setCurrent(nextStep); break; default: } } useEffect(()=>{ if(autoplay){ //自动轮播 autoPlay(); } return ()=>{ //销毁定时器 clearInterval(timer.current); timer.current=null; } },[autoplay]); return ( <div className={carousel}> <div className={carousel-inner}> {injecteIndex(children,current)} </div> </div> ) } ```# 完成动画 其实上面我们已经把无缝轮播业务逻辑完成了,那么如何让他轮播起来呢?我们这里使用react官方推荐的一个过渡库               ,因为react并没有像vue为我们提供transition api           。 ```js const CarouselItem=(props)=>{ const { children, selfIndex }=props; const visible=selfIndex===current; return ( <CSSTransition mountOnEnter unmountOnExit appear in={visible} timeout={500} classNames={carousel}> <div className={carousel-item} > {children} </div> </CSSTransition> ) });
.carousel-enter-active,.carousel-exit-active{ transition: all 500ms linear; } .carousel-enter{ transform: translateX(100%); opacity: 0.8; } .carousel-enter-active{ transform: translateX(0); opacity: 1; } .carousel-exit{ transform: translateX(0); opacity: 1; } .carousel-exit-active{ transform: translateX(-100%); opacity: 0.8; }

之前我们设置的top:0 left:0 可以得出轮播元素的原点都是容器的左上角 在enter过程将translateX从100到0 即可展示从右往左的动画效果 在exit过程前将translateX从0到-100 即可展示从左往右的动画效果

完成小圆点

其实让我写轮播图的老兄 最大的难点是小圆点的位置 因为大部分轮播图 小圆点部分都是写在inner里面的 而inner元素为overflow:hidden                ,即不管如何小圆点,他都会溢出隐藏。所以这次我们把小圆点放在inner元素上          ,并且提供一个属性让小圆点可调               。

//carousel <div className={classes}> <div className={inner}> {injecteIndex(children)} </div> <Dots length={itemLength} position={dotPosition}/> </div> //dots原点 <div className={classnames( classes, )} style={{...position}}> { newArray.map((item,index)=>( <div className={classnames(`${prefixCls}-item`,{ active:current===index })} key={index} onClick={()=>onClick(index)}/> )) } </div>

实现效果

源码地址

如果大家有想使用的话 可以放心 使用 源码已发到github和npm上面

npm install @parrotjs/carousel -S

以上就是react 组件实现无缝轮播示例详解的详细内容                ,更多关于react 组件无缝轮播的资料请关注本站其它相关文章!

声明:本站所有文章      ,如无特殊说明或标注          ,均为本站原创发布                。任何个人或组织               ,在未征得本站同意时      ,禁止复制          、盗用               、采集      、发布本站内容到任何网站     、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益     ,可联系我们进行处理          。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
微信支付怎么接触冻结(记录–接入微信支付的全套姿势) 企业网站建设推广(企业网站推广,提升品牌影响力的利器)