标签:
1 function CreateList() { 2 this.oWrap = document.createElement("div"); 3 this.copyright = document.createElement("div"); 4 this.initialize.apply(this, arguments); 5 /** 6 arguments就是构造函数接受的参数,构造函数调用时 7 new CreateList(aData[])传入的是一个数组 8 数组的每一个项都是json对象 9 json对象的格式为 10 project:[ 11 { 12 text:"测试文字", 13 }, 14 { 15 text:"测试文字", 16 href:"" 17 } 18 ] 19 每一个project数组的项对应一个DL----(对应无序列表的ul)-----自定义列表dl---dt--dd 20 21 22 23 24 */ 25 this.click.call(this) 26 } 27 CreateList.prototype = {//对CreateList的的函数进行定义 28 initialize: function(aData) { 29 var oDl, oElem, project, i; 30 while(aData[0]) {//解析arguments的数据,赋给各局部变量 31 oDl = document.createElement("dl"); 32 project = aData[0].project; 33 for(i = 0; i < project.length; i++) {//遍历project数组 34 if(project[i].href) { 35 /*project数组中,有href的保存为"dd",并用innerHTML加上标签<a href="project[i].href" target="_blank" 36 target参数为_blank意思是打开新窗口 37 */ 38 oElem = document.createElement("dd"); 39 oElem.innerHTML = i + ") <a href=\"" + project[i].href + "\" target=\"_blank\">" + project[i].text + "</a>" 40 } 41 else { 42 /** 43 没有href属性时,保存为dt 44 并在dt里面添加project[i].text + " (" + (project.length - 1) + ")" !! 45 oElem.innerHTML = project[i].text + " (" + (project.length - 1) + ")" 46 */ 47 oElem = document.createElement("dt"); 48 oElem.innerHTML = project[i].text + " (" + (project.length - 1) + ")" 49 } 50 oDl.appendChild(oElem);//for循环内,每次创建好一个dt或者dd,就append进oDL 51 oDl.style.height = "31px";//将当前创建好的dl高度设置为31px 52 } 53 this.oWrap.appendChild(oDl);//for循环外,dl已经创建好了,将其加入外层DIV也就是oWrap 54 aData.shift();//将arguments[0],也就是传进的第一个大参数json数组的第一项删除 55 //这样可以保证while(aDate[0])下一次循环时读取到的是最新的数据 56 } 57 this.oWrap.id = "wrap"; 58 this.copyright.id = "copyright"; 59 this.copyright.innerHTML = "\u539f\u751fJavaScript\u5b66\u4e60, QQ:21314130, By — Ferris 京ICP备10209901号"; 60 document.body.appendChild(this.oWrap); 61 document.body.appendChild(this.copyright) 62 }, 63 click: function() { 64 var that = this; 65 //console.log(this.tagName); 66 this.oWrap.onclick = function(event) { 67 //console.log(this.tagName); 68 69 var oEv, oTarget, oParent, i; 70 oEv = event || window.event; 71 oTarget = oEv.target || oEv.srcElement;//当前点击的元素 72 oParent = oTarget.parentElement || oTarget.parentNode;//当前点击元素的父元素 73 oParent.height = function() { 74 var iHeight = 0; 75 for(i = 0;i < oParent.children.length; i++) iHeight += oParent.children[i].offsetHeight; 76 return iHeight 77 }();//获取当前点击元素的父元素的height 78 79 80 if(oTarget.tagName.toUpperCase() == "DT") {//当点击的是dt时执行以下代码,此时oParent是dl 81 //oTarget是dt,而dt的父级元素就是dl 82 var aSiblings = that.siblings(oParent), count, i;//获取dl所有的aSiblings,即aSiblings是所有dl元素的数组 83 for(count = i = 0; i < aSiblings.length; i++) { 84 //alert( oTarget.offsetHeight); 85 that.startMove(aSiblings[i], oTarget.offsetHeight, "buffer", function() { 86 //将所有的aSiblings[]全部收拢,然后执行回调函数 87 console.log(this.tagName); 88 this.children[0].className = ""; 89 90 if(++count == aSiblings.length) {//确保收拢之后执行 91 92 if(oParent.offsetHeight == oTarget.offsetHeight) {//如果dl的高度与dt的高度相同 93 //则需要flex展开 94 oTarget.className = "current"; 95 that.startMove(oParent, oParent.height, "flex") 96 } 97 else {//否则需要buffer收拢 98 that.startMove(oParent, oTarget.offsetHeight, "buffer", function() { 99 oTarget.className = "" 100 }) 101 } 102 103 104 } 105 106 }) 107 } 108 }//end if 109 110 111 112 }//onclick end 113 }, 114 startMove: function(obj, iTarget, type, callback) { 115 var that = this; 116 clearInterval(obj.timer); 117 obj.iSpeed = 0; 118 obj.timer = setInterval(function() { 119 that[type].call(that, obj, iTarget, callback) 120 }, 30) 121 }, 122 buffer: function(obj, iTarget, callback) { 123 obj.iSpeed = (iTarget - obj.offsetHeight) / 5; 124 obj.iSpeed = obj.iSpeed > 0 ? Math.ceil(obj.iSpeed) : Math.floor(obj.iSpeed); 125 obj.offsetHeight == iTarget ? (clearInterval(obj.timer), callback && callback.call(obj)) : obj.style.height = obj.offsetHeight + obj.iSpeed + "px" 126 }, 127 flex: function(obj, iTarget, callback) { 128 obj.iSpeed += (iTarget - obj.offsetHeight) / 6; 129 obj.iSpeed *= 0.75; 130 if(Math.abs(iTarget - obj.offsetHeight) <= 1 && Math.abs(obj.iSpeed) <= 1) { 131 clearInterval(obj.timer); 132 obj.style.height = iTarget + "px"; 133 callback && callback.call(obj) 134 } 135 else { 136 obj.style.height = obj.offsetHeight + obj.iSpeed + "px" 137 } 138 }, 139 siblings: function(element) {//自己实现jquery的获取同级兄弟节点数组的函数 140 var aTmp = [], 141 oParent = element.parentElement || element.parentNode, 142 i; 143 for(i = 0; i < oParent.children.length; i++)//如果当前element!=oParent.children[i]为真,则执行&&后的push函数 144 element != oParent.children[i] && aTmp.push(oParent.children[i]); 145 return aTmp 146 } 147 };
技巧1:
oDiv.onclick=function (e){ var ev=e||window.event; var oTarget=ev.srcElement||ev.target; }
溯源 ,oTarget的值为当前点击的oDiv内的子DIV
技巧2:
this.initialize.apply(this, arguments);//等价于this.initialize(arguments[0]);
切记,arguments 是参数列表数组
this.click.call(this);
等价于this.click();
技巧3:
while(aDate[0]){ ........ aData.shift(); }
shift()为删除数组的第一个项,
技巧4:
startMove: function(obj, iTarget, type, callback) { var that = this; clearInterval(obj.timer); obj.iSpeed = 0; obj.timer = setInterval(function() { that[type].call(that, obj, iTarget, callback) }, 30) }, buffer: function(obj, iTarget, callback) { obj.iSpeed = (iTarget - obj.offsetHeight) / 5; obj.iSpeed = obj.iSpeed > 0 ? Math.ceil(obj.iSpeed) : Math.floor(obj.iSpeed); obj.offsetHeight == iTarget ? (clearInterval(obj.timer), callback && callback.call(obj)) : obj.style.height = obj.offsetHeight + obj.iSpeed + "px" }, flex: function(obj, iTarget, callback) { obj.iSpeed += (iTarget - obj.offsetHeight) / 6; obj.iSpeed *= 0.75; if(Math.abs(iTarget - obj.offsetHeight) <= 1 && Math.abs(obj.iSpeed) <= 1) { clearInterval(obj.timer); obj.style.height = iTarget + "px"; callback && callback.call(obj) } else { obj.style.height = obj.offsetHeight + obj.iSpeed + "px" } },
startMove预留了一个type,来制定运动的方式 这里定义了两种 一种是flex,一种是buffer
在定时器内 that[type].call(that,obj,iTarget,callback)
that是指的全局对象,所以that[type]即是that.type,访问制定类型type代表的函数
特点是type是字符串变量,因此可以实现不同成员函数的访问
obj.offsetHeight == iTarget ? (clearInterval(obj.timer), callback && callback.call(obj)) : obj.style.height = obj.offsetHeight + obj.iSpeed + "px"
语句1:(clearInterval(obj.timer), callback && callback.call(obj))
语句2:obj.style.height = obj.offsetHeight + obj.iSpeed + "px"
拆开来看就算 当obj的高度已经到达给定值iTarget时,执行语句1,清楚定时器,并判断callback是否存在,若存在,则调用----牢记&&,逻辑与,为真时往后执行,||逻辑或,为假时才往后执行
当obj高度未达到指定值时,执行语句2,继续运动
callback&&callback.call(obj)
关于call函数与apply函数,下篇文章在分析
标签:
原文地址:http://www.cnblogs.com/windSamW/p/4914333.html