js dom編程

文檔邏輯結(jié)構(gòu)

DOM基礎概念、操作
DOM是什么
DOM全稱為The Document Object Model,應該理解為是一個規(guī)范,定義了HTML和XML文檔的邏輯結(jié)構(gòu)和文檔操作的編程接口。

文檔邏輯結(jié)構(gòu)
DOM實際上是以面向?qū)ο蠓绞矫枋龅膶ο竽P?,它將文檔建模為一個個對象,以樹狀的結(jié)構(gòu)組織(本文稱之為“文檔樹”,樹中的對象稱為“節(jié)點”)。
每個文檔包含1個document節(jié)點,0個或1個doctype節(jié)點以及0個或多個元素節(jié)點等。document節(jié)點是文檔樹的根節(jié)點。
如對于HTML文檔,DOM 是這樣規(guī)定的:

整個文檔是一個文檔節(jié)點

每個 HTML 標簽是一個元素節(jié)點

包含在 HTML 元素中的文本是文本節(jié)點

每一個 HTML 屬性是一個屬性節(jié)點

注釋屬于注釋節(jié)點

節(jié)點與文檔內(nèi)容是一一對應的關系,節(jié)點之間有層次關系。

例如下面的html文檔:

<!DOCTYPE html>
<html>
<head>
    <title>文檔標題</title>
</head>
<body>
<a href="">我的鏈接</a>
<h1>我的標題</h1>
</body>
</html>

[圖片上傳失敗...(image-2c214-1530240178333)]

nodeType

元素.nodeType:只讀 屬性 當前元素的節(jié)點類型

DOM節(jié)點的類型nodeType一種有12種,可以查看這里。

常用的節(jié)點類型包括:元素節(jié)點、文本節(jié)點、屬性節(jié)點:

元素節(jié)點 ELEMENT_NODE:1

屬性節(jié)點 ATTRIBUTE_NODE :2

文本節(jié)點 TEXT_NODE:3

<ul id="ul1" style="color: green">
    <li>1111</li>
    <li>1111</li>
    <li>1111</li>
    <li>1111</li>
</ul>
oUl = document.getElementById('ul1');
alert(oUl.nodeType); // 彈出1
alert(oUl.childNodes[0].nodeType); //彈出3
alert(oUl.attributes[0].nodeType); //彈出2
alert(oUl.attributes[0].name); //彈出'id'
alert(oUl.attributes.length); //彈出2
alert(oUl.attributes[0].value); //彈出'ul1'

attributes

元素.attributes:只讀 屬性 屬性列表集合

具體代碼可以查看NodeType中js代碼中alert的部分。

DOM節(jié)點

childNodes \ children

獲取第一級子元素

有兼容性問題(空白節(jié)點),nodeType屬性

firstChild \ firstElementChild

獲取子元素里的第一個

lastChild \ lastElementChild

獲取子元素里的最后一個

childNodes

元素.childNodes:只讀屬性 子節(jié)點列表集合

childNodes至包含一級子節(jié)點,不包含后輩孫級以下的節(jié)點

childNodes的兼容性問題:

標準瀏覽器下:childNodes包含了文本和元素類型的節(jié)點,并且也會包含非法嵌套的子節(jié)點;

非標準瀏覽器下,至包含元素類型的節(jié)點,IE7及以下不包含非法嵌套的子節(jié)點

oUl = document.getElementById('ul1');
alert(oUl.childNodes.length); //在標準瀏覽器下彈出9;在IE6、7彈出4。因為標準瀏覽器下,文本元素(在這里是換行符)也包含在childNodes里面了。

for (var i=0; i<oUl.childNodes.length; i++){
    oUl.childNodes[i].style.background = 'red'; //在標準瀏覽器下會報錯,因為文本元素(這里是換行符)沒有是沒有style屬性的。
}

//可以通過下面這種方式來解決:

for (var i=0; i<oUl.childNodes.length; i++){
    if (oUl.childNodes[i].nodeType == 1) {
        oUl.childNodes[i].style.background = 'red';
    }
}

children

元素.children:只讀 屬性 子節(jié)點列表集合

標準下: 只包含元素類型的節(jié)點,并且包含非法嵌套的子節(jié)點

非標準下:只包含元素類型的節(jié)點,IE7及以下不包含非法嵌套的子節(jié)點

這樣,如果把childNodes換為children的話,就不用進行nodeType的判斷了。

for (var i=0; i<oUl.children.length; i++){
    oUl.children[i].style.background = 'red';
    }

子節(jié)點和兄弟節(jié)點的操作

firstChild

元素.firstChild:只讀 屬性 第一個子節(jié)點

標準下:firstChild會包含文本類型的節(jié)點

非標準下: 只包含元素節(jié)點

firstElementChild

元素.firstElementChild:只讀 屬性

標準下獲取第一個元素類型節(jié)點的子節(jié)點

非標準瀏覽器不支持

因此要進行判斷:

if (oUl.firstElementChild){
    oUl.firstElementChild.style.background = 'red';
} else {
    oUl.firstChild.style.background = 'red';
}

//更為簡潔的寫法:

var oFirst = oUl.firstElementChild || oUl.firstChild;
oFirst.style.background = 'red';

lastChild、lastElementChild

元素.lastChild
元素.lastElementChild 最后一個子節(jié)點
原理與firstChild
firstElementChild相似,不再贅述
nextSibling、previousSibling

元素.nextSibling
元素.nextElementSibling 下一個兄弟節(jié)點
元素.previousSibling
元素.previousElementSibling 上一個兄弟節(jié)點
父節(jié)點

parentNode

<ul id="ul1">
    <li>1111 <a href="javascript:;">隱藏</a></li>
    <li>2222 <a href="javascript:;">隱藏</a></li>
    <li>3333 <a href="javascript:;">隱藏</a></li>
    <li>4444 <a href="javascript:;">隱藏</a></li>
</ul>
var oA = document.getElementsByTagName('a');
for (var i=0; i<oA.length; i++){
    oA[i].onclick = function(){
        this.parentNode.style.display = 'none';
    }
}

元素.parentNode: 只讀 屬性 只有一個 當前節(jié)點的父級節(jié)點

offsetParent

<head>
    <style>
        div {padding: 40px 50px;}
        #div1 {background: red;}
        #div2 {background: green;}
        #div3 {background: orange;}
    </style>
</head>
<body id="body1">
    <div id="div1">
        <div id="div2">
            <div id="div3"></div>
        </div>
    </div>
</body>
var oDiv3 = document.getElementById('div3');
alert(oDiv3.parentNode.id); //彈出div2
alert(oDiv3.offsetParent.id); //彈出body1

上面的代碼,如果給div1的style里面加上position: relative; 那么div3的offsetParent就變成了div1

元素.offsetParent:只讀 屬性 離當前元素最近的一個有定位的父節(jié)點

如果沒有定位父級,默認是body

操作元素屬性的多種方式

點的形式和中括號形式

通過.點的形式:oText.value

通過中括號[]的形式:oText[‘value’] (當屬性名用變量來表示的時候,用中括號)

getAttribute、setAttribute、removeAttribute

元素.getAttribute(屬性名稱); 方法 獲取指定元素的指定屬性的值

元素.setAttribute(屬性名稱, 屬性值); 方法 給指定元素指定的屬性設置值

元素.removeAttribute(屬性名稱); 方法 移除指定的元素的指定的屬性

set/get與用點.的區(qū)別:

用.和[]的形式無法操作元素的自定義屬性;getAttribute可以操作元素的自定義屬性

用.和[]的形式來獲取src的時候,獲取的是一長串絕對路徑,但是在IE8以上以及標準瀏覽器中,用getAttribute(‘src’)可以獲取到相對路徑(但是在IE7及以下,獲取的src還是絕對路徑)

元素的創(chuàng)建操作

document.createElement();

document.createElement(標簽名);

動態(tài)創(chuàng)建元素

不會直接顯示在頁面當中

前面必須是document,不能是其他

appendChild()

父級.appendChild(要追加的元素)


<!DOCTYPE html>
<html lang="en">
<head>
    <style>
        div {
            padding: 40px 50px;
        }

        #div1 {
            background: red;
            position: relative;
        }

        #div2 {
            background: green;
            position: relative;
        }

        #div3 {
            background: orange;
        }
    </style>
    <script>
        window.onload = function () {
            var btn = document.getElementById('btn');
            var ul = document.getElementById('ul');
            btn.onclick = function () {
                var li = document.createElement('li');//<li></li>
                li.innerHTML = 'zhangsan';
                ul.appendChild(li)
            }
        }
    </script>
</head>
<body id="body1">
    <button id="btn">娣誨姞li</button>
   <ul id="ul">

   </ul>
</body>
</html>

方法

在指定父級子節(jié)點最后一個后面追加子元素

insertBefore()

父級.insertBefore(新的元素,指定的被插入的元素);

方法

在父級的指定子元素前面插入一個新元素

在IE下,如果第二個參數(shù)的節(jié)點不存在,會報錯

在其它標準瀏覽器下,如果第二個參數(shù)的節(jié)點不存在,則會以appendChild的方式進行添加

removeChild()

父級.removeChild(要刪除的節(jié)點);
或者 元素.remove();

replaceChild()

父級.replaceChild(新節(jié)點、被替換節(jié)點) 替換子節(jié)點

appendChild,insertBefore,replaceChild可以操作靜態(tài)節(jié)點,也可以操作動態(tài)生成的節(jié)點。

window.onload = function () {
            var btn = document.getElementById('btn');
            var ul = document.getElementById('ul');
            var content = document.getElementById('text');
            btn.onclick = function () {
                var li = document.createElement('li');//<li></li>
                li.innerHTML = content.value;
                var a = document.createElement('a');
                a.href = '#';
                a.innerHTML = 'Delete';
                a.onclick = function () {
                    this.parentNode.remove();
                }
                li.appendChild(a);
                ul.appendChild(li);
            }
        }

表單操作

name

name:表單中可以通過name來獲取元素:父級.name (該方法瀏覽器都兼容)

onchange事件

onchange事件:當值發(fā)生改變的時候觸發(fā)
text:當光標離開的時候,如果內(nèi)容有變化,就觸發(fā)
radio/checkbox:
標準下點擊的時候,只要值發(fā)生改變,就會觸發(fā);
非標準下,焦點離開的時候,如果值發(fā)生改變就觸發(fā)
select:一選擇不同的項,就觸發(fā)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<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="">請選擇城市</option>
        <option value="北京">北京</option>
        <option value="上海">上海</option>
    </select>

    <input type="button" value="按鈕" name="btn" />
</form>
<script>
    var oForm = document.getElementById('form1');
    oForm.text1.onchange = function(){
        alert(this.value); //注意,文本輸入框onchange的觸發(fā),是在輸入完畢之后,鼠標離開該文本框之后觸發(fā)
    }
    oForm.text1.oninput = function(){
      condole.log(this.value);//輸入一個字符,輸出一個字符
    }
    oForm.sex[0].onchange = function(){
// alert(1);
// alert(this.value);
    } //注意:oForm.sex其實是一個元素集合,因為name為sex的單選按鈕有兩個

    oForm.a[0].onchange = function(){
        alert(2);
    }

    // alert(oForm.city.value);
    oForm.city.onchange = function(){
        alert(this.value);
    }

    oForm.btn.onclick = function(){

//radio, checkbox 判斷當前的選項是否被選中
//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 + '未被選中');
            }
        }
    }
</script>

</body>
</html>

表格操作

<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>
var oTab = document.getElementById('tab1');
    alert(oTab.children[1].children[1].innerHTML); //什么也彈不出來,提示顯示oTab.children[1]未定義,這是因為如果在table中沒有添加tbody的話,瀏覽器會自動隱形添加一個tbody出來。因此,寫表格結(jié)構(gòu)時,最好添加上tbody。

正確的做法

<table width="100%" id="tab1" border="1px">
    <thead>
        <tr>
            <th>編號</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>
 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只能有一個)

tBodies:表格正文(DOM中規(guī)定tbody可以有多個)

tFoot:表格尾(DOM中規(guī)定tfoot只能有一個)

rows:行

cells:列

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table width="100%" id="tab1" border="1px">
    <thead>
    <tr>
        <th>編號</th>
        <th>姓名</th>
        <th>性別</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>

    </tbody>
</table>
<script>
    var data = [
        {id: 1, username: 'leo', sex: '男'},
        {id: 2, username: '小美', sex: '女'},
        {id: 3, username: '王亮', sex: '男'},
        {id: 4, username: 'zhangsan', 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');

        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);
    }
</script>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script>
        var data = [
            {id: 1, username: 'leo', sex: '男',age:32},
            {id: 2, username: '小美', sex: '女',age:32},
            {id: 3, username: '王亮', sex: '男',age:32},
            {id: 4, username: 'zhangsan', sex: '男',age:32},
            {id: 5, username: 'dddd', sex: '男',age:32}
        ];

        window.onload = function () {
//            var obj = {id: 1, username: 'leo', sex: '男'};
//            for(var p in obj)
//            {
//                alert(p);
//                alert(obj[p]);
//            }

            var oTab = document.getElementById('tab1');
            var oTbody = oTab.tBodies[0];
            for(var i = 0; i < data.length; i++)
            {
                var tr = document.createElement('tr');//<tr></tr>

//                var td1 = document.createElement('td');//<td></td>
//                td1.innerText = data[i].id;
//                tr.appendChild(td1);
//                var td2 = document.createElement('td');//<td></td>
//                td2.innerText = data[i].username;
//                tr.appendChild(td2);
//                var td3 = document.createElement('td');//<td></td>
//                td3.innerText = data[i].sex;
//                tr.appendChild(td3);

                for(var p in data[i])//{id: 2, username: '小美', sex: '女'}
                {
                    var td1 = document.createElement('td');//<td></td>
                    td1.innerText = data[i][p];
                    tr.appendChild(td1);
                }


                var td4 = document.createElement('td');//<td></td>
                var a = document.createElement('a');
                a.href = '#';
                a.innerText = '刪除';
                a.onclick = function () {
                    this.parentNode.parentNode.remove();
                    for(var j = 0; j < oTbody.rows.length; j++)
                    {
                        if(j % 2 != 0)
                        {
                            oTbody.rows[j].style.backgroundColor = 'blue';
                        }
                        else
                        {
                            oTbody.rows[j].style.backgroundColor = 'white';
                        }
                    }
                }

                td4.appendChild(a);
                tr.appendChild(td4);

                oTbody.appendChild(tr);
            }

            for(var j = 0; j < oTbody.rows.length; j++)
            {
                if(j % 2 != 0)
                {
                    oTbody.rows[j].style.backgroundColor = 'blue';
                }
                else
                {
                    oTbody.rows[j].style.backgroundColor = 'white';
                }
            }
        }
    </script>
</head>
<body>
<table width="100%" id="tab1" border="1px">
    <thead>
    <tr>
        <th>編號</th>
        <th>姓名</th>
        <th>性別</th>
        <th>年齡</th>
        <th>操作</th>
    </tr>
    </thead>
    <tbody>
        <!--<tr>-->
            <!--<td>1</td>-->
            <!--<td>leo</td>-->
            <!--<td>男</td>-->
        <!--</tr>-->
    </tbody>
</table>

</body>
</html>

<!DOCTYPE html>
<html>
<head>
<title>購物車</title>
<meta charset="utf-8" />
    <style type="text/css">
    h1 {
    text-align:center;
}
table {
    margin:0 auto;
    width:60%;
    border:2px solid #aaa;
    border-collapse:collapse;
}
table th, table td {
    border:2px solid #aaa;
    padding:5px;
}
th {
    background-color:#eee;
}
</style>

    <script>
        var map = new Map();//key:商品名,tr:購物車中的商品數(shù)量
        function compute_total_price() {
            var tbodys = document.getElementById('goods');
            var sum = 0;
            for(var i = 0; i < tbodys.rows.length; i++)
            {
                sum += parseInt(tbodys.rows[i].cells[3].innerText);
            }

            document.getElementById('total').innerText = sum;
        }
        
        function decrease(obj) {
            var count = parseInt(obj.nextElementSibling.value);
            if(count > 1)
            {
                count--;
            }
            else
            {
                del(obj.parentNode.parentNode.cells[4].children[0]);
            }
            obj.nextElementSibling.value = count;
            compute_price(obj.nextElementSibling);
        }
        function increase(obj) {
            var count = parseInt(obj.previousElementSibling.value);
            count++;
            obj.previousElementSibling.value = count;
            compute_price(obj.previousElementSibling);
        }
        function del(obj) {
           map.delete(obj.parentNode.parentNode.cells[0].innerText);
           obj.parentNode.parentNode.remove();
           compute_total_price();
        }
        function compute_price (obj) {
            var count = parseInt(obj.value);
            var price = parseInt(obj.parentNode.previousElementSibling.innerText);
            var total_price = price * count;
            obj.parentNode.nextElementSibling.innerText = total_price;
            compute_total_price();
        }
        window.onload = function () {
            var goods = document.getElementById('goods_list');
            var tbody = document.getElementById('goods');
            var inputs = goods.getElementsByTagName('input');





            for(var i = 0; i < inputs.length;i++)
            {

                inputs[i].onclick = function () {
                    var good_name = this.parentNode.parentNode.cells[0].innerText;
                    if(map.has(good_name))
                    {
                        var tr = map.get(good_name);
                        var str_count = tr.cells[2].children[1].value;
                        var count = parseInt(str_count) + 1;
                        tr.cells[2].children[1].value = count;
                        compute_price(tr.cells[2].children[1]);
                    }
                    else
                    {

                        var good_price = this.parentNode.parentNode.cells[1].innerText;
                        var cart_item = `
      <td>${good_name}</td>
      <td>${good_price}</td>
      <td align="center">
        <input type="button" value="-" onclick="decrease(this)"/>
        <input type="text" size="3" value="1"/>
        <input type="button" value="+" onclick="increase(this)"/>
      </td>
      <td>${good_price}</td>
      <td align="center">
          <input type="button" value="x" onclick="del(this)"/>
      </td>
    `;
                        var tr = document.createElement('tr')
                        tr.innerHTML = cart_item;
                        tbody.appendChild(tr);
                        map.set(good_name,tr);
                        compute_total_price();
                    }
                }
            }
        }
    </script>
</head>
<body>
<h1>真劃算</h1>
<table id="goods_list">
    <tr>
        <th>商品</th>
        <th>單價(元)</th>
        <th>顏色</th>
        <th>庫存</th>
        <th>好評率</th>
        <th>操作</th>
    </tr>
    <tr>
        <td>羅技M185鼠標</td>
        <td>80</td>
        <td>黑色</td>
        <td>893</td>
        <td>98%</td>
        <td align="center">
            <input type="button" value="加入購物車" />
        </td>
    </tr>
    <tr>
        <td>微軟X470鍵盤</td>
        <td>150</td>
        <td>黑色</td>
        <td>9028</td>
        <td>96%</td>
        <td align="center">
            <input type="button" value="加入購物車" />
        </td>
    </tr>
    <tr>
        <td>洛克iphone6手機殼</td>
        <td>60</td>
        <td>透明</td>
        <td>672</td>
        <td>99%</td>
        <td align="center">
            <input type="button" value="加入購物車" />
        </td>
    </tr>
    <tr>
        <td>藍牙耳機</td>
        <td>100</td>
        <td>藍色</td>
        <td>8937</td>
        <td>95%</td>
        <td align="center">
            <input type="button" value="加入購物車" />
        </td>
    </tr>
    <tr>
        <td>金士頓U盤</td>
        <td>70</td>
        <td>紅色</td>
        <td>482</td>
        <td>100%</td>
        <td align="center">
            <input type="button" value="加入購物車" />
        </td>
    </tr>
</table>

<h1>購物車</h1>
<table>
    <thead>
    <tr>
        <th>商品</th>
        <th>單價(元)</th>
        <th>數(shù)量</th>
        <th>金額(元)</th>
        <th>刪除</th>
    </tr>
    </thead>
    <tbody id="goods">

  </tbody>
    <tfoot>
    <tr>
        <td colspan="3" align="right">總計</td>
        <td id="total"></td>
        <td></td>
    </tr>
    </tfoot>
</table>
</body>
</html>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容