近来没有什么值得写的东西,空闲的时候帮前端的同学做了些大屏上的展示模块,就放在这里写写吧,手把手“需求->设计-> 实现”,受众偏新手向。

  

  为了直观便于理解, 直接把结果贴在上面。

  如上所示,基本需求比较简单明了, “分页显示供应商、供应占比列表,自动轮播”。

  一、需求评审

  该有的环节还是要有,尽管需求简单,评审不能省略,无论形式。开发的同学千万不要真的相信需求就这么简单,否则南辕北辙,出力不讨好,那必定是日常-_-||。

  于是有丰富填坑经验的开发同学,对于这个简单的模块需求,可能会提出如下的一些问题

  1. 如果只有一页,要不要轮播?

  2.每页的轮播间隔频率是多少?

  3.如果列表没有数据,如何显示这个模块?

  4.数据的刷新时机?是翻页刷新,轮播一圈刷新,还是其他?

  5.这个绿色的比值是什么含义? 是不是还有红色?

  6.百分比的小数位?

  7.如果接口异常比如网络不通,如何表示这种异常?

  8.供应商的名字会不会有500字那么长? 放不下如何布局?

  ……等等

  以上任何一个未明确的需求,都可能成为你编码完成后的一个bug或优化建议。 o(* ̄︶ ̄*)o。

  二、设计评审  

  关于上面待确认的每一个问题,我们伟大的产品经理都一一耐心的给出了“令人信服的”回答后。还是不能马上开始编码。下面我们需要进行一些技术方案的设计讨论,由技术leader把关。例如:

  1. 数据流,这个列表的数据,是从数据库中的哪几个表取出的? 确认下查询逻辑。

  2.接口设计,是一次返回前端所有数据,还是支持分页查询。

  3.性能考虑,查询频率是不是较高,并发是不是大,缺不缺索引,要不要上缓存?

  4.轮播如何实现? 有没有已经集成的轮播控件,是否满足要求,还是需要自己写一个。

  5.如何进行模块化开发,作为一个模块集成嵌入到整体页面中。

  ……等等

  明确了以上的问题后,作为前端同学的我,是不是可以开始撸代码了?

   

  三、想清楚再写

  说到这里,

  一类同学已经开始着手编码了, 第一个想到需要写的方法可能是,ajax 去后台请求数据列表的接口。

  另一类同学,可能仍在构思,如何组织代码,提炼主要的数据结构和功能方法。

  这里我们显然应该向“另外一类”同学学习。想清楚再写,是一个毫无疑问的好习惯

  技术预研

  实现一个功能,首先要扫除其中的未知技术点,扫除了所有未知之后,才能够优化的组织实现方案

  上面的需求对于我这种半吊子前端来说,比较关键的两个技术问题是。

  1)用什么方案来实现滑动动画。 2)如何实现“无限滚动”。

  滑动动画——经过一番百度,总结下动画可能的实现方案,包括用JS实现或者用CSS实现。 各有优劣,js 兼容性好,控制灵活;CSS性能高,平滑流畅。因为我们的动画非常线性,简单,于是这里我们决定采用CSS动画作为动画的实现方案。

  通过简单的研究,我们已经弄清楚了, 想让一个页面元素具有一个动画效果,可以通过向他添加一个包含了动画关键真的选择器来实现,比如定义一个滑出动画类,把这个css类加到元素上,元素就可以实现滑出的动画效果。

  无限滚动——思考下滚动页面,虽然对于数据来说可能会分成很多页,但对于屏幕展示来说,实际上最多同时出现两个页面,一个是前一页,一个是当前页。在不滚动的时候只有当前页需要显示。

  顺着这个思路, 滚动这个动作对应,“当前页飞入”“前一页飞出”这两个细分动作,特别的情况是,初始显示时,是没有“前一页”的。

  那么滚动这个动作大概思路就是,

  1. 根据当前页号取得对应数据,绘制HTML页面,append到滚动区域,对其添加“飞入”动画

  2. 根据当前页号取得上一页页面元素,对其添加“飞出”动画,动画结束后将其移除, 仅显示当前页。

  四、编码实现

  终于到了编码的时间了。

  用到的 css 动画类选择器,以及关键帧 

.slip_in_animation{
animation: slip_in 1s;
} .slip_out_animation{
animation: slip_out 1s;
} /*右侧滑入*/
@keyframes slip_in
{
from {transform:translateX(100%);}
to {transform:translateX(0);} } /*右侧滑入*/
@keyframes slip_out
{
from {transform:translateX(0);}
to {transform:translateX(-100%);}
}

  js应用于页面元素,飞入飞出, 飞出后删除,*动画在结束后并不会改变元素实际位置。所以要在动画结束前,移除元素,避免它回到之前位置,挡住当前页,发生“闪烁”

    //页面滑入,要显示的页面
this.slipIn = function(pageNo){
$("#supplierListPage_"+pageNo).addClass("slip_in_animation");
}; //页面滑出,
this.slipOut = function(pageNo){
$("#supplierListPage_"+pageNo).addClass("slip_out_animation"); //移除上一页,定时比动画稍短,避免闪烁
setTimeout(function(){
$("#supplierListPage_"+pageNo).remove();
},900);
};

  翻页的逻辑,第一次不滚动;滚到头,把最后一页飞出,第一页飞入。

    this.switchNext = function(pageNo){

        //附加生成新的页面
var newPageHtml = _this.makePageHtml(pageNo);
$("#"+ _this.containerId).append(newPageHtml); //多于一页的情况
if(_this.firtshow){
_this.firtshow= false;
//第一次换页 不需要移除之前页面。
}else{
//前面已经有显示过的页面,需要把前面的页面滚动出去。
var olderPage = pageNo -1;
if(olderPage <=0){
//当前页是第一个,前一页就是最后一页
olderPage = _this.totalPage;
}
_this.slipOut(olderPage);
}
_this.slipIn(pageNo);
};

  定时滚动到下一页。如果是最后一页,重新开始第一页。

    this.startRolling = function(){
_this.switchNext(_this.curPage); //按间隔轮播
_this.switchTimer = setInterval(function(){ if(_this.totalPage == 1)
return; if(_this.curPage < _this.totalPage) {
_this.curPage++;
}else{
_this.curPage = 1;
}
_this.switchNext(_this.curPage);
},_this.switchInterval);
};

写到这里,下面是完整代码,需要的可以参考。

完整的代码CSS:

.slip_in_animation{
animation: slip_in 1s;
} .slip_out_animation{
animation: slip_out 1s;
} /*右侧滑入*/
@keyframes slip_in
{
from {transform:translateX(100%);}
to {transform:translateX(0);} } /*右侧滑入*/
@keyframes slip_out
{
from {transform:translateX(0);}
to {transform:translateX(-100%);}
}

完整JS:

function SupplierListTable(){

    var _this = this;
//echart 图表对象。 //轮播间隔 毫秒
this.switchInterval = 5000; //当前轮播的页,从1开始
this.curPage=1; //每页条数
this.pageSize = 5; //当前数据对应总页数
this.totalPage = 0; //数据列表
this.chartDataList = new Array(); //第一次展示标志
this.firtshow =true; this.containerId = null;
//轮播定时器
this.switchTimer = null; this.init = function(containerId){
_this.containerId = containerId;
//初始化图表
$("#"+containerId).html("");
_this.reloadData(containerId);
}; this.getTotalPage = function(){
var totalPage = Math.ceil(_this.chartDataList.length/_this.pageSize);
return totalPage;
}; this.reloadData =function(containerId){ //从网络请求数据。 setTimeout(function(){ _this.chartDataList= [
{name:"供应商1",percent:"12%"},
{name:"供应商2",percent:"13%"},
{name:"供应商3",percent:"14%"},
{name:"供应商4",percent:"15%"},
{name:"供应商5",percent:"16%"},
{name:"供应商6",percent:"13%"},
{name:"供应商7",percent:"14%"},
{name:"供应商8",percent:"15%"},
{name:"供应商9",percent:"16%"} ]; _this.totalPage = _this.getTotalPage();
_this.curPage = 1; _this.stopRolling();
_this.startRolling(); },300); }; this.stopRolling= function(){
if(_this.switchTimer != null){
clearInterval(_this.switchTimer);
_this.switchTimer = null;
_this.curPage = 0;
}
}; this.startRolling = function(){
_this.switchNext(_this.curPage); //按间隔轮播
_this.switchTimer = setInterval(function(){ if(_this.totalPage == 1)
return; if(_this.curPage < _this.totalPage) {
_this.curPage++;
}else{
_this.curPage = 1;
}
_this.switchNext(_this.curPage);
},_this.switchInterval);
}; this.switchNext = function(pageNo){ //附加生成新的页面
var newPageHtml = _this.makePageHtml(pageNo);
$("#"+ _this.containerId).append(newPageHtml); //多于一页的情况
if(_this.firtshow){
_this.firtshow= false;
//第一次换页 不需要移除之前页面。
}else{
//前面已经有显示过的页面,需要把前面的页面滚动出去。
var olderPage = pageNo -1;
if(olderPage <=0){
//当前页是第一个,前一页就是最后一页
olderPage = _this.totalPage;
}
_this.slipOut(olderPage);
}
_this.slipIn(pageNo);
}; //生成指定页的html。
this.makePageHtml = function(pageNo){ var startRecIndex= _this.pageSize * (pageNo - 1);
var endRecIndex = _this.pageSize * pageNo ; if(endRecIndex > _this.chartDataList.length){
endRecIndex = _this.chartDataList.length;
} var html = "<div style='width: 100%; box-sizing: border-box;position: absolute;padding: 20px;' id='supplierListPage_" +pageNo+"'>";
for (var i = startRecIndex; i < endRecIndex; i++) {
html+= "<div style=' margin-bottom: 10px ;border-bottom: 1px solid #484752;'><span style='color: white'>" +_this.chartDataList[i].name+"</span> <span style='float: right;color: #0c9c6e'>"+_this.chartDataList[i].percent+"</span></div>"
}
html+="</div>" return html;
}; //页面滑入,要显示的页面
this.slipIn = function(pageNo){
$("#supplierListPage_"+pageNo).addClass("slip_in_animation");
}; //页面滑出,
this.slipOut = function(pageNo){
$("#supplierListPage_"+pageNo).addClass("slip_out_animation"); //移除上一页,定时比动画稍短,避免闪烁
setTimeout(function(){
$("#supplierListPage_"+pageNo).remove();
},900);
}; } $(document).ready(function(){ var containerId = 'supplierListChart'; var supplierListTable = new SupplierListTable();
supplierListTable.init(containerId); });

HTML页面容器:

<div  style="height: 300px;width:400px;overflow-x: hidden;position: relative" id="supplierListChart" >
</div>

前端开发日常——CSS动画无限轮播的更多相关文章

  1. css动画属性--轮播图效果

    通过css的动画属性实现轮播图的显示效果 代码如下: 主体部分: <div id="move"> <ul> <li><img src=&q ...

  2. iOS开发UI篇—无限轮播(功能完善)

    iOS开发UI篇—无限轮播(功能完善) 一.自动滚动 添加并设置一个定时器,每个2.0秒,就跳转到下一条. 获取当前正在展示的位置. [self addNSTimer]; } -(void)addNS ...

  3. iOS开发UI篇—无限轮播(循环利用)

    iOS开发UI篇—无限轮播(循环利用) 一.无限轮播  1.简单说明 在开发中常需要对广告或者是一些图片进行自动的轮播,也就是所谓的无限滚动. 在开发的时候,我们通常的做法是使用一个UIScrollV ...

  4. iOS开发UI篇—无限轮播(新闻数据展示)

    iOS开发UI篇—无限轮播(新闻数据展示) 一.实现效果        二.实现步骤 1.前期准备 (1)导入数据转模型的第三方框架MJExtension (2)向项目中添加保存有“新闻”数据的pli ...

  5. iOS开发UI篇—无限轮播(循环展示)

    iOS开发UI篇—无限轮播(循环展示) 一.简单说明 之前的程序还存在一个问题,那就是不能循环展示,因为plist文件中只有五个数组,因此第一个和最后一个之后就没有了,下面介绍处理这种循环展示问题的小 ...

  6. ViewPager无限轮播与自定义切换动画

    一直在寻求一个能用得长久的ViewPager,寻寻觅觅终于发现,ViewPager有这一个就够了. 注:并非完全原创 先看一下效果: 淡入淡出: 旋转: 无限轮播的ViewPager 主要设计思路(以 ...

  7. iOS项目开发之实现无限轮播

    简介 分析 实现 代码下载 一.简介 在实际的开发当中,会经常有界面需要实现图片的无限轮播这样的需求.比如新闻app,或者其他app的广告位 实现的方式有很多种,最先想动的一定是scrollView, ...

  8. iOS开发之三个Button实现图片无限轮播(参考手机淘宝,Swift版)

    这两天使用Reveal工具查看"手机淘宝"App的UI层次时,发现其图片轮播使用了三个UIButton的复用来实现的图片循环无缝滚动.于是乎就有了今天这篇博客,看到“手机淘宝”这个 ...

  9. Android之仿京东淘宝的自动无限轮播控件

    在App的开发中,很多的时候都需要实现类似京东淘宝一样的自动无限轮播的广告栏,所以就自己写了一个,下面是我自定义控件的思路和过程. 一.自定义控件属性 新建自定义控件SliderLayout继承于Re ...

随机推荐

  1. 分享俩个js数组比较少用的方法join与from

    1:array.join 用于将数组中的所有元素转化为字符串 例: var arr = ["one", "two", "four"]; va ...

  2. Spring AOP全面详解(超级详细)

    如果说 IOC 是 Spring 的核心,那么面向切面编程AOP就是 Spring 另外一个最为重要的核心@mikechen AOP的定义 AOP (Aspect Orient Programming ...

  3. Chapter 09 - NSUndoManager (C#实现 + 全网原创)

    此例子针对NSDocument实现了tableview 每一行添加/删除的undo/redo,以及每一个单元格内容编辑的undo/redo.基于NSDocument类的实现.PersonModel + ...

  4. zkw线段树——简单易懂好写好调的线段树

    0.简介 zkw线段树是一种非递归线段树,与普通线段树不同的是,它是棵标准的满二叉树,所以遍历过程可全程使用位运算,常数一般比线段树小得多. 1.结构/建树 前面说了,zkw线段树是满二叉树,可是原数 ...

  5. 【Java】学习路径57-TCP协议客户端与服务器端的关闭

    在TCP协议中,如果发送端(客户端)关闭了,那么接收端(服务器端)端就会收到这个消息. 那么接收端(服务器端)怎么知道的呢? 我们进行实验: 首先在发送端中编写一段程序,当用户输入"end& ...

  6. 02_Django-路由配置-HTTP协议的请求和响应

    02_Django-路由配置-HTTP协议的请求和响应 视频:https://www.bilibili.com/video/BV1vK4y1o7jH 博客:https://blog.csdn.net/ ...

  7. KingbaseES 参数 - ora_statement_level_rollback

    参数 ora_statement_level_rollback 控制KingbaseES 是否实现类似oracle 语句级的回滚.当该参数打开时,如果事务操作失败,仅会回滚最后一条操作,避免了全部操作 ...

  8. HBase原理深入

    HBase 读写数据流程 Hbase 读数据流程 首先从 zk 找到 meta 表的 region 位置,然后读取 meta 表中的数据,meta 表中存储了用户表的 region 信息 根据要查询的 ...

  9. Go语言学习的坑爹历程

    鄙人暑期实习,需要用Go语言进行编程 在go语言中,结构体的定义只支持变量的声明,成员函数是采用"接口方法"来实现的 留一个成员定义的模板在此 package main impor ...

  10. Git Rebase-提交整洁之道

    git rebase git rebase是一个非常有用的命令,但知道和用的人非常少,今天介绍一下其作用 git rebase -i 作用:常用来合并多个相同目的的提交. 交互式有下面几个命令,常用命 ...