第八节dom以及dom库的封装

1、获取页面中元素的方法 document.getElementById() context.getElementsByTagName() context.getElementsByClassName() ie6~8不兼容 document.getElementsByName()应用于表单中的name document.body document.documentElement context.querySelector/context.querySelectorAll ie6~8不兼容 通过这个获取到的节点集合不存在dom映射2、描述节点和节点之间关系的属性(在标准浏览器中会把空格和换行当做文本节点处理) childNodes children在ie6~8下获取的结果和标准浏览器获取的结果不一致 parentNode previousElementSibling/previousSibling nextElementSibling/nextSibling lastChild/lastElementChild firstChild/firstElementChild3、dom的增删改 createElement() document.createDocumentFragment() appendChild() insertBefore() cloneNode(true/false) replaceChild() removeChild() get/set/removeAttribute4、dom盒子模型(参照第六节)什么是惰性思想? 使用惰性思想来封装我的常用方法库:第一次在给utils赋值的时候我们就已经把兼容处理好了,把处理的结果存放在flag变量中,以后在每一个方法中,只要是ie6~8不兼容的,我们不需要重新检测,只需要使用flag的值即可比如以下: var utils = (function () { var flag = "getComputedStyle" in window; return { listToArray: function (likeArray) { if (flag) { return Array.prototype.slice.call(likeArray); } var arr = []; for (var i = 0; i < likeArray.length; i++) { arr[arr.length] = likeArray[i]; } return arr; } })(); 以下的Dom库封装utils 方法库完成了这些功能 1.获取某一个容器中所有元素子节点(还可以筛选出指定签名的)(function children) 2.获取上一个哥哥元素节点(prev)、获取下一个弟弟元素节点(next)、获取所有的哥哥元素节点(prevAll)、获取所有弟弟元素节点(nextAll)、获取相邻的两个元素节点(sibling)、获取所有的兄弟元素节点(siblings) 4.获取第一个元素子节点(firstChild)、获取最后一个元素子节点(lastChild) 5.获取当前元素的索引(index) 6.prepend增加到某一个容器开头(和appendChild对应) 7.insertAfter增加到某一个元素后面(和inserBefore对应) 8.addClass增加样式类名 9.removeClass 删除样式类名 10.hasClass判断是否存在某一个样式类名 11.解决getElementsByClassName()兼容问题 12.Jq中的css方法 11.getcss 12.setcss 13.getGroupCssDom库封装utils 方法库 var utils = (function () { var flag = "getComputedStyle" in window; //获取指定的子元素 function children(objId, Ele) { var curary = []; if (!flag) { var childary = objId.childNodes; for (var i = 0; i < childary.length; i++) { if (childary[i].nodeType == 1) { curary[curary.length] = childary[i]; } } childary = null; } else { curary = this.listToArray(objId.children); } if (typeof Ele == "string") { for (var k = 0; k < curary.length; k++) { var curEle = curary[k]; if (curEle.nodeName.toLowerCase() !== Ele.toLowerCase()) { curary.splice(k, 1); k--; } } curEle = null; } return curary; }//获取上一个哥哥元素节点 function prev(curEle) { if (flag) { return curEle.previousElementSibling; } var pre = curEle.previousSibling; while (pre && pre.nodeType != 1) { pre = pre.previousSibling; } return pre; }//获取下一个弟弟节点 function next(curEle) { if (flag) { return curEle.nextElementSibling; } var nextEle = curEle.nextSibling; while (nextEle && nextEle.nodeType != 1) { nextEle = nextEle.nextSibling; } return nextEle; }//获取所有的哥哥节点 function prevAll(curEle) { var ary = []; var pre = this.prev(curEle); while (pre) { ary.unshift(pre); pre = this.prev(pre); } return ary; }//获取所有的弟弟节点 function nextAll(curEle) { var pre = this.next(curEle); var ary = []; while (pre) { ary.push(pre); pre = this.next(pre); } return ary; }//获取相邻两个元素节点 function sibling(curEle) { var ary = []; var pre = this.prev(curEle); var next = this.next(curEle); pre ? ary.push(pre) : null; next ? ary.push(next) : null; return ary; }//获取所有的兄弟节点 function siblings(curEle) { return this.prevAll(curEle).concat(this.nextAll(curEle)); }//获取当前元素索引 function index(curEle) { return this.prevAll(curEle).length; }//第一个元素节点 function firstChild(curEle) { var chs = this.children(curEle); return chs.length > 0 ? chs[0] : null; }//最后一个元素节点 function lastChild(curEle) { var chs = this.children(curEle); return chs.length > 0 ? chs[chs.length - 1] : null; }//向容器中开头追加新元素的方法 function prepend(con, newEle) { var fir = this.firstChild(con); if (fir) { return con.insertBefore(newEle, fir); } else { return con.appendChild(newEle); } }//把新元素追加到指定元素之前 function insertBefore(oldEle, newEle) { return oldEle.parentNode.insertBefore(newEle, oldEle); }//把元素追加到指定元素之后 function insertAfter(oldEle, newEle) { var nex = this.next(oldEle); if (nex) { return oldEle.parentNode.insertBefore(newEle, nex); } return oldEle.parentNode.appendChild(newEle); }//类数组转换成数组 function listToArray(likeArray) { if (flag) { return Array.prototype.slice.call(likeArray); } var arr = []; for (var i = 0; i < likeArray.length; i++) { arr[arr.length] = likeArray[i]; } return arr; }//json格式字符串转换为json格式对象 function jsonParse(str) { if (flag) { return JSON.parse(str); } return eval("(" + str + ")"); }//检测是否有class function hasClass(curEle, className) { var reg = new RegExp("(^| +)" + className + "( +|$)"); return reg.test(curEle.className); }//增加class function addClass(curEle, className) { var ary = className.split(/ +/); for (var i = 0; i < ary.length; i++) { var cur = ary[i]; if (!this.hasClass(curEle, cur)) { curEle.className += '' + cur; } } }//移出class function removeClass(curEle, className) { //先把首尾空格去掉,在拆分成数组 var ary = className.replace(/^ +| +$/g, "").split(/ +/g); for (var i = 0; i < ary.length; i++) { var cur = ary[i]; if (this.hasClass(curEle, cur)) { var reg = new RegExp("(^| +)" + cur + "( +|$)"); curEle.className = curEle.className.replace(reg, ' '); } } }//getbyclass封装 function getclass(strClass, context) { context = context || document; var aryEle = context.getElementsByTagName('*'); var aryCan = strClass.replace(/(^ +| +$)/g, "").split(/ +/); var ary = []; for (var i = 0; i < aryEle.length; i++) { var cur = aryEle[i]; var isOkey = true; for (var k = 0; k < aryCan.length; k++) { var curk = aryCan[k]; var reg = new RegExp("(^| +)" + curk + "($| +)"); if (!reg.test(cur.className)) { isOkey = false; break; } } if (isOkey) { ary.push(cur); } } return ary; }//获取样式 function getcss(attr) { var val = null; var reg = null; if (flag) { val = getComputedStyle(this)[attr]; } else { if (attr = "opacity") { val = this.currentStyle["filter"]; var reg = /^alpha\(opacity=(\d+(?:\.\d+)?)\)$/; val = reg.test(val) ? reg.exec(val)[1] / 100 : 1; } else { val = this.currentStyle[attr]; } } reg = /^(-?\d+(\.\d+)?)(em|rem|px)$/i; return reg.test(val) ? parseFloat(val) : val; }//设置css样式 function setcss(attr, value) { //在js中设置float样式值的话,也需要处理兼容 if (attr == "float") { this["style"]["cssFloat"] = value; this["style"]["styleFloat"] = value; return; } //如果打算设置的是元素的透明度,我们需要设置两套样式兼容所有的兼容 if (attr == "opactity") { this["style"]["opactity"] = value; this["style"]["filter"] = "alpha(opacity=" + value * 100 + ")"; return; } var reg = /^(width|height|top|bottom|left|right|((margin|padding)(Top|Bottom|Left|Right)?))$/; if (reg.test(attr) && !isNaN(value)) { value += "px"; } this["style"][attr] = value; }//批量设置css样式 function setGroupCss(obj) { for (var k inobj) { if (obj.hasOwnProperty(k)) { setcss.call(this, k, obj[k]); } } }//获取、单独设置、批量设置 function css(curEle) { //如果第三个参数存在就是设置,如果不存在就是获取值 var ary = Array.prototype.slice.call(arguments, 1); if (typeof arguments[1] == "string") { if (typeofarguments[2] == "undefined") { return getcss.apply(curEle, ary); } return setcss.apply(curEle, ary); } if (Object.prototype.toString.call(arguments[1]) == "[object Object]") { return setGroupCss.apply(curEle, ary); } }return { listToArray: listToArray, jsonParse: jsonParse, children: children, prev: prev, next: next, prevAll: prevAll, nextAll: nextAll, sibling: sibling, siblings: siblings, index: index, firstChild: firstChild, lastChild: lastChild, prepend: prepend, insertBefore: insertBefore, insertAfter: insertAfter, hasClass: hasClass, addClass: addClass, removeClass: removeClass, getclass: getclass, css: css } })(); 1、基于dom库封装选项卡插件 ~function () { function fn(container, deIndex) { var tabOption = utils.firstChild(container); var olis = utils.children(tabOption, "li"); var divList = utils.children(container, "div"); //让deIndex对应的页卡有选中样式 utils.addClass(olis[deIndex], "active"); utils.addClass(divList[deIndex], "active"); //实现具体的切换功能 for (var i = 0; i < olis.length; i++) { olis[i].onclick = function () { var sibEle = utils.siblings(this); var index = utils.index(this); for (var i = 0; i < sibEle.length; i++) { utils.removeClass(sibEle[i], "active"); } utils.addClass(this, "active"); for (var i = 0; i < divList.length; i++) { if (i != index) { utils.removeClass(divList[i], "active"); } else { utils.addClass(divList[i], "active"); } } }; } } window.mytab = fn; }(); 2、运用事件委托的方式完成选项卡插件封装 ~function () { function fn(container, deIndex) { var tabOption = utils.firstChild(container); var olis = utils.children(tabOption, "li"); var divList = utils.children(container, "div"); //让deIndex对应的页卡有选中样式 utils.addClass(olis[deIndex], "active"); utils.addClass(divList[deIndex], "active"); tabOption.onclick = function (e) { e = e || window.event; e.target = e.target || e.srcElement; if (e.target.tagName.toLowerCase() == "li") { detailFn.call(e.target, divList, olis); } }; }function detailFn(divList, olis) { var index = utils.index(this); for (var i = 0; i < divList.length; i++) { i === index ? (utils.addClass(divList[i], "active"), utils.addClass(olis[i], "active")) : (utils.removeClass(divList[i], "active"), utils.removeClass(olis[i], "active")); } } window.mytab = fn; }(); 3、运用面向对象的方式封装选项卡插件 ~function () { function TabChange(container, deIndex) { this.init(container, deIndex); } TabChange.prototype = { constructor: TabChange, //按照索引来设置默认选中的页卡 defaultIndexEvent: function () { utils.addClass(this.olis[this.deIndex], "active"); utils.addClass(this.divList[this.deIndex], "active"); }, //事件委托实现绑定切换 liveClick: function () { var _this = this; this.tabOption.onclick = function (e) { e = e || window.event; e.target = e.target || e.srcElement; if (e.target.tagName.toLowerCase() == "li") { _this.detailFn(e.target); } } }, detailFn: function (curEle) { var index = utils.index(curEle); for (var i = 0; i < this.divList.length; i++) { i === index ? (utils.addClass(this.divList[i], "active"), utils.addClass(this.olis[i], "active")) : (utils.removeClass(this.divList[i], "active"), utils.removeClass(this.olis[i], "active")); } }, //初始化,也是当前插件的唯一入口 init: function (container, deIndex) { this.container = container || null; this.deIndex = deIndex || 0; this.tabOption = utils.firstChild(container); this.olis = utils.children(this.tabOption, "li"); this.divList = utils.children(container, "div"); this.defaultIndexEvent(); this.liveClick(); } }; window.mytab = TabChange; }();

    推荐阅读