(二)JavaScript关于浏览器--操作DOM
二、操作DOM
HTML被解析后就是一颗DOM树,操作DOM就是对节点的几个操作:
更新,遍历,添加,删除
1.首先,要获取一个DOM节点,有两种方法:
第一种,直接定位唯一的一个节点document.getElementById();返回一组的节点document.getElementsByTagName();
以及CSS选择器document.getElementsByClassName()也是返回一组的DOM节点。也可以从父节点开始一步一步缩小范围,如下:
document.getElementById('table').getElementsByTagName('tr');
第二种,querySelector 和 querySelectorAll;querySelector返回的是一个对象,querySelectorAll返回的一个集合(NodeList)
a. 当用Document类型调用querySelector()方法时,会在文档元素范围内查找匹配的元素;而当用Element类型调用querySelector()方法时,只会在这个元素的后代元素中去查找匹配的元素。若不存在匹配的元素,则这两种类型调用该方法时,均返回null。
b. 当用Document类型调用querySelectorAll()方法时,匹配的所有Element对象;而当用Element类型调用querySelectorAll()方法时,只包含了Element元素的后代匹配该类选择器的Element对象。若不存在匹配的元素,均一个空的NodeList对象。
//获取页面I属性D为test的元素:
document.getElementById("test");
//or
document.querySelector("#test");
document.querySelectorAll("#test")[0];
//获取页面class属性为”red”的元素:
document.getElementsByClassName('red');
//or
document.querySelector('.red');
document.querySelectorAll('.red');
querySelectorAll 返回的是一个 Static Node List,是一个 li 集合的快照,对文档的任何操作都不会对其产生影响;而 getElementsBy 系列的返回的是一个 Live Node List,每一次调用 lis 都会重新对文档进行查询,导致无限循环的问题。
// Demo 1
var ul = document.querySelectorAll('ul')[0],
lis = ul.querySelectorAll("li");
for(var i = 0; i < lis.length ; i++){
ul.appendChild(document.createElement("li"));
}
// Demo 2
var ul = document.getElementsByTagName('ul')[0],
lis = ul.getElementsByTagName("li");
for(var i = 0; i < lis.length ; i++){
ul.appendChild(document.createElement("li"));
}
2.更新DOM
<!DOCTYPE html>
<html>
<body>
<p id="firid">...</p></br>
<p id="secid">...</p>
<script>
var p = document.getElementById('firid');
var pp = document.getElementById('secid');
// 设置文本:
p.innerHTML = 'innerHTML';
pp.innerText = "innerText";
</script>
</body>
</html>
修改CSS也是经常需要的操作。DOM节点的
style
属性对应所有的CSS,可以直接获取或设置。因为CSS允许
font-size
这样的名称,但它并非JavaScript有效的属性名,所以需要在JavaScript中改写为驼峰式命名
fontSize
:(获取标签,在修改样式)
// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px';
p.style.paddingTop = '2em';
3,插入DOM
有两个办法可以插入新的节点。一个是使用appendChild
,把一个子节点添加到父节点的最后一个子节点。
appendChild() 方法向节点添加最后一个子节点(是先获取一个节点,再把这个节点插入到父节点下)。
<!DOCTYPE html>
<html>
<body>
<ul id="myList1"><li>Coffee</li><li>Tea</li></ul>
<ul id="myList2"><li>Water</li><li>Milk</li></ul>
<p id="demo">在父节点mylist1下的最后添加一个子节点</p>
<button onclick="myFunction()">亲自试一试</button>
<script>
function myFunction(){
var node=document.getElementById("myList2").firstChild;//mylist2的第一个子节点
document.getElementById("myList1").appendChild(node);//获取mylist1,并完成插入
} //这个节点首先会从原先的位置删除,再插入到新的位置。
</script>
</body>
</html>
或者直接在要插入的地方创建一个节点
var
list = document.getElementById('list'),
haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);
第二种插入方法是:
使用parentElement.insertBefore(newElement,referenceElement);
,子节点会插入到referenceElement
之前。(在父节点下用这个函数添加节点到某一个节点前面)
<!DOCTYPE html>
<html>
<body>
<div id="list">
<p id="java">Java</p>
<p id="python">Python</p>
<p id="scheme">Scheme</p>
</div>
<script>
var list = document.getElementById('list');
var ref = document.getElementById('python');
var haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.insertBefore(haskell,ref);//在ref前添加
</script>
</body>
</html>
4.删除DOM
要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild
把自己删掉:(从它父节点删除一个节点)
// 拿到待删除节点:
var self = document.getElementById('to-be-removed');
// 拿到父节点:
var parent = self.parentElement;
// 删除:
var removed = parent.removeChild(self);