概念:
parentElement 获取对象层次中的父对象。
parentNode 获取文档层次中的父对象。
childNodes 获取作为指定对象直接后代的 HTML 元素和 TextNode 对象的集合。
children 获取作为对象直接后代的 DHTML 对象的集合。
parentNode和parentElement功能一样,childNodes和children功能一样。
但是parentNode和childNodes是符合W3C标准的,可以说比较通用。而另外两个只是IE支持,不是标准,Firefox就不支持
/* * 根据元素clsssName得到元素集合 * @param fatherId 父元素的ID,默认为document * @tagName 子元素的标签名 * @className 用空格分开的className字符串 */ function getElementsByClassName(fatherId,tagName,className){ node = fatherId&&document.getElementById(fatherId) || document; tagName = tagName || "*"; className = className.split(" "); var classNameLength = className.length; for(var i=0,j=classNameLength;i<j;i++){ //创建匹配类名的正则 className[i]= new RegExp("(^|\s)" + className[i].replace(/-/g, "\-") + "(\s|$)"); } var elements = node.getElementsByTagName(tagName); var result = []; for(var i=0,j=elements.length,k=0;i<j;i++){//缓存length属性 var element = elements[i]; while(className[k++].test(element.className)){//优化循环 if(k === classNameLength){ result[result.length] = element; break; } } k = 0; } return result; }
<div id="container"> <span class="aaa zzz ccc"></span> <div class="aaa bbb ccc"></div> </div> <div class="aaa bbb ccc"></div> window.onload = function(){ alert(getElementsByClassName(document,"div","aaa ccc").length);//2 alert(getElementsByClassName("container","div","aaa ccc").length);//1 alert(getElementsByClassName("container","span","aaa zzz").length);//1 }
http://www.nowamagic.net/librarys/veda/detail/195
测试:
<div id="dv"> <ul> <li class="current li" city="shanghai"><a href="http://www.qidian.com">qidian</a></li> <li class="current">aa<a href="http://www.baidu.com">baidu</a></li> <li><a href="http://www.duowan.com">duowan</a></li> </ul> </div>
var dv=document.getElementById("dv"); console.dir(dv); console.log(dv.nodeType); console.log(dv.innerHTML); console.log(dv.tagName); console.log(dv.id); console.log(dv.getAttribute("title")); console.log(dv.getAttribute("id")); console.log(dv.attributes["id"]); console.log(dv.textContent); var ul=dv.children[0]; ul.setAttribute("city","shanghai"); var attr=ul.getAttribute("city"); console.log(attr); var cl=dv.children[0].children[1].childNodes[0]; console.log(cl.innerHTML); console.log(cl.nodeType); console.log(cl.data);
可以发现elementNode有innerHTML属性,而textNode有data属性
获取属性getAttribute(attr),如果没有这个属性时,返回的是null
在ie浏览器中并没有dv.attributes["id"]这种方式获取属性,所以以后获取属性统一使用getAttribute(attr)
createElement,createTextNode,appendChild,removeChild,replaceChild
<div id="dv"> <ul> <li class="current li" city="shanghai"><a href="http://www.qidian.com">qidian</a></li> <li class="current">aa<a href="http://www.baidu.com">baidu</a></li> <li><a href="http://www.duowan.com">duowan</a></li> <li style="display: none; color: Red;"><a href="http://www.longre.com">longre</a></li> </ul> </div>
var p=document.createElement("p"); var txt=document.createTextNode("hongdapppp"); p.appendChild(txt); //<p>hongdappp</p> var body=document.getElementsByTagName("body")[0]; body.appendChild(p); //这边无论执行几遍都只添加一次,p是一个 p.setAttribute("city","shanghai"); p.removeChild(txt); //p里面的txt移除了 var dv=document.getElementById("dv"); var li=dv.getElementsByTagName("ul")[0]; //只能替换直接下级的,不能用li/a dv.replaceChild(p,li); //第一个参数是替换的,第二个参数是被替换的
insertBefore
var ul=document.getElementsByTagName("ul")[0]; var li=dv.getElementsByTagName("li")[0]; ul.insertBefore(p,li);//第一个参数p插入到第二个参数li的前面
getAttributeNode
createDocumentFragment()
var dv=document.getElementById("dv"); var ul=dv.getElementsByTagName("ul")[0]; var lis=ul.getElementsByTagName("li"); var first_li=lis[0]; var city_Attribute=first_li.getAttributeNode("city"); console.dir(city_Attribute); var comment=document.createComment("zhushi"); var oFragment = document.createDocumentFragment(); oFragment.appendChild(comment); for(var i = 0 ; i < 10; i ++) { var p = document.createElement("p"); var oTxt = document.createTextNode("段落" + i); p.appendChild(oTxt); oFragment.appendChild(p); } console.dir(oFragment); document.body.appendChild(oFragment);
属性节点city
在更新少量节点的时候可以直接向document.body节点中添加,但是当要向document中添加大量数据是,如果直接添加这些新节点,这个过程非常缓慢,
因为每添加一个节点都会调用父节点的appendChild()方法,
为了解决这个问题,可以创建一个文档碎片,把所有的新节点附加其上,然后把文档碎片一次性添加到document中。
cloneNode()
true 复制子节点
false 不复制子节点
var dv=document.getElementById("dv"); var ul=dv.getElementsByTagName("ul")[0]; var lis=ul.getElementsByTagName("li"); dv.appendChild(lis[0].cloneNode(true)); dv.appendChild(lis[1].cloneNode(false));
两种getElementsByClassName
function $(element) { if (arguments.length > 1) { for (var i = 0, elements = [], length = arguments.length; i < length; i++) { elements.push($(arguments[i])); } return elements; } //如果该参数是一个字符串那假设它是一个id if (typeof element == "string") { return document.getElementById(element); } else { return element; } } /* 第一个参数CSS类名,第二个参数父对象, 第三个参数标签名(eg "div"、"li") 其中第一个参数必选,第二个第三个参数可选 */ document.getElementsByClassName = function(className, parentElement, tagName) { var children = ($(parentElement) || document.body).getElementsByTagName(tagName || '*'); //兼容IE5.x以上的版本和FF的判断 //var children =document.all?document.all:document.getElementsByTagName("*"); //兼容IE5.x版本和FF的判断 var elements = [],child; for (var i = 0,length = children.length; i < length; i++) { child = children[i]; if (hasClassName(child, className)) elements.push(child); } return elements; }; //判断对象element是否包含指定类className function hasClassName(element, className) { if (! (element = $(element))) return false; var elementClassName = element.className; if (elementClassName.length == 0) return false; if (elementClassName == className || elementClassName.match(new RegExp("(^|\s)" + className + "(\s|$)"))) return true; return false; }
第二种
document.getElementsByClassName = function(className) { var allArray = new Array(); var elements = new Array(); if (typeof document.all != "undefined") { allArray = document.all } else { allArray = document.getElementsByTagName("*") } for (var i = 0; i < allArray.length; i++) { var isClassName = hasClassName(allArray[i], className); if (isClassName) { elements.push(allArray[i]) } } return elements }; function hasClassName(element, className) { var elementClassName = element.className; if (elementClassName.length == 0) return false; if (elementClassName == className || elementClassName.match(new RegExp("(^|\s)" + className + "(\s|$)"))) return true; return false }