【第5回 | JS WebAPI】3: DOMノードの操作

目次

| ノードの操作

1-1 概要

2-1 親ノードを取得する

3-1 子ノードの取得 (子オブジェクトをすべて取得することは推奨されません)

3-2 子ノードの取得(子[要素ノード]をすべて取得)

3-3 最初と最後の子ノードを取得する

4-1 兄弟ノードの取得

5-1 ノードを動的に作成および追加する

5-2 ケース:コメントエリア

5-4 ノードの削除

5-5 ノードの複製

| 包括的なケース: 動的フォーム生成

| 動的に作成される 3 つの要素の違い

| まとめ


| ノードの操作


1-1 概要

ノードとは何ですか?

  • Web ページ内のすべてのコンテンツはノード (ラベル、属性、テキスト、コメントなど) であり、DOM ではノードはノードによって表されます。通常は要素ノードを使用します

  • HTML DOM ツリー内のすべてのノードには JavaScript を介してアクセスでき、すべての HTML 要素 (ノード) を変更、作成、または削除できます。

  • 一般に、ノードには少なくとも3 つの基本属性、nodeType (ノード タイプ)、nodeName (ノード名)、nodeValue (ノード値) があります。

  • 実際の開発では、ノード操作は主に要素ノード上で動作します。

ノード操作とは何ですか?

コード例

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <span></span>
    </div>

    <script>
        // 如果以前想得到div和span元素,需要进行两步
        var divObj = document.getElementsByTagName('div');
        var spanObj = document.getElementsByTagName('span');

        // 而我们若使用节点操作来获取父元素,则只需要获取某一个元素对象,然后根据这个元素对象和其它元素对象的层级关系,使用对应的函数即可
        // span是div的父节点。我们得到了span,则只需要操作这个节点,使用parentNode就可以获取其父节点对象div了
        var spanObj2 = document.getElementsByTagName('span');
        divObj2 = spanObj2[0].parentNode;
        console.log(divObj2);  //div
    </script>
</body>
</html>

 


2-1 親ノードを取得する


3-1 子ノードの取得 (子オブジェクトをすべて取得することは推奨されません)

 

子要素のラベルと改行はノードとみなされます。次のコードのように、使用する場合

var ul = document.getElementsByTags('ul');

var lis = ul.childNodes;

コードを実行すると、2 li を含む要素オブジェクトの擬似配列だけでなく、5 つの要素オブジェクトの擬似配列も取得されます。

具体的な理由は以下の通りです

<ul>(换行 第一个节点)
	<li(标签,第二个节点)>XXX</li>(换行,第三个节点)
	<li(标签,第四个节点)>XXX</li>(换行,第五个节点)
</ul>

 


  • 要約すると、戻り値には要素ノード、テキスト ノードなどを含むすべての子ノードが含まれるためです。内部の要素ノードのみを取得したい場合は、特別に処理する必要があります。したがって、通常は childNode の使用を推奨しません。


3-2 子ノードの取得(子[要素ノード]をすべて取得)

parentNode.children

コード例(childNodeとchildrenの比較)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <span></span>
        <span></span>
        <span></span>
        <span></span>
    </div>

    <script>
        var divObj = document.querySelector('div');
        var children1 = divObj.childNodes;
        var children2 = divObj.children;

        var str1 = '';
        var str2 = '';

        for(var i=0 ; i<children1.length ; i++) {
            str1 += children1[i];
        }
        for(var i=0 ; i<children2.length ; i++) {
            str2 += children2[i];
        }

        console.log(str1); //[object Text][object HTMLSpanElement][object Text][object HTMLSpanElement][object Text][object HTMLSpanElement][object Text][object HTMLSpanElement][object Text]
        console.log(str2); //[object HTMLSpanElement][object HTMLSpanElement][object HTMLSpanElement][object HTMLSpanElement]

    </script>
</body>
</html>

 

 

3-3 最初と最後の子ノードを取得する

注意: firstChildで取得した子ノードには「改行などの非要素ノード」が含まれます

次の 2 つのメソッドは、最初と最後の子 [要素] ノードを取得できます。

 


実際の開発において、IE9 以下のバージョンのブラウザと互換性のある方法で firstElementChild と lastElementChild を取得するにはどうすればよいでしょうか?

実際の開発では、firstChild と lastChild に他のノードが含まれていて操作が不便で、firstElementChild と lastElementChild には互換性の問題があるため、最初の子要素ノードまたは最後の子要素ノードを取得するにはどうすればよいでしょうか。

解決:

1. 最初の子要素ノードが必要な場合は、parentNode.chilren[0] を使用できます。

2. 最後の子要素ノードが必要な場合は、parentNode.chilren[parentNode.chilren.length - 1] を使用できます。


4-1 兄弟ノードの取得

注意:この方法で取得した兄弟ノードには「改行などの非要素ノード」が含まれます。

 node.nextSibling  //返回当前元素的下一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。
 node.previousSibling  // 返回当前元素上一个兄弟元素节点,找不到则返回null。同样,也是包含所有的节点。

兄弟の子[要素]ノードを取得するには、以下の2つの方法があります。

 node.nextElementSibling   //返回当前元素下一个兄弟元素节点,找不到则返回null。
 node.previousElementSibling   //g 返回当前元素上一个兄弟节点,找不到则返回null。

IE9 以下のブラウザと互換性のある関数をカプセル化して、兄弟の子 [要素] ノードを取得できます。

 function getNextElementSibling(element) {
 	var el = element;
 	while (el = el.nextSibling) {
	 	if (el.nodeType === 1) {
	 		return el;
 		}
 	}
 	return null;
 } 

5-1 ノードを動的に作成および追加する

  • 使用シナリオ: ul に li を動的に追加する場合


コード例

基本手順: 親ノード要素を取得 → 挿入する要素を作成 → 要素を挿入

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <ul>

    </ul>
    <script>
        // 动态创建元素节点
        var liElement = document.createElement('li');
        // 把创建的元素节点加入(获取父节点 → 添加子节点)
        var ulNode = document.querySelector('ul');
        ulNode.appendChild(liElement);
    </script>
</body>
</html>

 


5-2 ケース:コメントエリア

中心となるアイデア: ボタンをクリックすると、li が動的に作成され、ul に追加されます。li の作成中に、li.innerHTML を通じてテキスト フィールドの値を li に割り当てます。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
        }

        li {
            list-style: none;
        }

        textarea{
            display: block;

            resize:none;  /* 取消拖拽 */
            outline: none;/* 取消选中高亮 */
            height: 200px;
            width: 500px;
            margin: 100px auto;
            margin-bottom: 30px;
            background-color: aliceblue;
            padding: 10px;

            font-family: 'Microsoft YaHei';
            font-size: 20px;
        }

        button {
            display: block;

            background-color: lightskyblue;
            width: 100px;
            height: 40px;
            margin: 0 auto;
        }

        ul {
            width: 500px;
            margin: 40px auto;
            background-color: lightgoldenrodyellow;
        }

        li {
            width: 500px;
            margin: 5px auto;
            height: 30px;
            border-bottom: 1px solid grey;
        }

    </style>
</head>
<body>
    <textarea placeholder="输入评论" name="comment"></textarea>
    <button>发布</button>
    <ul>
    </ul>

    <!-- 点击按钮,获取文本域,然后添加li -->
    <script>
        var btn = document.querySelector('button');
        var text = document.querySelector('textarea');

        btn.onclick = function(){
            // 获取文本域文本
            var textContent = text.value;
            //创建li节点
            var newLi = document.createElement('li');
            //添加li节点
            var ul = document.querySelector('ul');
            ul.appendChild(newLi);
            // 向li节点中添加内容 innerHTML
            newLi.innerHTML = textContent;
            // 清空文本
            text.value = '';
        }
    </script>
</body>
</html>

5-4 ノードの削除

コード例

 


5-5 ノードの複製

コード例

 


| 包括的なケース: 動的フォーム生成

Ajax をまだ学習していないため、データベースから動的にデータを取得できません。したがって、オブジェクトにデータを書き込みます

上記の知識を総合的に活用することに注意してください。

  • CSSとHTMLの知識

  • 配列ストレージオブジェクト

  • ループがイベントを作成する

  • テーブルのボディに行と列を挿入する方法

  • 削除ボタンの記述では、innerHTML メソッドを使用して HTML タグをレンダリングする必要があることに注意してください。

  • なお、削除する場合、削除されるのはaの親(tr)から相対的な親(td)、つまり削除した行の要素ノードになります。

サンプルコード:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        table {
            width: 500px;
            margin: 100px auto;
            border-collapse: collapse;
            text-align: center;
        }
        
        td,
        th {
            border: 1px solid #333;
        }
        
        thead tr {
            height: 40px;
            background-color: #ccc;
        }
    </style>
</head>

<body>
    <table cellspacing="0">
        <thead>
            <tr>
                <th>姓名</th>
                <th>科目</th>
                <th>成绩</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>

        </tbody>
    </table>
    <script>
        // 1.先去准备好学生的数据
        var datas = [{
            name: '魏璎珞',
            subject: 'JavaScript',
            score: 100
        }, {
            name: '弘历',
            subject: 'JavaScript',
            score: 98
        }, {
            name: '傅恒',
            subject: 'JavaScript',
            score: 99
        }, {
            name: '明玉',
            subject: 'JavaScript',
            score: 88
        }, {
            name: '大猪蹄子',
            subject: 'JavaScript',
            score: 0
        }];
        // 2. 往tbody 里面创建行: 有几个人(通过数组的长度)我们就创建几行
        var tbody = document.querySelector('tbody');
        for (var i = 0; i < datas.length; i++) { // 外面的for循环管行 tr
            // 1. 创建 tr行
            var tr = document.createElement('tr');
            tbody.appendChild(tr);
            // 2. 行里面创建单元格(跟数据有关系的3个单元格) td 单元格的数量取决于每个对象里面的属性个数  for循环遍历对象 datas[i]
            for (var k in datas[i]) { // 里面的for循环管列 td
                // 创建单元格 
                var td = document.createElement('td');
                // 把对象里面的属性值 datas[i][k] 给 td  
                // console.log(datas[i][k]);
                td.innerHTML = datas[i][k];
                tr.appendChild(td);
            }
            // 3. 创建有删除2个字的单元格 
            var td = document.createElement('td');
            td.innerHTML = '<a href="javascript:;">删除 </a>';
            tr.appendChild(td);

        }
        // 4. 删除操作 开始 
        var as = document.querySelectorAll('a');
        for (var i = 0; i < as.length; i++) {
            as[i].onclick = function() {
                // 点击a 删除 当前a 所在的行(链接的爸爸的爸爸)  a的爸爸是tr,tr的爸爸是td,因此删除的是td。注意使用的是this 
                tbody.removeChild(this.parentNode.parentNode)
            }
        }
        // for(var k in obj) {
        //     k 得到的是属性名
        //     obj[k] 得到是属性值
        // }
    </script>
</body>

</html>

 


| 動的に作成される 3 つの要素の違い

 

| まとめ

 

 

 

 

おすすめ

転載: blog.csdn.net/m0_57265007/article/details/127981342
おすすめ