js小记:DOM基本操作 总结

一、获取节点 、节点关系

1、获取节点
- nodeType
- nodeName
- nodeValue
- tagName    // 与nodeName一样
 ****************************
- getElementByID() 
- getElementsByTagName()    //得到数组NodeList
- getElementsByName()       //得到数组NodeList
- getElementsByClassName()  //得到数组NodeList //IE7、8不兼容
 ****************************
//IE7、8不兼容
- querySelector()          //类似于选择器(只得到第一个)
- querySelectorAll()       //得到数组NodeList(是静态的:用它后,再删除部分Dome节点,发现length值不变)

注:
1、如果页面中多个元素的ID值相同,getElementByID()只返回文档中第一次出现的元素
2、 getElementByID()在 IE7及较低版本 还有一个怪癖:如果有哪个表单元素(< input>、< textarea>、< button> 及< select>)的name属性值 等于 指定的ID(即:getElementByID()要获取的ID值),而且该元素在文档中位于给定ID的元素前面,那么IE就会返回那个表单元素。

2、节点关系(指针)
 - childNodes
 - firstChild
 - lastChild
 ****************************
 - parentNode
 - ownerDocument      //返回祖先节点(整个document)
 ****************************
 - nextSibling        //没有则返回null
 - previousSibling

测试代码:

<body>
<ul id='myul'>
    <li class="myli"></li>
    <li class="myli list"></li>
    <li class="myli">
        <h1>I'm h1</h1>
    </li>
</ul>
<div id="app" name="bty">
  <p></p>
</div>
<img src="">
<div id="app2"><p></p></div>

<script type="text/javascript">
console.log(document.getElementsByClassName('myli')[1]);//<li class="myli list"></li>
console.log(document.getElementsByClassName('myli list')[0]);//<li class="myli list"></li>
console.log(document.getElementsByClassName('list myli')[0]);//<li class="myli list"></li>

var oUl = document.querySelector('#myul'); //得到整个#myul的HTML
console.log(oUl.childNodes[3]);//<li class="myli list"></li>
console.log(oUl.querySelectorAll('.myli'));//[li.myli, li.myli.list, li.myli]  //是个数组
console.log(oUl.querySelector('.myli'));//<li class="myli"></li>    //只得到第一个
console.log(document.querySelector('#myul .list'));//<li class="myli list"></li>

console.log(document.getElementsByTagName('h1')[0]);//<h1>I'm h1</h1>
console.log(document.getElementsByTagName('h1')[0].innerHTML);//I'm h1
console.log(document.getElementsByName("bty")[0].nodeName);//DIV

var oDiv = document.getElementById('app');
var oDiv2 = document.getElementById('app2');
var oP = oDiv2.getElementsByTagName('p')[0];
var obody = document.getElementsByTagName('body')[0];

console.log(oDiv.nodeType);//1

console.log(oDiv.childNodes.length);//3
console.log(oDiv.childNodes);//[text,p,text]  //是个数组
console.log(oDiv2.childNodes.length);//1
console.log(oDiv2.childNodes);//[p]

console.log(obody.firstChild.nodeName);//#text
console.log(obody.lastChild.nodeName);//SCRIPT
console.log(obody.lastChild.tagName);//SCRIPT
console.log(oDiv.childNodes[0].nodeName);//#text
console.log(oDiv.childNodes[0].nodeValue);//
console.log(oDiv2.childNodes[0].nodeName);//P
console.log(oDiv2.childNodes[0].nodeValue);//null

console.log(oDiv.parentNode.nodeName);//BODY
console.log(oP.ownerDocument.nodeName);//#document
console.log(oDiv.nextSibling.nodeName);//#text
console.log(oDiv.nextSibling.nextSibling.nodeName);//IMG
console.log(oDiv.previousSibling.nodeName);//#text
console.log(oDiv.previousSibling.previousSibling.nodeName);//UL
</script>
</body>

二、节点操作

 - createElement("Tagname")
 - createTextNode("input text")
 - createAttribute("attribute name")
***********************************
 - textContent //该节点及其后代节点的文本内容(IE8不兼容)
 - innerText   //该节点及其后代节点的文本内容(IE8不兼容)
 - innerHTML   //缺点:有时会引起 内存泄漏 或 安全问题
***********************************
 - Node.appendChild("newNode")              
 - Node.insertBefore("newNode","基准位置")  
 //Node.insertBefore("newNode",null)插入后成为最后一个子节点
 - Node.replaceChild("newNode","替换位置")
 - Node.removeChild("删除的位置")
 - Node.cloneNode(true/false)
***********************************
 - Node.normalize()    //合并Node的文本**子节点**  [ˈnɔ:məlaɪz] 
 - Node.firstChild.splitText(位置) //将一个**文本节点**拆分成两个文本节点,返回值为位置后的文本

返回值:
appendChild()、insertBefore() 操作完后 返回 第一个参数的值(新增的节点)。
replaceChild() 操作完后 返回 已被替换下来 的节点。
removeChild() 操作完后 返回 删除 的节点。
cloneNode() 操作完后 返回 克隆的节点;若为深复制,则包括子节点都返回


测试代码:

<body>
<ul id="app">
  <li>1</li>
  <li>2</li>
  <li>替换我</li>
</ul>
<p id="p">删除我</p>
<ul id="clone"></ul>
<script type="text/javascript">
var oUl = document.getElementById('app');
var oP = document.getElementById('p');
var oUl2 = document.getElementById('clone');

//appendChild()、createAttribute()
var nodeli = document.createElement("LI");
var nodetext = document.createTextNode("3");
nodeli.appendChild(nodetext); 
var att=document.createAttribute("class");
nodeli.setAttribute("att","democlass"); 
    //obody.childNodes[1] 为 UL
console.log(oUl.appendChild(nodeli));//<li att="democlass">3</li>

//normalize()
var nodeli2 = document.createElement("li");
var nodetext2 = document.createTextNode("4");
var nodetext22 = document.createTextNode("我是第二个文本子节点");
nodeli2.appendChild(nodetext2);
nodeli2.appendChild(nodetext22);
console.log(nodeli2.childNodes.length);     //2
nodeli2.normalize();                        //合并文本子节点
console.log(nodeli2.childNodes.length);     //1

//splitText()
var newNode = nodeli2.firstChild.splitText(5);//分割firstChild
console.log(nodeli2.childNodes.length);     //2
console.log(nodeli2.firstChild.nodeValue);  //4我是第二
console.log(newNode.nodeValue);             //个文本子节点

//insertBefore()
oUl.insertBefore(nodeli2,oUl.childNodes[0]);//此处oUl.childNodes[0]为#text

//replaceChild()
var nodeli3 = document.createElement("li");
var nodetext3 = document.createTextNode("我是替换过的");
nodeli3.appendChild(nodetext3);  
                //上面插入的nodeli2也计入其中
console.log(oUl.replaceChild(nodeli3,oUl.childNodes[6]));//<li>替换我</li>

//removeChild        //删除P标签
console.log(oP.removeChild(oP.childNodes[0]));//"删除我"

//cloneNode
oUl2.appendChild(oUl.cloneNode(true));//true为深复制,默认为false
//oUl2.appendChild(oUl.cloneNode());//什么也不会发生
</script>
</body>

页面输出:
这里写图片描述

注:在IE中有另一种createElement()的使用方式 ,即为这个方法传入完整的元素标签,也可以包含属性,如下例子所示:

var div = document.createElement("<div id=\"myNewDiv\" class=\"box\"></div >"); 

textContent:
测试代码:

<div id="users">
    <h2>Title</h2>
    <ul>
        <li class="user">Sam</li>
        <li class="user">Amy</li>
        <li class="user last">hhh</li>
    </ul>
</div>

<script type="text/javascript">
var oUl = document.getElementById('users');
console.log(oUl.textContent);

var oLast = document.getElementsByClassName('last')[0];
oLast.textContent = 'bty';
console.log(oUl.textContent);
</script>

第一个console.log(oUl.textContent)输出:
这里写图片描述
第二个console.log(oUl.textContent)输出:
这里写图片描述


三、节点属性

节点属性的操作分下面三类

**************
- Node.getAttribute('id')          // 获取(也能获取自定义属性)     
- Node.setAttribute('id','value')  // 设置
- Node.removeAttribute('id')       // 移除
- Node.attributes                  // 获取DOM全部特性
**************
- 属性访问器                     // 两种访问方式(这里是className,上面都是class)
**************
- dataset   (自定义属性)       //用处:元素上保存数据

注:由于存在下面两种差别,在通过 JavaScript 以编程方式操作 DOM 时,开发人员经常不使用 getAttribute(),而是只使用属性访问器。只有在取得自定义特性值的情况下,才会使用 getAttribute()方法。
- 差别1 style,用于通过 CSS 为元素指定样式。在通过 getAttribute()访问时,返回的是 CSS 字符串,而通过 属性访问器访问它则会返回一个对象。由于 style 属性是用于以编程方式访问元素样式的,因此并没有直接映射到 style 特性。
- 差别2 onclick, 用于onclick事件处理程序。当在元素上使用时,onclick 特性中包含的是 JavaScript 代码,如果通过 getAttribute()访问,则会返回相应代码的字符串。而在属性访问器访问onclick 属性时,则会返回一个 JavaScript 函数。这是因为 onclick 及其他事件处理程序属性本身就应该被赋予函数值。


测试代码:

<div style="color:red;" id="app" >aas</div>

<script type="text/javascript">
    var oDiv = document.getElementById('app');
    console.log(oDiv.getAttribute('class'));//null
    console.log(oDiv.getAttribute('style'));//color:red;

    oDiv.setAttribute("class","myclass");
    console.log(oDiv.getAttribute('class'));//myclass

    oDiv.removeAttribute("class");
    console.log(oDiv.getAttribute('class'));//null

    console.log(oDiv.attributes); //{0: style, 1: id, style: style, id: id, length: 2}
</script>

属性访问器
测试代码:

<label for='userName'>username:</label>
<input id='userName' value="我是值" type='text' class='u-txt'/>

<script type="text/javascript">
    var oinput = document.getElementById('userName');
    //访问属性:两种访问方式
    console.log(oinput.className);      //u-txt
    console.log(oinput["className"]);   //u-txt
                    //这里是className,上面都是class                                    

    console.log(oinput.id);             //userName
    console.log(oinput["id"]);          //userName

    console.log(oinput.value);          //我是值
    console.log(oinput["value"]);       //我是值

    //修改属性
    oinput.className = "2u-txt";        
    console.log(oinput.className);      //2u-txt

    oinput.disabled = true;
</script>

dataset(自定义属性)
测试代码:

<div id="user" data-id="123"
               data-name="bty"
               data-email="qq">hhh</div>

<script type="text/javascript">
    //dataset一般用作 保存 节点的自定义属性
    var oDiv = document.getElementById('user');
    console.log(oDiv.dataset);      //{id: "123", name: "bty", email: "qq"}
    console.log(oDiv.dataset.name); //bty
</script>

细讲attributes

- attributes.getNamedItem(name)    //返回nodeName值等于name的节点;
- attributes.removeNamedItem(name) //从列表中移除nodeName值等于name的节点;
- attributes.setNamedItem(node)    //向列表中添加节点,以节点的nodeName属性为索引;
- attributes.item(pos)             //返回位于数字 pos 位置处的节点。
// getNamedItem(name)
var id = element.attributes.getNamedItem("id").nodeValue; 
var id = element.attributes["id"].nodeValue;  //简写
element.attributes["id"].nodeValue = "someOtherId"; 

//removeNamedItem(name)
var oldAttr = element.attributes.removeNamedItem("id"); //返回被删除的Attr

//setNamedItem(node) 
element.attributes.setNamedItem(newAttr); 

一般来说, attributes 的方法不够方便,因此开发人员更多的会使用getAttribute()、removeAttribute()和 setAttribute()方法。
不过,如果想要遍历元素的特性,attributes 属性倒是可以派上用场。在需要将 DOM 结构序列化为 XML 或 HTML 字符串时,多数都会涉及遍历元素特性。以下代码展示了如何迭代元素:

function outputAttributes(element){ 
     var pairs = new Array(), 
         attrName, 
         attrValue, 
         i, 
         len; 

     for (i=0, len=element.attributes.length; i < len; i++){ 
         attrName = element.attributes[i].nodeName; 
         attrValue = element.attributes[i].nodeValue; 
         if (element.attributes[i].specified){ 
             pairs.push(attrName + "=\"" + attrValue + "\""); 
         } 
     } 
     return pairs.join(" "); 
} 

四、文本操作


最后来个思维导图,方便记忆。
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值