JavaScript:Dom

概念:

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
}
原文地址:https://www.cnblogs.com/hongdada/p/3528893.html