封装工具
childNodes封装
因为childNodes获取时会把子元素获取到,也就是会把文本节点、注释节点等获取到不便使用,所以封装。
创建类数组以便于讲元素节点放入,通过获得节点长度循环,将nodeType===1的节点放入类数组
function elemChildren(node){
var temp={
'length':0,
'push':Array.prototype.push,
'splice':Array.prototype.splice
},
len = node.childNodes.length;
for(var i =0;i<len;i++){
var childItem=node.childNodes[i];
if(childItem.nodeType===1){
//temp[temp['length']]=childItem;
//temp['length']++;
temp.push(childItem);
}
}
return temp;
}
parentNode封装
因为普通的parentNode只能获取一层父元素,无法指定获取的父元素
函数中传入tier层级参数,通过typeof判断非空,之后while循环 将tier累减不断重新赋值第一个参数
function parentNode(elem,tier){
var type=typeof(tier);
if(type==='undefined'){
return elem.parentNode;
}else{
while(tier){
elem= elem.parentNode;
tier--;
}
}
return elem;
}
insertAfter封装
因为在Element中只有insertBefore,没有insertAfter方法
判断兄弟元素是否存在,如果存在兄弟节点,则通过nextElementSibling来获得弟元素,在弟元素上insertBefore,如果没有弟元素则在当前元素的父元素上appendChild
Element.prototype.insertAfter=function(newEl,origin){
var brotherElement=origin.nextElementSibling;
if(brotherElement){
var fatherEle=brotherElement.parentNode;
fatherEle.insertBefore(newEl,brotherElement);
}else{
this.appendChild(newEl)
}
}
pageXOffset封装
判断pageXOffset是否存在,如果存在则返回不存在则将怪异模式和标准模式相加,因为两者只能存在其一
function getScrollOffset(){
if(window.pageXOffset){
return{
left:window.pageXOffset,
top:window.pageYOffset,
}
}else{
return{
left:document.body.scrollLeft+document.documentElement.scrollLeft,
top:document.body.scrollTop+document.documentElement.scrollTop
}
}
}
innerWidth封装
判断innerWidth是否存在,如果存在则返回不存在则将通过compatMode判断怪异模式和标准模式,
function getViewportSize(){
if(window.innerWidth){
return{
width:window.innerWidth,
height:window.innerHeight
}
}else{
if(document.compatMode==='BackCompat'){
return{
width:document.body.clientWidth,
height:document.body.clientHeight
}
}else{
return{
width:document.documentElement.clientWidth,
height:document.documentElement.clientHeight
}
}
}
}
scrollWidth封装
用于没有常规访问方式只有IE访问方式,所以直接判断第一个形式是否存在,不存在返回第二个
function getScrollSize(){
if(document.body.scrollWidth){
return{
width:document.body.scrollWidth,
height:document.body.scrollHeight
}
}else{
return{
width:document.documentElement.scrollWidth,
height:document.documentElement.scrollHeight
}
}
}
offsetLeft封装
因为offsetLeft在寻找距离时,如果父级有定位则计算与父级的距离,所以要通过offsetParent去判断是否有父级定位,不断循环去累加与父级的距离
function getElemDocPosition(el){
var parent=el.offsetParent,
offsetLeft=el.offsetLeft,
offsetTop=el.offsetTop;
while(parent){
offsetLeft+=parent.offsetLeft;
offsetTop+=parent.offsetTop;
parent=parent.offsetParent;
}
return {
left:offsetLeft,
top:offsetTop
}
}
window.getCoumputedStyle封装
判断getCoumputedStyle是否存在 否则反之使用currentStyle,记得还要判断是否有prop
function getStyles(elem,prop){
if(window.getComputedStyle){
if(prop){
return window.getComputedStyle(elem,null)[prop];
}else{
return window.getComputedStyle(elem,null);
}
}else{
if(prop){
return elem.currentStyle[prop];
}else{
return elem.currentStyle;
}
}
}
elem.attachEvent封装
判断addEventListener是否存在 否则反之使用attachEvent,但是由于指向问题记得用call改变,
function attachEvent(event,fn,bubble){
if(event.addEventListener){
event.addEventListener(event,fn,bubble);
}else if(event.attachEvent){
event.attachEvent('on'+event,function(){
fn.call(elem);
})
}else{
event['on'+event]=fn;
}
}
e.stopPropagation封装
判断stopPropagation是否存在 否则反之使用cancleBubble,但是由于e指向问题记得用在开始判断,
function removeBubble(e){
var e=e||window.event;
if(e.stopPropagation()){
e.stopPropagation()
}else{
e.cancelBubble=true;
}
}
更多封装代码请查看以往DOM文章内
常见练习代码
要求:
在原型上编程,遍历任何一个父元素,找到子元素的节点。接收参数,有参数则为对应的子元素,没有则打印子元素集合
Element.prototype.findChildren=function (argument,child,childArr) {
var child=child||this.childNodes;
var childArr=childArr||{},
str=Object.prototype.toString;
if(argument){
for (var i = 0; i < child.length; i++) {
if (child[i].hasChildNodes()) {
if(argument===child[i].nodeType){
childArr[str.call(child[i])]= child[i];
}
arguments.callee(argument,child[i].children,childArr);
}else{
if(argument===child[i].nodeType){
childArr[str.call(child[i])]= child[i];
}
}
};
return childArr;
}else{
for (var i = 0; i < child.length; i++) {
if (child[i].hasChildNodes()) {
childArr[str.call(child[i])]= child[i];
arguments.callee(argument,child[i].children,childArr);
}else{
childArr[str.call(child[i])]= child[i];
}
};
return childArr;
}
}
var divC=document.getElementsByClassName('c')[0];
var child= divC.findChildren();
console.log(child);
在原型上编程,找出一个元素的第N层父级元素
Element.prototype.finFather=function(rank){
var father=this.parentNode,
fatherArr={},
i=1;
while(father.toString()!='[object HTMLBodyElement]') {
fatherArr[i]=father.toString();
father=father.parentNode;
i++;
};
return fatherArr[rank];
}
Element.prototype.isChild=function(){
var child=this.childNodes;
for (var i = 0; i < child.length; i++) {
if(child[i].nodeType===1){
return true;
}
};
return false;
}
var oDiv=document.createElement('div');
oDiv.id='box';
document.body.appendChild(oDiv);
var oUl=document.createElement('ul');
oUl.className='list';
oDiv.appendChild(oUl);
var oLi=document.createDocumentFragment();
for (var i = 1; i <=5; i++) {
var li=document.createElement('li');
li.className='list-item';
li.innerHTML=i;
oLi.appendChild(li);
};
oUl.appendChild(oLi);
Element.prototype.foEachElement=function(element,elementArr){
var element=element||this.childNodes,
elementArr=elementArr||{};
for (var i = 0; i < element.length; i++) {
elementArr[i+element[i].toString()]=element[i];
if(element[i].hasChildNodes()){
elementArr[i+element[i].toString()]=element[i];
arguments.callee(element[i].childNodes,elementArr);
}else{
elementArr[i+element[i].toString()]=element[i];
}
};
return elementArr;
}
Element.prototype.reverse=function(){
var child=this.children;
for (var i = child.length; i>0; i--) {
this.appendChild(child[i-1]);
};
}