慕课手机demo
学习了一下慕课手机展示页demo,于是自己跟着实现了一下
实现思路
- 采用BEM开发模式;
- 布局主要为 relative + absolute + float;
- 动画采用 css3 + js;
- 通过监听滚轮高度判断页面位置,设置相应的动画播放;
- 通过onmouseover、onmouseout事件监听鼠标在导航项之间的移动,设置nav-tip元素位置样式实现滑动门效果;
- 通过onclick事件判断鼠标所点击的导航项或侧边大纲项,设置滚轮高度移动到相应位置,通过判断滚轮位置设置相应导航项和大纲项样式,从而实现双向定位;
设置元素的动画初始样式、完成样式,过渡时间等。将要设置动画的元素以数组形式存放在screenAnimateElements对象中。在页面加载时,循环遍历这个对象为其中每个元素添加动画初始样式。判断滚轮高度,当页面滚动到相应部位时,设置相应导航项、大纲项的样式且播放相应屏的动画(通过为元素添加动画完成样式)。实现滑动门时,当鼠标移出,则判断此时页面位置(可以通过滚轮高度或循环查找导航项中的类是否包含我们设置的状态类),再设置滑动门到相应的导航项。
BEM模式
Bem 是块(block)、元素(element)、修饰符(modifier)的简写,由 Yandex 团队提出的一种前端 CSS 命名方法论。使用BEM能清晰的看懂html code,明白元素之间的联系。规则:
- 中划线 - :仅作为连字符使用,表示某个块或者某个子元素的多单词之间的连接记号。
- 双下划线 __ :双下划线用来连接块和块的子元素
- 单下划线 _ :单下划线用来描述一个块或者块的子元素的一种状态
注意:
- 模块不应该影响外部,即不该为模块设置边框、大小、定位等;
- 模块之间、元素之间可以彼此嵌套;
- 一个元素是一个可选的模块组件。并不是所有的模块都必须有元素;
- 一个Block下的所有Element无论相互层级如何,都要摊开扁平的属于Block。因此,block__elem1__elem2这样的命名是不规范的
- 当这段代码可能被重用,并且它不依赖于页面上的其他组件,应该创建一个模块;
- 当这段代码在没有父实体(模块)的情况下不能使用,应该创建一个元素;
获取滚轮高度
本来我用的是 document.body.scrollTop 来获取滚轮高度,但没效果,alert发现取值为0。于是改用了 document.documentElement.scrollTop ,成功。查了一下发现有兼容的问题。在不同的浏览器中,有些能识别document.body.scrollTop,有些能识别document.documentElement.scrollTop。)。但为了兼容,可以这样:
var top = document.body.scrollTop + document.documentElement.scrollTop;
// 一个有值时另外一个就会为 0
或
var top = document.documentElement.scrollTop || document.body.scrollTop;
或
var top = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop;
还可以用 window.pageYOffset 来获取。
关于href
测试侧边大纲时,不论我点击哪一项,都会跳转回首屏。回去检查html发现我把大纲项 a 标签的 href 空着。
- <a href=""> 点击会刷新页面,相当于访问当前URL;
- <a href="#"> 会保留a标签的表现,点击时会跳到首屏,因为#是用来跳转到锚点的,这样写默认表示<a href="#top">
- <a href=“javascript:;”>链接表示当点击这个a标签时,执行javascript后面的语句,但是为空,就说明没有任何改变;
- <a href=“javascript:void(0);”>链接表示点击时执行void(0)这句话,返回值为undefined,也是没有任何改变。
第一屏动画的设置
由于是根据滚轮高度来播放动画,那么在刚打开页面时,滚轮高度为0,第一屏呈现动画初始化状态,影响体验。因此,默认初始化第一屏动画,在页面加载时跳过第一屏。再为第一屏动画的播放设置一个定时器,否则将看不到动画效果。这样,我们一打开页面的时候就会看见第一屏动画播放。
圆点指向的圆点动画效果
这里用一个静态的圆点指向图片,再利用::before、::after生成一个圆(利用border-radius),调整它们的位置到与圆点重叠,设置缩放的动画效果,再设置不用的时间,这样看起来圆点就在不停“跳跃”了。
其实圆点图片也可以用css实现,一个div变成圆,一个div变成指向边(利用linear-gradients,从红色渐变到背景色),设置它们的位置。