Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

轮播图组件 react banner slider(17-07-23) #13

Open
zhaozy93 opened this issue Jul 23, 2017 · 0 comments
Open

轮播图组件 react banner slider(17-07-23) #13

zhaozy93 opened this issue Jul 23, 2017 · 0 comments

Comments

@zhaozy93
Copy link
Owner

zhaozy93 commented Jul 23, 2017

react-banner-slider

最近好忙,每天都要很晚回家。事情也比较多,又到了亲朋好友结婚的季节了。。。。jQuery源码也好久没继续看了,不过最近差不多理解了react的构建思想,大概知道如何实现组件的实现,setState背后的机制和简单的diff,确实无论哪个库或者哪个框架都有不少干货,要不然也不会流行开来。

先放地址npm
github

entry

刚好需要写一个轮播图的组建,其实轮播图应该是很多前端er的入门任务吧,不过好像我这种半路出家的当时没实现过。于是就写了一个banner组建,主要应用于pc端吧,以后再对移动端进行适配。
应用起来真是超级简单

import Banner from 'react-banner-slider';
<Banner className='custome-banner-class' style={{marginTop: 30}} duration={1} stopDuration={500} direction={true} autoPlayer={true}>
  <Banner.Item className='custome-banner-item-class' key={1} backgroundSrc={'./static/1.jpg'}>
    <div style={{position: 'absolute', top: '50%', left: '50%'}}>
      <h2>Title</h2>
      <span>Description</span>
    </div>
  </Banner.Item>
  <Banner.Item className="cnmdsjfhais" key={2} backgroundSrc={'./static/2.jpg'}>111</Banner.Item>
  <Banner.Item key={3} backgroundSrc={'./static/3.jpg'}>111</Banner.Item>
</Banner>

思想斗争过程

当时就想着一定要最终样子像antd里面Select选择器组件那样。 而且个人认为两者比较像, 外层决定它是一个什么样的组件,内层比较固定,在Select里面就是Select.Option基本就是字符串,以供用户选择。 在这里banner其实内部也特别简单就是图片而已。但是呢背景是图片可以,但图片上方总还是要有一些元素、文字甚至小图片等,而且肯定还是主要内容,毕竟是Banner嘛。 因此开始的关键就是如何做结构的处理。

  • 顶层Banner肯定确认无疑
  • Banner的子元素应该是符合条件的, 毕竟要从这里面拿到图片的信息。(Banner.Item)
  • 最内层也就是背景图片上的自定义信息,例如文字图标等。

实现

实现1

之前确实没有写过像这样的组件,只是跟着antd模仿写了几个组件而已,日常写业务都比较简单,也比较定制化。这次自己写起来第一个问题就是处理children的问题。 首先要思路清晰,什么样的才是符合条件的Banner子元素,其余的剔除掉。 还有就是最内层自定义内容的处理, 这部分有一点比较重要的就是css属性,其实所有组件都应该如此。给用户足够的自由去自定义组件的整体或部分的样式。 起始这个问题算是借鉴antd里面的处理方式,用户传入的参数一个不少的全都保留下来,并且对class做拼接,style做合并,但保证用户的优先级要更高。

实现2

当整体的结构固定下来之后(尽管代码还不完善), 就应该考虑主要需求了,

  • 图片转起来
  • 自动播放?
  • 播放顺序?
  • 每幅图片停留时间?

这里面要讲一下的就是图片转起来的方式。
然后想到两种方案。

  • 假设五张图片五张图片就横向排开,这样宽度就是500%, 然后动态的改变left, 容器overflow: hidden
  • 五张图片层叠堆起来,所占的位置就一个,不显示的就隐藏掉,这样好像dom结构更简单。

于是呢采用了第二种,简单啊。 5个元素的位置固定,控制visible就可以了。然后呢也确实简单。 那么下一个问题就是咋么播起来、转起来的问题了。

实现3

转起来那肯定是动画喽, 先抽象一下,大概有4个动画

  • 从中间向右 ---> 隐藏
  • 从中间向左 ---> 隐藏
  • 从右向中间 ---> 显示
  • 从左向中间 ---> 显示

然后呢, 思路也比较简单, js控制判断哪个图片要做哪个动画,然后为这个元素添加一个类, 然后再删掉这个类名就好了。

展示其中一个动画, 只控制了位置,控制透明度来增加渐入渐出是另外的类名,确保每个类作该做的事情。

@-webkit-keyframes moveToRight {
  from {
    -webkit-transform: translateX(0%);
  }
  to {
    -webkit-transform: translateX(100%);
  }
}

然后效果还不错。

bug1

之后呢发现如果快速点击就完蛋了, 容易出现js控制跟不上问题。 寻找问题在于上一个动画还没结束下一个动画就进来了。 之后做了一点思想斗争,是应该结束掉动画呢,还是让当前动画执行完呢。 其实实现起来都比较简单。 但还是让当前动画执行完毕吧, 考虑点主要有两个

  • 没个动画执行时间非常短只有几百毫秒 正常状况下 除非用户疯狂点击,一般不会出现乱动的问题
  • 动画如果执行一半就立即切换状态 生硬

综合这两点,给每个Banner增加了一个是否在动画的状态flag来决定能不能继续添加动画。

总结

本想放一张gif图在这个位置,但无奈录屏了几次 都太大了。都要100M,可能是分辨率太高的问题。所以放一张手机拍的吧,效果不是很好。
gif
过去几个月也发布了几个小npm包

  • 格式检查 这个也一直在用,主要用于ajax前对数据进行格式检查,然后再提示用户是否正确。蛮好的
  • 数字转汉子 目前就应用过一次,虽然目前能达到需求,但内部逻辑日后还有很大改进空间
@zhaozy93 zhaozy93 changed the title 轮播图组件 react banner slider 轮播图组件 react banner slider(17-07-23) Jul 23, 2017
@zhaozy93 zhaozy93 mentioned this issue May 1, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant