JS中級(jí)課程
(一)DOM元素的具體操作
DOM的概念及節(jié)點(diǎn)類(lèi)型
DOM:全稱(chēng)Document Object Model 文檔對(duì)象模型
- 文檔HTML頁(yè)面
- 文檔對(duì)象HTML頁(yè)面里面的元素
- 文檔對(duì)象模型: 一套定義,準(zhǔn)則為了能夠讓JS去操作頁(yè)面中的元素而定義出來(lái)的標(biāo)準(zhǔn)
DOM會(huì)把文檔看做是一棵樹(shù)愉豺,頁(yè)面中的每一個(gè)元素就是樹(shù)上的節(jié)點(diǎn)雀扶,同時(shí)DOM定義了很多方法秩仆,屬性來(lái)操作這棵樹(shù)中的每一個(gè)元素(節(jié)點(diǎn))---每一個(gè)節(jié)點(diǎn)稱(chēng)為DOM節(jié)點(diǎn)
DOM節(jié)點(diǎn)
獲取第一級(jí)子元素,也就是說(shuō)孫子節(jié)點(diǎn)獲取不了
有兼容性問(wèn)題(空白節(jié)點(diǎn),換行),用了childNodes必須使用nodeType
獲取子元素里面的第一個(gè)
獲取子元素里面的最后一個(gè)
1.childNodes
元素.childNodes:只讀屬性,子節(jié)點(diǎn)列表合集
childNodes包含一級(jí)子節(jié)點(diǎn),不包含后背孫子及其下面的節(jié)點(diǎn)
childNodes的兼容性
- childNodes包含了文本注釋元素類(lèi)型的節(jié)點(diǎn),并且也包含了非法嵌套的節(jié)點(diǎn)
- 非標(biāo)準(zhǔn)瀏覽器下面肴熏,包含元素類(lèi)型的節(jié)點(diǎn),IE7以下不包含非法節(jié)點(diǎn)
<ul id="ul1">
<li>111</li>
<li>111</li>
<li>111</li>
<li>111</li>
</ul>
上面是布局,下面是代碼
var ul = document.getElementById("ul1");
window.alert(ul.childNodes.length);
//標(biāo)準(zhǔn)瀏覽器彈出來(lái)9芬首;IE67彈出來(lái)4因?yàn)闃?biāo)準(zhǔn)瀏覽器換行也屬于文本節(jié)點(diǎn)
for(var i=0;i<ul.childNodes.length;i++)
{
ul.childNodes[i].style["background"] = "red";
//這里標(biāo)準(zhǔn)瀏覽器下面會(huì)報(bào)錯(cuò)誤,因?yàn)橛形谋竟?jié)點(diǎn)
}
//解決方案
for(var i=0;i<ul.childNodes.length;i++)
{
if(ul.childNodes[i].nodeType==1)
{
ul.childNodes[i].style["background"] = "red";
}
}
這樣就去掉了文本節(jié)點(diǎn)
PS:childNodes必須和nodeType一起使用敛滋,涉及到空白節(jié)點(diǎn)的問(wèn)題:元素節(jié)點(diǎn)的nodeType就是1,屬性節(jié)點(diǎn)就是2,文本節(jié)點(diǎn)nodeType就是3,注釋節(jié)點(diǎn)就是8,document節(jié)點(diǎn)就是9
2.children
元素.children 只讀子節(jié)點(diǎn)的列表合集田篇。她找的只是元素節(jié)點(diǎn)替废。不包括文本節(jié)點(diǎn)箍铭,注釋節(jié)點(diǎn)等等
for(var i=0;i<ul.children.length;i++)
{
ul.children[i].style["background"] = "red";
//這樣不會(huì)報(bào)錯(cuò)誤
}
3.nodeType
元素.nodeType:只讀,當(dāng)前元素的節(jié)點(diǎn)類(lèi)型
nodeName:獲取的就是節(jié)點(diǎn)的名稱(chēng)
4.attributes
元素.attributes:只讀屬性
屬性節(jié)點(diǎn)
<div id="div1"></div>
元素.attributes[0].nodeType 就是數(shù)字2 找的就是id屬性
元素.attributes[0].nodeValue 就是屬性值 div1
元素.attributes[0].nodeName 就是節(jié)點(diǎn)屬性名 id
注釋節(jié)點(diǎn)要是獲取值就是 xxx.childNodes[0].nodeValue 獲取的就是注釋里面的文字
子節(jié)點(diǎn)和兄弟節(jié)點(diǎn)
firstChild
她會(huì)包含文本節(jié)點(diǎn)和注釋節(jié)點(diǎn)。在IE678下只包含元素節(jié)點(diǎn)冗美,9以上全部包括
firstElementChild,IE678不支持,需要寫(xiě)兼容性
元素.firstElementChild只讀屬性
var Ofirst = ul.firstElementChild||firstChild;
if(Ofirst){
Ofirst.style.background = "red";
}else
{
window.alert("沒(méi)有節(jié)點(diǎn)可以選擇")
}
以上這段代碼會(huì)報(bào)錯(cuò)袁余。因?yàn)樵趏Ul下面沒(méi)有子元素節(jié)點(diǎn)状答,因此oUl.firstElementChild會(huì)返回為null,null不會(huì)傳給變量oFirst刀崖,所以oFirst等于oUl.firstChild惊科,而在標(biāo)準(zhǔn)瀏覽器下,oUl.firstChild是存在的亮钦,是一個(gè)文本節(jié)點(diǎn)馆截,因此在下面的判斷中,oFirst存在蜂莉,因此走if語(yǔ)句的第一句蜡娶,但是oFirst是文本節(jié)點(diǎn),沒(méi)有style可以設(shè)置映穗,因此會(huì)報(bào)錯(cuò)窖张。因此最好的做法是如下:
Ofirst.children[0].style["background"] = "red";
lastChild,lastElementChild
表示最后一個(gè)。同firstChild
nextSibling,previousSibling
元素.nextSibling下一個(gè)節(jié)點(diǎn)要是元素的是nextElementSibling
元素.previousSibling下一個(gè)節(jié)點(diǎn)要是元素的是previousSibling
父節(jié)點(diǎn)
元素.parentNode
offsetParent
找到當(dāng)前元素最近的一個(gè)有定位的父節(jié)點(diǎn)
- 要是沒(méi)有定位父級(jí)蚁滋,默認(rèn)就是body
offsetLeft ,offsetTop
元素.offsetLeft\offsetTop外邊框到有定位父級(jí)的內(nèi)邊框的距離(找到最近的)
要是沒(méi)有定位他找的就是距離body
getBoundingClientRect()
結(jié)果就是獲取到這個(gè)元素的所有信息宿接,返回的就是一個(gè)對(duì)象。然后在left,top之類(lèi)的辕录。這里特別注意的就是獲取的值會(huì)根據(jù)滾動(dòng)條變化的
offsetWidth,offsetHeight
- 元素.style.width :樣式寬就是width值帶單位
- clientWidth:樣式寬+padding,不帶單位
- offsetWidth:樣式寬+padding+border
- 高度一樣
操作元素的屬性的多種方式
- 通過(guò).點(diǎn)的形式 OText.value
- 通過(guò)中括號(hào)[]的形式:OText['value']當(dāng)屬姓名用變量表示睦霎,用中括號(hào)
getAttribute,setAttribute,removeAttribute
- 元素.getAttribute(屬性名稱(chēng)) 獲取指定元素指定屬性的值
- 元素.setAttribute(屬性名稱(chēng)) 給指定元素指定的屬性設(shè)置值
- 元素.removeAttribute(屬性名稱(chēng)) 移除指定元素的指定屬性
PS:set/get與.的區(qū)別
1.用.和中括號(hào)沒(méi)辦法操作自定義屬性,比如abc="234";getAttribute可以操作自定義屬性
2.用.和[]的形式來(lái)獲取src的時(shí)候走诞,獲取的是一長(zhǎng)串絕對(duì)路徑碎赢,但是在IE8以上以及標(biāo)準(zhǔn)瀏覽器中,用getAttribute(‘src’)可以獲取到相對(duì)路徑(但是在IE7及以下速梗,獲取的src還是絕對(duì)路徑)
節(jié)點(diǎn)創(chuàng)建
document.createElement(標(biāo)簽名)
- 動(dòng)態(tài)創(chuàng)建
- 不會(huì)直接顯示在頁(yè)面中
- 前面必須是document,不能是其他的
節(jié)點(diǎn)插入 appendChild()
父級(jí).appendChild(要追加的元素)
- 方法
- 在指定父級(jí)子節(jié)點(diǎn)最后一個(gè)后面追加子元素
insertBefore
父級(jí).insertBefore(新的元素.指定的被插入的元素)
var divnew = document.createElement("p");
divnew.innerHTML = "今天天氣不錯(cuò)";
divnew.style["color"] = "yellow";
document.getElementById("div1").insertBefore(divnew,document.getElementsByClassName("abc")[0]);
相當(dāng)于最外面是div1,然后在class是abc的前面插入p
- 在父級(jí)的指定子元素前面插入一個(gè)新的元素
- 在IE下要是第二個(gè)參數(shù)不存在會(huì)報(bào)錯(cuò)誤
- 在其他瀏覽器下肮塞。要是第二個(gè)參數(shù)不存在。則會(huì)用appendChild()來(lái)添加
removeChild
父級(jí).removeChild(要?jiǎng)h除的節(jié)點(diǎn))
replaceChild
父級(jí).replaceChild(新節(jié)點(diǎn),要替換的節(jié)點(diǎn))
appendChild,insertBefore,replaceChild既可以操作靜態(tài)節(jié)點(diǎn),也可以操作動(dòng)態(tài)節(jié)點(diǎn)
因?yàn)樵贘S里面沒(méi)有addclassName方法姻锁,和removeclassName方法所以我們需要自己寫(xiě)
添加className方法
var liall = document.getElementsByTagName("li");
for(var i=0;i<liall.length;i++)
{
addClassName(liall[i],"on");
}
/*添加類(lèi)*/
function addClassName(obj,className2)
{
if(obj.className=="")
{
obj.className="on";
}else
{
var Name = obj.getAttribute("class");
var arr = Name.split(" ");
var flag = false; //開(kāi)關(guān)
for(var i=0;i<arr.length;i++)
{
if(arr[i]==className2) //當(dāng)數(shù)組里面這個(gè)元素要是找到了證明他的存在枕赵,所以就沒(méi)必要添加了
{
flag = true;
}
}
if(!flag) //表示全部都沒(méi)找到
{
obj.className +=" "+className2;
}
}
}
/*添加類(lèi)結(jié)束*/
移除className方法
var liall = document.getElementsByTagName("li");
for(var i=0;i<liall.length;i++)
{
removeClassName(liall[i],"on");
}
/*移除class類(lèi)名*/
function removeClassName(obj,className2)
{
if(obj.className!="")
{
var string = obj.className; //獲取到類(lèi)名
var arr = string.split(" "); //切割成數(shù)組
var arrnew = [] ; //新的數(shù)組用來(lái)存儲(chǔ)
for(var i=0;i<arr.length;i++)
{
if(arr[i] != className2)
{
arrnew.push(arr[i]);
}
}
obj.className = arrnew.join(" ");
}
}
/*移除class類(lèi)名方法*/
表格操作
<table width="100%" id="tab1" border="1px">
<tr>
<td>1</td>
<td>leo</td>
<td>男</td>
<td><a href="javascript:;">刪除</a></td>
</tr>
<tr>
<td>1</td>
<td>小美</td>
<td>女</td>
<td><a href="javascript:;">刪除</a></td>
</tr>
</table>
因?yàn)闆](méi)有寫(xiě)tbody所以他根本沒(méi)辦法獲取到值
var oTab = document.getElementById('tab1');
alert(oTab.children[1].children[1].innerHTML);
//什么也彈不出來(lái),提示顯示oTab.children[1]未定義位隶,這是因?yàn)槿绻趖able中沒(méi)有添加tbody的話(huà)拷窜,瀏覽器會(huì)自動(dòng)隱形添加一個(gè)tbody出來(lái)。因此涧黄,寫(xiě)表格結(jié)構(gòu)時(shí)篮昧,最好添加上tbody。
下面這個(gè)是最正規(guī)的寫(xiě)法
<table width="100%" id="tab1" border="1px">
<thead>
<tr>
<th>編號(hào)</th>
<th>姓名</th>
<th>性別</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>leo</td>
<td>男</td>
<td><a href="javascript:;">刪除</a></td>
</tr>
<tr>
<td>1</td>
<td>小美</td>
<td>女</td>
<td><a href="javascript:;">刪除</a></td>
</tr>
</tbody>
</table>
因?yàn)閷?xiě)了tbody便可以彈出來(lái)
var oTab = document.getElementById('tab1');
// alert(oTab.children[0].children[1].children[1].innerHTML); //這是就可以彈出“小美”
alert(oTab.tBodies[0].rows[1].cells[1].innerHTML); //彈出小美笋妥,更為直觀
表格屬性
-
tHead:表格頭(DOM規(guī)定thead只能有一個(gè))
-
tBodies表格正文(DOM規(guī)定tbody可以有多個(gè))
-
tFoot表格尾(DOM規(guī)定只能有一個(gè))
- rows:行
- cells:列
表格數(shù)據(jù)的操作
<table width="100%" id="tab1" border="1px">
<thead>
<tr>
<th>編號(hào)</th>
<th>姓名</th>
<th>性別</th>
<th>操作</th>
</tr>
</thead>
<tbody></tbody>
</table>
下面是動(dòng)態(tài)創(chuàng)建表格
var data = [
{id: 1, username: 'leo', sex: '男'},
{id: 2, username: '小美', sex: '女'},
{id: 3, username: '王亮', sex: '男'},
{id: 4, username: '杜鵬', sex: '男'},
];
var oTab = document.getElementById('tab1');
var oTbody = oTab.tBodies[0];
for(var i=0; i<data.length; i++){ //表格的創(chuàng)建
var oTr = document.createElement('tr');
if(i%2 == 0){ //各行變色
oTr.style.background = 'white';
} else {
oTr.style.background = 'gray';
}
var oTd = document.createElement('td');
oTd.innerHTML = data[i].id;
oTr.appendChild(oTd);
oTd = document.createElement('td');
oTd.innerHTML = data[i].username;
oTr.appendChild(oTd);
oTd = document.createElement('td');
oTd.innerHTML = data[i].sex;
oTr.appendChild(oTd);
oTd = document.createElement('td');
// oTd.innerHTML = ' '; //如果單元格中的內(nèi)容為空懊昨,那么在IE7及以下,這個(gè)td不會(huì)被創(chuàng)建春宣,為了好看酵颁,給最后一列td里面添加一個(gè)空格嫉你,這樣在IE7下,最后一列td也會(huì)被創(chuàng)建
oTr.appendChild(oTd);
var oA = document.createElement('a');
oA.innerHTML = '刪除';
oA.href = 'javascript:;';
oA.onclick = function(){
oTbody.removeChild(this.parentNode.parentNode);
for(var i=0; i<oTbody.rows.length; i++){
if(i%2 == 0) {
oTbody.rows[i].style.background = 'white';
} else {
oTbody.rows[i].style.background = 'gray';
}
}
}
oTd.appendChild(oA);
oTbody.appendChild(oTr);
}
表單操作
<form id="form1">
<input type="text" name="text1" />
<input type="radio" name="sex" value="男" checked />男
<input type="radio" name="sex" value="女" />女
<input type="checkbox" name="a" value="html" checked />html
<input type="checkbox" name="a" value="css" />css
<input type="checkbox" name="a" value="javascript" />javascript
<select name="city">
<option value="">請(qǐng)選擇城市</option>
<option value="北京">北京</option>
<option value="上海">上海</option>
</select>
<input type="button" value="按鈕" name="btn" />
</form>
var oForm = document.getElementById('form1');
oForm.text1.onchange = function(){
alert(this.value); //注意躏惋,文本輸入框onchange的觸發(fā)幽污,是在輸入完畢之后,鼠標(biāo)離開(kāi)該文本框之后觸發(fā)
}
oForm.sex[0].onchange = function(){
// alert(1);
// alert(this.value);
} //注意:oForm.sex其實(shí)是一個(gè)元素集合簿姨,因?yàn)閚ame為sex的單選按鈕有兩個(gè)
oForm.a[0].onchange = function(){
alert(2);
}
// alert(oForm.city.value);
oForm.city.onchange = function(){
alert(this.value);
}
oForm.btn.onclick = function(){
//radio, checkbox 判斷當(dāng)前的選項(xiàng)是否被選中
//alert(oForm.sex[0].checked);
for(var i=0; i<oFrom.sex.length; i++){
if(oForm.sex[i].checked){
alert(oForm.sex[i].value + '被選中了');
} else {
alert(oForm.sex[i].value + '未被選中');
}
}
for(var i=0; i<oFrom.a.length; i++){
if(oForm.a[i].checked){
alert(oForm.a[i].value + '被選中了');
} else {
alert(oForm.a[i].value + '未被選中');
}
}
}
表單中的name來(lái)獲取元素父級(jí).name
window.alert(document.getElementById("form1").sex.value);
onchange事件
- onchange事件 :當(dāng)值發(fā)生改變的時(shí)候觸發(fā)
在type = text里面 :當(dāng)光標(biāo)離開(kāi)的時(shí)候距误,內(nèi)容有變化就觸發(fā)
在type = radio/checkbox :
在點(diǎn)擊下的時(shí)候只要值發(fā)生改變,就是觸發(fā)
在非標(biāo)準(zhǔn)情況下焦點(diǎn)離開(kāi)扁位,值發(fā)生改變才觸發(fā) - select 一選擇不同的項(xiàng)就觸發(fā)
onsubmit
- onsubmit:當(dāng)提交表單的時(shí)候觸發(fā)
- submit():方法提交表單
代碼見(jiàn)下
<form id="form1" action="http://www.baidu.com">
<input type="text" name="text1" />
<input type="text" name="text2" value="111" />
<input type="submit" name="dosubmit" value="提交" />
<input type="reset" name="doreset" value="重置" />
</form>
對(duì)應(yīng)的JS代碼
oForm.onsubmit = function(){
if(this.text1.value == ''){
alert('請(qǐng)輸入內(nèi)容');
return false; //如果沒(méi)有在文本框中填寫(xiě)任何內(nèi)容深寥,就寫(xiě)return false,那么點(diǎn)擊“提交”按鈕贤牛,也不會(huì)提交到http://www.baidu.com上
}
}
/* 讓頁(yè)面等待一秒鐘后自動(dòng)提交
setTimeout(function(){
oForm.submit();
}, 1000)
onreset
PS:注意是重置惋鹅,而不是清空,他的意思是恢復(fù)到默認(rèn)值
onreset:當(dāng)點(diǎn)擊重置按鈕的時(shí)候觸發(fā)
oForm.onreset = function(){
var re = window.confirm("你確定要重置嗎?")
return re;
}