前面我们通过[《css布局简史与决胜未来的第四代css布局技术》](https://segmentfault.com/a/1190000015782763)了解了css布局发展史和未来,下面,我们通过[《使用flex进行网易云音乐界面构建和布局解析》](https://segmentfault.com/a/1190000015846688)了解一下,如何在实际项目中使用flex进行布局,相信大家也体会到了它的便捷之处。今天我们就深入项目的细节,说说每一个切图人员绕不过去的坎儿,也是jser必须要面对的一个常规任务--《网易云音乐高复用的响应式轮播图的实现》

轮播图相对于大家的工作,就和你首次去女朋友家的准备工作一样,重要而且绕不过去。遗憾的是,大部分人写轮播图都跟第一次见家长一样,没什么经验。

很多人想自己写一套轮播图,然后以后工作中不断的完善,最后形成自己的插件库,遗憾的是有这个想法的大部分人,到了行动的时候才发现,想要实现它,比兑现“结婚就买套房”的诺言都难。最后只好迫于项目压力和自身技能水平,变成了插件的搬运工。

可是插件搬运工有三个问题,首先这个东西对一个人的技术成长没什么用,其次也是重点,插件并不能完全符合项目需求,自己又没有能力进行二次开发,遇上诡异bug也只能听天由命,继续踏上寻找更合适的插件的慢慢征途。最后,有些插件很重,很臃肿,但你只需要的是最基础的轮播功能而已。你会为了吃上一碟醋,专门包顿饺子吗?我想不会。那你为什么仅仅为了使用一个轮播图会而项目里面使用几百k甚至上M的插件?

很多人可能会说因为不会写,好,今天我们就来实现一个,你会发现原来js的世界如此的简单和美好,有找插件的功夫,你都能开发出8个插件了。

往上看,大家都认的啥叫轮播图,仔细看下你第一步要做的至少说我拖着一个东西得能动,哪怕是一个红色方块呗。这里就得说下拖拽,拖拽改变的无非就是left和top值(外星人才改right和bottom,我们地球人一般都用left和top,别问我为什么),先让他在一个方向上动起来。

```

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>

<style>

#div1 {

width: 100px;

height: 100px;

position: absolute;

left: 50px;

top: 50px;

background: red;

}

</style>

<script>

document.addEventListener("DOMContentLoaded", function () {

var oDiv = document.getElementById('div1');

var disX = 0;

oDiv.addEventListener("touchstart", function (e) {

var startPoint = e.changedTouches[0].pageX;

var startLeft = oDiv.offsetLeft;

disX = startPoint - startLeft;

});

oDiv.addEventListener("touchmove", doMove,false);

function doMove(e) {

var currPoint = e.changedTouches[0].pageX;

var newLeft  = currPoint - disX;

oDiv.style.left = newLeft +'px';

}

function doUp(e) {

var currPoint = e.changedTouches[0].pageX;

var newLeft  = currPoint - disX;

oDiv.style.left = newLeft +'px';

oDiv.removeEventListener("touchmove", doUp,false);

oDiv.removeEventListener("touchend", doUp,false);

}

oDiv.addEventListener("touchend", doUp,false);

}, false);

</script>

</head>

<body>

<div id="div1"></div>

</body>

</html>

```

仔细看,无非就是用了移动端事件而已,分分钟就能理解,问题是很多同学会说,老师,我不理解这里,这是啥,

```

var currPoint = e.changedTouches[0].pageX;

var newLeft  = currPoint - disX;

oDiv.style.left = newLeft +'px';

```

**这个又是啥?**

```

var currPoint = e.changedTouches[0].pageX;

var newLeft  = currPoint - disX;

oDiv.style.left = newLeft +'px';

oDiv.addEventListener("touchmove", doUp,false);

oDiv.addEventListener("touchend", doUp,false);

```

其实这些就是核心内容,简单的说就是一张图,非常简单的图,**你一看就能懂。**

其实就是算蓝线的距离只要蓝线正确,位置就错不了,真要是理解不了也没事,你就把他当成公式记住一点毛病也没有。有了这些基础知识就好办了,搭个架子,

```

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

<style>

* {

margin: 0;

padding: 0;

}

li {

list-style: none;

}

.swiper-container {

width: 320px;

height: 130px;

position: relative;

margin: 20px auto;

overflow: hidden;

}

.swiper-container .swiper-wrapper {

width: 2240px;

height: 130px;

position: absolute;

left: 0px;

}

.swiper-container .swiper-wrapper img {

width: 320px;

height: 130px;

float: left;

display: block;

}

.swiper-container ul {

width: 35px;

height: 4px;

position: absolute;

bottom: 10px;

left: 50%;

margin-left: -15px;

}

.swiper-container ul li {

width: 4px;

height: 4px;

border-radius: 2px;

border: 0.25px solid #fff;

margin-left: 2.5px;

background: #666;

float: left;

cursor: pointer;

}

.swiper-container ul .active {

background: #fff;

}

.swiper-container ul li:hover {

background: #fff;

}

</style>

</head>

<body>

<div class="swiper-container">

<div class="swiper-wrapper">

<img src="data:images/4.jpg">

<img src="data:images/0.jpg">

<img src="data:images/1.jpg">

<img src="data:images/2.jpg">

<img src="data:images/3.jpg">

<img src="data:images/4.jpg">

<img src="data:images/0.jpg">

</div>

<ul>

<li class="active"></li>

<li></li>

<li></li>

<li></li>

<li></li>

</ul>

</div>

<script>

document.addEventListener("DOMContentLoaded", function () {

var oSWiperContainer = document.querySelector(".swiper-container");

var oSWiperWrapper = document.querySelector(".swiper-container .swiper-wrapper");

var aImg = document.querySelectorAll(".swiper-container .swiper-wrapper img")

var aLi = document.querySelectorAll(".swiper-container ul li");

oSWiperContainer.addEventListener("touchstart", function (e) {

var disX = 0;

var startPoint = e.changedTouches[0].pageX;

var startLeft = oSWiperWrapper.getBoundingClientRect().left;

disX = startPoint - startLeft;

oSWiperContainer.addEventListener("touchmove", doMove, false);

oSWiperContainer.addEventListener("touchend", doUp, false);

function doMove(e) {

var currPoint = e.changedTouches[0].pageX;

var newLeft = currPoint - disX;

oSWiperWrapper.style.left = newLeft + 'px';

}

function doUp(e) {

oSWiperContainer.removeEventListener("touchmove", doUp, false);

oSWiperContainer.removeEventListener("touchend", doUp, false);

}

}, false);

}, false);

</script>

</body>

</html>

```

至少现在一拖拽走起来了,这里简单吧,连纵向都不用考虑,轮播比拖拽还简单,只考虑水平方向,

问题是松手了以后,轮播图的,每一项没去正确的位置,啥叫正确的位置,其实每次改变的left的值将好是一个轮播图的宽度,上图。

你先别管别的,看红框就是手机屏幕宽度,每次其实就是移动一个格子。那我只要定一个iNow值记录移动几个格子,只要iNow正确就一切OK了呗,说干就干。

```

<!DOCTYPE html>

<html>

<head>

<meta charset="utf-8">

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

<style>

* {

margin: 0;

padding: 0;

}

li {

list-style: none;

}

.swiper-container {

width: 320px;

height: 130px;

position: relative;

margin: 20px auto;

overflow: hidden;

}

.swiper-container .swiper-wrapper {

width: 2240px;

height: 130px;

position: absolute;

left: 0px;

transition: .3s all ease;

}

.swiper-container .swiper-wrapper img {

width: 320px;

height: 130px;

float: left;

display: block;

}

.swiper-container ul {

width: 35px;

height: 4px;

position: absolute;

bottom: 10px;

left: 50%;

margin-left: -15px;

}

.swiper-container ul li {

width: 4px;

height: 4px;

border-radius: 2px;

border: 0.25px solid #fff;

margin-left: 2.5px;

background: #666;

float: left;

cursor: pointer;

}

.swiper-container ul .active {

background: #fff;

}

.swiper-container ul li:hover {

background: #fff;

}

</style>

</head>

<body>

<div class="swiper-container">

<div class="swiper-wrapper">

<img src="data:images/1.jpg">

<img src="data:images/2.jpg">

<img src="data:images/3.jpg">

<img src="data:images/4.jpg">

</div>

<ul>

<li class="active"></li>

<li></li>

<li></li>

<li></li>

<li></li>

</ul>

</div>

<script>

document.addEventListener("DOMContentLoaded", function () {

var oSWiperContainer = document.querySelector(".swiper-container");

var oSWiperWrapper = document.querySelector(".swiper-container .swiper-wrapper");

var aImg = document.querySelectorAll(".swiper-container .swiper-wrapper img")

var aLi = document.querySelectorAll(".swiper-container ul li");

var iNow = 0;

var oW = aImg[0].offsetWidth;

oSWiperContainer.addEventListener("touchstart", function (e) {

var disX = 0;

var startPoint = e.changedTouches[0].pageX;

var startLeft = oSWiperWrapper.getBoundingClientRect().left;

disX = startPoint - startLeft;

oSWiperContainer.addEventListener("touchmove", doMove, false);

oSWiperContainer.addEventListener("touchend", doUp, false);

function doMove(e) {

var currPoint = e.changedTouches[0].pageX;

var newLeft = currPoint - disX;

oSWiperWrapper.style.left = newLeft+'px';

}

function doUp(e) {

var endPoint = e.changedTouches[0].pageX;

if(endPoint-startPoint>50){

iNow--;

if(iNow==-1){

iNow = 0;

}

oSWiperWrapper.style.left = -iNow*oW+'px';

}

if(endPoint-startPoint<-50){

iNow++;

if(iNow==aImg.length){

iNow = aImg.length -1;

}

oSWiperWrapper.style.left = -iNow*oW+'px';

}

oSWiperContainer.removeEventListener("touchmove", doMove, false);

oSWiperContainer.removeEventListener("touchend", doUp, false);

}

}, false);

}, false);

</script>

</body>

</html>

```

强调一点,getBoundingClientRect(),这里我为什么没用offsetLeft呢?因为实际项目里面不可能轮播图的外层什么都不套,或者说万一有margin、padding,轮播图的距离就不对了,使用offsetLeft是不具有项目的实用性的,做演示还行,实际项目那么写就废了。

最后我说一个无限轮播图,其实就是算数字的

所谓无限轮播的原理,就是当iNow 等于最右边的0的时候,拉回到红框位置,左侧是当iNow 等于 最左边的4的时候,iNow等于6.

很多人有了源代码就忽略了基础的学习,直接拿过去用了,那跟直接找插件没区别,所以这个就当一个小练习吧。

四个练习:

1.实现多屏幕相应适配

2.实现无线轮播

3.实现如果滑动距离不超过50px就不播下一张

4.实现定时器自动轮播!

这里我把上面四个练习解决方法的左侧代码放出来作为提示,大家尽量学会实现。

注意学习是一个过程,不是一个结果,得到最终的源码不重要,学会自己实现这个才重要,毕竟网上有太多的资源和插件代码,如果那个有用,那么每一个人的工资都应该非常高才对。那为什么很多人的技术水平并不高,工资也不理想呢,是因为大家只努力去得到结果,而忽视了技术的实现过程。端盘子和吃菜谁都会,但是饭店却只会给厨师高工资就是这个道理。我们要做的是厨师,不是端盘子的服务员或者食客(此处仅为了说明过程的重要性,无其他意思)。

就说这么多吧,最后一句。牛顿说过,我有一个苹果我吃了你瞅着我就比你幸福,错了牛顿说他没说过这句话,他说的是,我有一个思想,你也有一个,咱俩一交换,就又生一个思想(牛顿好像大意如此,大家理解就OK)。

所以大家有问题可以留言,根据大家的留言我会提供更有针对性的课程。

使用flex进行网易云音乐界面构建和布局解析(2)相关推荐

  1. 用flex进行网易云音乐界面构建和布局解析(2)

    前面我们通过<css布局简史与决胜未来的第四代css布局技术>了解了css布局发展史和未来,下面,我们通过<使用flex进行网易云音乐界面构建和布局解析>了解一下,如何在实际项 ...

  2. Linux---Ubuntu18.04.03系统安装网易云音乐(解决2.5K屏网易云音乐界面字体过小问题)

    1.网易云官网下载Linux版本的软件包 https://music.163.com/#/download 下载安装即可. 打开网易云软件(版本1.2.1): netease-cloud-music ...

  3. 仿照网易云音乐界面 android特效

    2019独角兽企业重金招聘Python工程师标准>>> 仿照网易云音乐界面 ,页面UI实现的听不错的,学习ui的朋友可以下载下来研究研究,android特效更多学习. 项目大体框架, ...

  4. 高仿网易云音乐界面 android特效

    仿照网易云音乐界面 ,页面UI实现的听不错的,学习ui的朋友可以下载下来研究研究, 项目大体框架,由ViewPager和TabContentPagerAdapter实现顶部的左右滑动切换view. 右 ...

  5. linux的网易云音乐界面不显示图片,网易云音乐Linux 1.2.0有一些问题,附出现libfribidi.so.0的解决...

    网易云音乐Linux 1.2.0已经推出并提供了deb包下载,由于是和Deepin联合开发的,所以支持了Deepin 64位和主流的Ubuntu 18.04 64位操作系统(参考:网易云音乐Linux ...

  6. 网易云音乐App 音频会话管理解析

    点击"开发者技术前线",选择"星标????" 让一部分开发者看到未来 导读:WebRTC(Web Real-Time Communication)是一个支持网页 ...

  7. Qt 实现PC端网易云音乐界面

    闲暇时间持续开发中,目前只是做了很小的一部分.欢迎大家提供想法和交流... github: https://github.com/FlyWM/MumuMusic

  8. linux的网易云音乐界面不显示图片,网易云音乐1.2.0(build 0408) 有时候界面会变成白屏,变为完全无响应状态...

    今天抓到了crash堆栈,但是看不懂,不知道如何做才能提供更多信息 widon@widon-deepin:~$ netease-cloud-music [00007f8aa0005450] acces ...

  9. axure如何实现跳转_Axure教程:网易云音乐首页原型设计

    作者利用Axure动态面板功能对网易云音乐首页进行了一个简单的原型设计,那如何利用Axure动态面板功能实现轮播效果及交互功能以及隐藏丑陋的滚动条呢?下面来和我一起研究一下~ 制作示例如下: 网易云音 ...

最新文章

  1. 深入浅出Yolo系列之Yolov3amp;Yolov4核心基础知识完整讲解
  2. 永不丢失照片:防弹照片备份的完整指南
  3. 在Java里面使用instanceof的性能影响
  4. java中isolate时间_Java HikariDataSource.setIdleTimeout方法代码示例
  5. flex布局的一点注意点
  6. Python __all__的作用
  7. Chrome浏览器扩展开发系列之一:初识Google Chrome扩展
  8. G - Periodic Strings (周期串)
  9. Uber 踉跄上市、Facebook 要被拆分?!| 一周热闻回顾
  10. ecshop退出登录会清空购物车的bug优化,最完美解决方法
  11. L1-014 简单题 (5 分)—团体程序设计天梯赛
  12. Error connecting to database: No such file or directory
  13. 关于调用Thread.sleep() 哪条线程休眠问题
  14. log4cplus指南
  15. 计算机求和公式IFEROR,IFERROR函数详解_Excel公式教程
  16. WIN7系统 提示缺少msvcr120.DLL,msvcr110.DLL的 请戳这里。
  17. 车金融|我在M公司的那两年
  18. 全自动苹果CMS火车头采集器,苹果CMS火车头发布插件
  19. 一条命令轻松调节mac鼠标移动速度
  20. 谷歌搜索结果在新标签页中打开

热门文章

  1. 卷积神经网络特征图可视化热图可视化
  2. 强人教你吃自助火锅(转载)
  3. Mybatis实现自定义分页插件
  4. 阿里入股优酷=几乎买下了半个中国互联网?
  5. curl常见用法以及查看响应时间
  6. nginx设置超时响应时间
  7. 日语初学者会话100句
  8. 全国城市空气质量实时数据(PM2.5)实时下载
  9. 心脏滴血漏洞HeartBleed CVE-2014-0160深入代码层面的分析
  10. 游戏信息不存在 网站后台没有创建游戏