总结:
1.匿名函数使用
(function(global){})(window) //封装插件,避免全局变量
(function(global,$){})()
复制代码
扩展:$(function(){ ... })
jqeruy中的写法等于js中window.onload = funtion(){ ... }
2.ES6中的CLASS使用
class Slide{
constructor(opts){
this.x = opts.x;
...
this.init();
}
init(){
...
}
}
var slide = new Slide(opts); //实例化
复制代码
2.1
utils.js中的var utils 使用es6的语法 export default utils
slide_2.js中调用import utils from "./utils.js"
ps:原生的浏览器是不知道import的,chrome 64版本后支持 不过需要使用时,如:<script type="module" src="./slide_2.js"></script>
添加type="module"
3.严格模式的使用"use strict"
4.生命周期写法具体实现:
(function(global,utils){
'use strict';
var Slide = funtion(opts){
this.x = opts.x;
...
this.initialization();
}
//只要可能操作的节点
Slide.Eles = {
body : 'body',
pre : '#pre',
...
}
//数组对象生成dom树
Slide.getDom = {
{tag:'div',class:'slide-wrapper',children:[
{tag:'div',class:'slide-viewport',children:[
{tag:'ul',class:'slide-panel'}
]}
]}
}
//通过原型使用
Slide.prototype = {
constructor : Slide,//保证原型链指向正确
initialization : () => {
this.setDom = utils.domTree(Slide.getDom); //obj生成Element节点
this.option(); //绘制Element时进行配置
this.drawHTML(this.id); //绘制Element到HTML中
this.bindEvent(this.fun); //绑定节点事件
}
option : () => { ... },
drawHTML : () => { ... },
bindEvent : function(e){
this.initializeElements(); //Slide.Eles的循环生成obj属性
e.pager && this.pagerEvent();
e.direction && this.directionEvent();
e.autoPlay && this.autoPlayEvent();
},
initializeElements : function () {
let eles = Slide.Eles;
for(let name in eles){
if(eles.hasOwnProperty(name)){
this[name] = utils.$(eles[name]);
}
}
}
}
global.Slide = Slide;//window全局变量
})(window,utils)
复制代码
生命周期写法的一种思考:通过class 中 oop 写法(slide_1.html) 和新的写法 (slide_2.html)进行对比 明显可扩展性和可读性更加高,灵活性也更好一点,不过对于小的插件或者轮子写起来也相对麻烦
这次写slide其实就复杂化了
4.1 数组对象生成无限深度节点
在utils.js可以看到domTree的使用
//对象类型
const data = [
{tag:'div', className:'slide-wrapper', title:'parent 1', children:[
{tag:'div',className:'slide-viewport', title:'parent 1-1', children:[
{tag:'div',className:'slide-panel', title: 'child 1-1-1'},
{tag:'div',className:'slide-panel', title: 'child 1-1-2', children:[
{tag:'div',className:'slide-panel', title: 'child 1-1-2-1'},
{tag:'div',className:'slide-panel', title: 'child 1-1-2-2'}
]}
]},
{tag:'div',className:'slide-viewport2', title:'parent 1-2', children:[
{tag:'div',className:'slide-panel2', title: 'child 1-2-1'}
]}
]}
]
function DrawElement(domObject) {
this.data = domObject
this.fragmentNode = document.createDocumentFragment()
this.init()
return this.fragmentNode
}
DrawElement.prototype = {
init() {
// count = -1 因为paddingLeft开始为count * 15px
this.render(this.data, this.fragmentNode, -1)
},
/**
* 绘制dom对象生成真实碎片节点
* @param {Object} recursiveObj - 递归dom对象
* @param {element} parentNode - 父节点对象element.
* @param {Number} count - 计数,用于计算paddingLeft
*/
render(recursiveObj, parentNode, count) {
count++
recursiveObj.forEach(item => {
let node = this.buildNode(item, count)
parentNode.appendChild(node)
if(item.children) {
this.render(item.children, node, count)
}
})
},
buildNode(item, index) {
let parent = document.createElement(item.tag),
chlidSpan = document.createElement("span")
this.setClassProp(chlidSpan, item, index)
parent.appendChild(chlidSpan)
return parent
},
setClassProp(element, item, index) {
element.textContent = item.title
element.className = item.className
element.style.paddingLeft = index * 15 + 'px'
}
}
复制代码
使用 document.getElementById('tree').appendChild(new DrawElement(data))