轮播图
html:
<div id="my-slider" class="slider-list">
<ul>
<li class="slider-list__item--selected">
<img src="https://p5.ssl.qhimg.com/t0119c74624763dd070.png"/>
</li>
<li class="slider-list__item">
<img src="https://p4.ssl.qhimg.com/t01adbe3351db853eb3.jpg"/>
</li>
<li class="slider-list__item">
<img src="https://p2.ssl.qhimg.com/t01645cd5ba0c3b60cb.jpg"/>
</li>
<li class="slider-list__item">
<img src="https://p4.ssl.qhimg.com/t01331ac159b58f5478.jpg"/>
</li>
</ul>
</div>
css
#my-slider{
position: relative;
width: 790px;
}
.slider-list ul{
list-style-type:none;
position: relative;
padding: 0;
margin: 0;
}
.slider-list__item,
.slider-list__item--selected{
position: absolute;
transition: opacity 1s;
opacity: 0;
text-align: center;
}
.slider-list__item--selected{
transition: opacity 1s;
opacity: 1;
}
js
class Slider{
constructor(id){
this.container = document.getElementById(id);
this.items = this.container
.querySelectorAll('.slider-list__item, .slider-list__item--selected');
}
getSelectedItem(){
const selected = this.container
.querySelector('.slider-list__item--selected');
return selected
}
getSelectedItemIndex(){
return Array.from(this.items).indexOf(this.getSelectedItem());
}
slideTo(idx){
const selected = this.getSelectedItem();
if(selected){
selected.className = 'slider-list__item';
}
const item = this.items[idx];
if(item){
item.className = 'slider-list__item--selected';
}
}
slideNext(){
const currentIdx = this.getSelectedItemIndex();
const nextIdx = (currentIdx + 1) % this.items.length;
this.slideTo(nextIdx);
}
slidePrevious(){
const currentIdx = this.getSelectedItemIndex();
const previousIdx = (this.items.length + currentIdx - 1)
% this.items.length;
this.slideTo(previousIdx);
}
}
const slider = new Slider('my-slider');
链接:JS Bin - Collaborative JavaScript Debugging
行为:控制流
使用自定义事件来解耦。
总结:基本方法
-
结构设计
-
展现效果
-
行为设计
- API(功能)
- Event(控制流)
JS Bin - Collaborative JavaScript Debugging
重构:插件化
解耦
- 将控制元素抽取成插件
- 插件与组件之间通过依赖注入方式建立联系
重构:模板化
解耦
- 将HTML模板化,更易于扩展
重构:组件框架
抽象
- 将通用的组件模型抽象出来
总结
组件设计的原则:封装性,正确性,扩展性,复用性
实现组件的步骤:结构设计,展现效果,行为设计
三次重构:插件化,模板化,抽象化(组件框架)
高阶函数
- 以函数作为参数
- 以函数作为返回值
- 常用于作为函数装饰器
function H0F0(fn){
return function(..args){
return fn.apply(this, args);
}
}
常用高阶函数
- Once——code.h5jun.com/zoqop
- Throttle——code.h5jun.com/gale
- Debounce——code.h5jun.com/wik
- Consumer / 2——code.h5jun.com/roka,code.h5jun.com/kapef
- Iterative——code.h5jun.com/bucu
为什么使用高阶函数
纯函数适合用于单元测试,与外部环境和执行顺序无关,系统稳定性和可靠性得到提高
编程范式
命令式
let list = [1, 2, 3, 4];
let map1 = [];
for(let i = 0; i < list.length; i++){
map1.push(list[i] * 2);
}
声明式
let list = [1, 2, 3, 4];
const double = x = > x * 2;
list.map(double);
例子
Toggle——命令式——code.h5jun.com/tuda
Toggle——声明式——code.h5jun.com/nal
Toggle——三态门——code.h5jun.com/foqo
1.防抖动函数
假设delay为1秒
在单位时间 (> 1)内 事件触发的间隔时间小于 1 秒的都不执行
function doubounce (func,delay){
let timer = null
return function(...args){
if(timer) clearTimeout(timer)
timer = setTimeout(()=>{
func.apply(this,args)
},delay)
}
}
2.节流函数
在单位时间 (>1)内 不论事件触发多少次都只会在1秒后执行一次
function throttle(func,delay){
let timer
return function(...args){
if(!timer){
timer = setTimeout(() => {
timer = null
func.call(this,args)
}, delay);
}
}
}