🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[toc] ## previously ``` document.getElementById(); //上下文只能是document;只会获取到一个元素 不用[n]来获取 id嘛 独有的 context.getElementByTagName(); //把指令容器中子子孙孙辈分的所有标签名为TAGNAME的都获取到了,放在一个数组中 context.getElementsByClassName(CLASSNAME);//同上,但是在IE6~8下不兼容 document.getElementsByName(); //上下文只能是document;在IE浏览器中只对表单元素的name起作用 document.body document.documentElement context.querySelector/context.querySelectorAll //在IE6~8下不兼容;并且获取的是static NodeList ``` ``` //->描述节点和节点之间关系的属性(在标准的浏览器中会把空格和换行当做文本节点来处理) childNodes //->元素节点,不过在IE6~8和标准浏览器不一样,会把注释加进来?;值获取儿子; children //->Element在IE6~8不兼容 parentNode previousSibling/previousElementSibling nextSibling/nextElementSibling lastChild/lastElementChild firstChild/firstElementChild ``` ``` 元素1 文本3 注释8 document9 ``` DOM的增删改 ``` createElement document.createDocumentFragment() appendChild insertBefore cloneNode(true/false) replaceChild removeChild get/set/removeAttribute ``` DOM盒子模型 ``` getComputedStyle ``` ## children 获取某一个容器中的元素子节点(只是儿子) ``` //->首先获取所有的子节点(childNodes),在所有的子节点中把元素节点过滤出来(nodeType === 1) function children(curEle,tagName){ var ary = []; if(/MSIE(6|7|8)/i.test(navigator.userAgent)){ var nodeList = curEle.childNodes; //var连写时一般让短的在前面 for(var i=0,len=nodeList.length;i<len;++i){ if(curNode.nodeType===1){ ary[ary.length] = curNode; } } }else{ //children下获取到的是一个类数组,是一个对象,So要转换为数组 ary = Array.prototype.slice.call(curEle.children); } //->二次筛选 if(typeof tagName === 'string'){ for(var k=0;k<ary.length;++k){ //需要使用.length作为动态的边界判断 var curEleNode = ary[k]; if(curEleNode.nodeName.toLowerCase===tagName.toLowerCase()){ ary.splice(k,1); k--; //因为删除了,后面的会上移 } } } return ary; } console.log(children(oDiv)); ``` ## prev ``` //prev:获取上一个哥哥元素节点 //首先获取当前元素的上一个哥哥节点,判断是否为元素节点,不是的话基于当前的继续找上面的哥哥节点...一直找到哥哥元素节点为止,如果没有哥哥元素界定啊,返回null即可 function prev(curEle){ if(flag){ //如果是标准浏览器 return curEle.previousElementSibling; } var pre = curEle.previousSibling; while(pre&&pre.nodeType!==1){ pre = pre.previousSibling; } return pre; } ``` ## next ``` function next(curEle){ if(flag){ return curEle.nextElementSibling; } var next = curEle.nextSibling; while(next&&next.nodeType==1){ next = next.nextSibling; } return next; } ``` ## prevAll ``` function prevAll(curEle){ var ary = []; var pre = this.prev(curEle); while(pre){ ary.unshift(pre); pre = this.prev(pre); } return ary; } ``` ## nextAll ``` function nextAll(curEle){ var ary = []; var next = this.next(curEle); while(pre){ ary.push(next); next = this.next(next); } return ary; } ``` ## sibling 获取相邻的两个元素节点 ``` function sibling(curEle){ var pre = this.prev(curEle); var nex = this.next(curEle); var ary = []; pre?ary.push(pre):null; nex?ary.push(nex):null; return ary; } ``` ## siblings 获取所有的兄弟元素节点 ``` function siblings(curEle){ return this.prevAll(curEle).concat(this.nextAll(curEle)); } ``` ## index 获取当前元素的索引 ``` function index(curEle){ return this.prevAll(curEle).length; } ``` ## firstChild和lastChild ``` function firstChild(curEle){ var chs = this.children(curEle); //所有子节点 return this.length>0?chs[0]:null; } //->lastChild:获取最后一个元素子节点 function lastChild(curEle){ var chs = this.children(curEle); //所有子节点 return this.length>0?chs[chs.length-1]:null; } ``` ## append ``` function append(newEle,container){ container.appendChild(newEle); } ``` ## prepend 把新的元素添加到容器中的第一个子元素节点的前面 ``` function prepend(newEle,container){ var fir = this.firstChild(container); if(fir){ container.insertBefore(newEle,fir); return; } container.appendChild(newEle) } ``` ## insertBefore 把新元素追加到指定元素的前面 ``` function insertBefore(newEle,oldEle){ oldEle.parentNode.insertBefore(newEle,oldEle); } ``` ## insertAfter 把新的元素追加到指定元素的后面 ``` function insertAfter(newEle,oldEle){ var nex = this.next(oldEle); if(nex){ oldEle.parentNode.insertBefore(newEle,nex); return; } oldEle.parentNode.appendChild(newEle); } ``` ## hasClass ``` //->hasClass:验证当前元素中是否包含className这个样式类名 function hasClass(curEle,className){ //curEle.className //->"box bg border" //->"bg" /\s+bg\s+/ //->"box" /^box\s+/ //->"border" /\s+border$/ var reg = new RegExp("(^| +)"+className+"( +|$)"); return reg.test(curEle.className); } console.log(hasClass(box,"bg")); console.log(hasClass(box,"position")); ``` ## addClass ``` function addClass(curEle,className){ if(!hasClass(curEle,className)){ curEle.className += " "+className; } } addClass(box,'position'); ``` 但这么写仍然会重复 ``` addClass(box,'position bg'); //这么写仍然会重复 ``` 以空格拆分为数组,一个一个进行处理 ``` function addClass(curEle,className){ //->为了防止className传递进来的值包含多个样式类名,我们把传递进来的字符串按照一到多个空格拆分成数组中的每一项 var ary = className.replace(/^ +| +$/g,'').split(/ +/g); //->循环数组,一项项的进行验证添加即可 for(var i=0,len=ary.length;i<len;++i){ var curName = ary[i]; if(!hasClass(curEle,curName)){ curEle.className += " "+curName; } } } ``` ## removeClass ``` function removeClass(curEle,className){ //->为了防止className传递进来的值包含多个样式类名,我们把传递进来的字符串按照一到多个空格拆分成数组中的每一项 var ary = className.replace(/^ +| +$/g,'').split(/ +/g); //->循环数组,一项项的进行验证添加即可 for(var i=0,len=ary.length;i<len;++i){ var curName = ary[i]; if(!hasClass(curEle,curName)){ var reg =new RegExp("(^| +)"+curName+"( +|$)"); curEle.className = curEle.className.replace(reg," "); } } } ``` ## getElementsByClassName - 只要包含传入的类名就会被选中 - 若果传入的字符串中包含多个类名,那么是选中包含所有这些类名的元素(和传入字符串中的这些个类名的空格多少与先后顺序没有关系) - 若没有匹配中的,则返回空集合 ``` //->getElementsByClass:通过元素的样式类名获取一组元素集合 //->className:要获取的样式类名(可能是一个也可能是多个) //->获取元素的上下文->如果这个值不传递的话,默认应该是document function getElementsBycClass(className,context){ conext = context||document; var classNameAry = className.replace(/^ +| +$/g,'').split(/ +/g); //先去掉首尾空格,然后再按照中间的空格把它里面的每一项拆分成数组 var ary = []; //->获取指定的上下文中所有的元素标签,循环这些标签,获取每一个标签的className样式类名的字符串 var nodeList = context.getElementsByTagName("*"); //->获取指定上下文中的所有的元素标签 for(var i=0,len=nodeList.length;i<len;++i){ var curNode = nodeList[i]; //->判断curNode.className是否即包含"w3"也包含"w1" ,如果两个都包含的话,curNode就是我想要的,否则就不是我想要的 var isOk = true;//->我们假设curNode中包含了所有的样式 for(var k=0;k<classNameAry.length;++k){ var reg = new RegExp("(^| +)+curNameAry[k]+( +|$)") if(!reg.test(curNode.className)){ isOk = false; break; } } if(isOk){ //拿每一个标签分别和所有样式类名比较后,如果结果还是true的话,说明当前元素标签包含了所有的样式,也是我们想要的 ary.push(curNode); } } return ary; } console.log(getElementsByClass("w3 w1 ")); ``` ## setCss 在JS中给元素设置样式属性值,我们只能通过`curEle.style[attr]=value`这种方式给当前元素设置行内样式 setCss给当前元素的某一个样式属性设置值(增加在行内样式上的) ``` function setCss(curEle,attr,value){ //->在JS中设置float样式值的话也需要处理兼容 if(attr==="float"){ curEle['style']['cssFloat'] = value; curEle['style']['styleFloat'] = value; return; } //->如果打算设置的是元素的透明度,我们需要设置两套样式来兼容所有的浏览器 if(attr === 'opacity'){ curEle['style']['opacity'] = value; curEle['style']['filter'] = "alpha(opacity="+value*100+")"; return; } // ->对于某些样式属性,如果传递进来的值没有加单位,我们需要把单位默认的补充上,这样的话,这个方法就会人性化一些 var reg = null; reg = /^(width|height|top|bottom|left|right|((margin|padding)(Top|Bottom|Left|Right)?))$/; if(reg.test(attr)){ if(!isNaN(value)){ //如果为true,说明加单位了 value+='px'; } } curEle['style'][attr] = value; } setCss(box,'left','100px'); setCss(box,'left',200); setCss(box,'background',"red"); setCss(box,"opacity",0.1); setCss(box,"borderTop","10px solid #000"); setCss(box,"padding","10px 20px 30px 40px"); setCss(box,"padding",10); //复合值的话 只支持4个值都相同的情况下不加单位 ``` ## setGroupCss ``` function setGroupCss(curEle,options){ //->通过检测options的数据类型,如果不是一个对象,则不能进行批量的设置 options = options||0; //排除null和undefined if(Object.prototype.toString.call(options)!=="[object Object]"){ return; } for(var key in options){ if(options.hasOwnProperty(key)){ this.setCss(curEle,key,options[key]); } } } utils.setGroupCss(box,{ width:200 ,backgroundColor:"red" ,opacity:0.1 ,float:"right" ,borderTop:"10px solid #000" ,padding:10 }) ``` ## css 此方法实现了获取、单独设置、批量设置元素的样式值 ``` function css(curEle){ var argTwo = arguments[1]; if(typeof argTwo === 'string'){ //->第一个参数值是一个字符串,这样的话很有肯能就是在获取样式,为什么说是很有可能呢?因为还需要判断是否存在第三个参数,如果第三个参数存在的话,就不是获取了,而是在单独的设置样式属性值 var argThree = arguments[2]; if(!argThree){ //->第三个参数不存在; // return this.getCss(curEle,argTwo); return this.getCss.apply(this,arguments); } //->第三个参数存在则为单独设置 // this.setCss(curEle,argTwo,argThree); this.setCss.apply(this,arguments); } argTwo = argTwo || 0; if(argTwo.toString === "[object Object]"){ //->批量设置样式属性值 this.setGroupCss.apply(this.arguments); } } ``` 其中的`!argThree`有bug, 因为有可能这个值是个0这样判断的话就会进来,但并不是死我们所期望的,它本应该是设置值,应该判断它是不是undefined ``` if(typeof argument[2]==='undefined'){} ```