zishu's blog

zishu's blog

一个热爱生活的博主。https://zishu.me

DOM--文書オブジェクトモデル

DOM の中国語名は文書オブジェクトモデル、英語名は Document Object Model で、略して DOM と呼ばれます。これは html と xml 文書に対する API であり、html を木構造で表現することで、文書構造をより直感的に研究することができます。この木構造の文書構造を DOM ツリーまたはノードツリーと呼びます。同じ概念です。

一、DOM とは何ですか?#

DOM の中国語名は文書オブジェクトモデル、英語名は Document Object Model で、略して DOM と呼ばれます。これは html と xml 文書に対する API であり、html を木構造で表現することで、文書構造をより直感的に研究することができます。この木構造の文書構造を DOM ツリーまたはノードツリーと呼びます。同じ概念です。

js は dom ノードを通じて、文書の html タグ、属性、css スタイル、および具体的な内容を変更し、ページ内のすべてのイベントに応答することができます。

dom ツリー構造図

二、ノードツリー#

1. ノードタイプ#

  1. 文書ノード--Document
  2. タグノード--Element
  3. テキストノード--Text
  4. コメントノード--Comment
  5. 属性ノード--Attr

2. 属性#

  1. ノードタイプ--nodeType
  2. ノード名--nodeName
  3. ノード値--nodeValue
  4. 子ノード--childNodes
  5. 親ノード--parentNodes
  6. 前のノード--previousSibling
  7. 次のノード--nextSibling
  8. 最初の子ノード--firstChild
  9. 最後の子ノード--lastChild

3. 文書ノード--document#

(1) 取得#

  1. getElementById ()--id で要素を取得
<div id="demo">idで要素を取得</div>

<script>
    var demo = document.getElementById('demo');
    demo.onclick = function() {
        console.log('idで要素を取得')
    }
</script>

<!-- idがdemoの要素をクリックすると、コンソールに' idで要素を取得'と出力されます -->
  1. getElementsByName ()--name で要素を取得
<input type="text" name="int" value="nameで要素を取得1">
<input type="text" name="int" value="nameで要素を取得2">

<script>
    var int = document.getElementsByName('int');
    for(var i = 0;i < int.length; i++) {
        console.log(int[i].value);
    }
</script>

<!-- コンソールにnameがintの要素のvalue値が出力されます -->
  1. getElementsByTagName ()--タグ名で要素を取得
<div>タグ名で要素を取得1</div>
<div>タグ名で要素を取得2</div>

<script>
    var div = document.getElementsByTagName('div');
    for(var i = 0;i < div.length; i++) {
        console.log(div[i].innerHTML)
    }
</script>

<!-- コンソールにタグ名がdivの要素のテキスト内容が出力されます -->
  1. getElementsByClassName ()--class で要素を取得
<div class="demo">classで要素を取得1</div>
<div class="demo">classで要素を取得2</div>

<script>
    var demo = document.getElementsByClassName('demo');
    for(var i = 0;i < demo.length; i++) {
        console.log(demo[i].innerHTML)
    }
</script>

<!-- コンソールにclassがdemoの要素のテキスト内容が出力されます -->
  1. querySelector ()--セレクタで要素を取得

querySelector () の括弧の中には記号を付ける必要があります。classは.idは#タグはそのままタグ名TagNameを書きます。

<div>セレクタでタグ名を取得</div>
<div class="div">セレクタでclassを取得</div>
<div id="div">セレクタでidを取得</div>

<script>
    var divtag = document.querySelector('div');
    var divclass = document.querySelector('.div');
    var divid = document.querySelector('#div');

    divtag.onclick = function() {
        console.log('セレクタでタグ名を取得')
    };
    // タグdivをクリックすると、コンソールに"セレクタでタグ名を取得"と出力されます

    divclass.onclick = function() {
        console.log('セレクタでclassを取得')
    };
    // classがdivをクリックすると、コンソールに"セレクタでclassを取得"と出力されます

    divid.onclick = function() {
        console.log('セレクタでidを取得')
    };
    // idがdivをクリックすると、コンソールに"セレクタでidを取得"と出力されます
</script>
  1. querySelectorAll ()--セレクタで要素集合を取得

取得されるのは配列の集合です。

<input type="text" value="int1">
<input type="text" value="int2">
<input type="text" value="int3">

<script>
    var int = document.querySelectorAll('input')
    for(i = 0; i < int.length; i++) {
        console.log(int[i].value)
    }
</script>

<!-- ブラウザは順に`int1`,`int2`,`int3`を出力します -->

(2) 作成#

  1. createElement ()--要素(タグ)ノードを作成
<ul id="ul"></ul>

<script>
    var ul = document.getElementById('ul');
    ul.appendChild(document.createElement('li'))
</script>

ul の下に li タグが生成されたことが確認できます。

image

  1. createTextNode ()--テキストノードを作成
<ul id="ul"></ul>

<script>
    var ul = document.getElementById('ul');
    var li = ul.appendChild(document.createElement('li'));
    var node = document.createTextNode('私はliです');
    li.appendChild(node);
</script>

li タグの中にテキストが生成されました。

image

  1. createAttribute ()--属性ノードを作成
<input type="text">

<script>
    var int = document.getElementsByTagName('input')[0];
    var value = document.createAttribute('value');
    value.nodeValue = '属性ノードを作成して生成';
    int.setAttributeNode(value);
</script>

value 属性値が正常に作成されたことが確認できます。

image

  1. createComment ()--コメントノードを作成
<div id="div">コメントノードを作成</div>

<script>
    var div = document.getElementById('div');
    var comment = document.createComment('コメントノードを追加');
    div.appendChild(comment);
</script>

f12 でソースコードを確認すると、div に 1 行のコメントが生成されていることがわかります。

image

  1. createDocumentFragment ()--文書フラグメントを作成

文書フラグメントの役割は、追加されたすべてのノードの親要素に相当します。

  1. createDocumentFragment がなければ、多くのノードを追加しても、dom 上に表示されますが、追加するたびに appendChild () メソッドが呼び出され、多くのページレンダリングが発生し、冗長に見えます。
  2. 複数の追加ノードを createDocumentFragment ノードの中に置くと、ページは 1 回だけ呼び出してすべてのノードをレンダリングできます。
  1. createEvent ()--イベントオブジェクトを作成

  2. addEventListener ()--イベントリスナー関数を追加

  3. removeEventListener ()--イベントリスナー関数を削除

イベントリスナー関数の詳細

  1. dispatchEvent ()--イベントを発火

CSS 操作#

<div id="demo">dom</div>
<script>
    // 直接'.'を使ってstyleを操作
    var demo= document.getElementById('demo');
    demo.style.color = 'red';

    // setAttribute()を使って属性ノードを作成
    demo.setAttribute('style','background-color: green');

    // styleのcssText属性を使って
    demo.style.cssText = "border: 10px solid black";
</script>

4. 要素ノード(element オブジェクト)#

image

innerHTML, innerText, outerHTML, outerText の違いについて

一つは要素の内容、もう一つはテキストの内容です。

image

<div id="div1">最初のdiv</div>
<div id="div2">二番目のdiv</div>
<div id="div3">三番目のdiv</div>
<div id="div4">四番目のdiv</div>
<div id="div5"></div>
<div id="div6"></div>
<div id="div7"></div>
<div id="div8"></div>
<script>
    var div1 = document.getElementById('div1').innerHTML
    console.log(div1)   // 最初のdiv

    var div1 = document.getElementById('div1').outerHTML
    console.log(div1)   // <div id="div1">最初のdiv</div>

    var div2 = document.getElementById('div2').innerText
    console.log(div2)   // 二番目のdiv

    var div2 = document.getElementById('div2').outerText
    console.log(div2)   // 二番目のdiv

    document.getElementById('div5').innerHTML = '<a>《第5のdiv》</a>'
    // 既存のタグ内に内容を追加し、タグがあれば認識されます

    document.getElementById('div6').outerHTML = '<a>《第6のdiv》</a>'
    // 元のタグが上書きされ、新しいテキストにタグが含まれていれば自動的に生成され、タグがなければそのままテキストとして表示されます

    document.getElementById('div7').innerText = '<a>《第7のdiv》</a>'
    // 既存のタグ内に内容を追加し、新しいタグはタグ要素として認識されず、元のタグ内にテキスト内容として直接書き込まれます

    document.getElementById('div8').outerText = '<a>《第8のdiv》</a>'
    // 元のタグが上書きされ、新しいタグはタグ要素として認識されず、直接テキスト形式で表示されます
</script>

(1) ノード属性#

  1. childElementCount--現在の要素の子ノードの数を返します。
<div id="demo">
    <a></a>
    <span></span>
    <p></p>
    <div></div>
</div>

<script>
    var demo = document.getElementById('demo')
    console.log(demo.childElementCount) // 4
</script>
  1. firstElementChild--現在の要素の最初の子要素ノードを返します。
    lastElementChild--現在の要素の最後の子要素ノードを返します。
<div id="demo">
    <a></a>
    <span></span>
    <p></p>
    <div></div>
</div>

<script>
    var demo = document.getElementById('demo')
    console.log(demo.firstElementChild) // <a></a>
    console.log(demo.lastElementChild)  // <div></div>
</script>
  1. nextElementSibling--現在の要素の次の兄弟要素ノードを返します。
    previousElementSibling--現在の要素の前の兄弟要素ノードを返します。
<span></span>
<div id="demo"></div>
<p></p>

<script>
    var demo = document.getElementById('demo')
    console.log(demo.nextElementSibling)        // <p></p>
    console.log(demo.previousElementSibling)    // <span></span>
</script>
  1. 現在の要素のすべての子ノードを返します。
<div id="demo">
    <span></span>
    <p></p>
    <a></a>
</div>


<script>
    var demo = document.getElementById('demo').children
    for(var i in demo) {
        console.log(demo[i])
    }
</script>

コンソールで返された結果を確認します。

image

  1. すべての子ノード集合を返します。
<div id="demo">
    <span></span>
    <p></p>
    <a id="demo1"></a>
</div>


<script>
    var demo = document.getElementById('demo').children
    for(var i in demo1.childNodes) {
        console.log(demo[i])
    }
</script>

image

(2) ノードメソッド#

  1. appendChild--子ノードを挿入
<div id="demo"></div>
<script>
    var demo = document.getElementById('demo')
    var node = document.createTextNode('子ノードを挿入')
    demo.appendChild(node)
</script>  

f12 で確認すると、div にノードが挿入されていることがわかります。

image

  1. insertBefore (a, b)--指定位置にノードを挿入

パラメータ a は挿入する内容、b は位置を指定し、b ノードの前に a ノードを挿入します。

<div id="demo"></div>
<script>
    var demo = document.getElementById('demo')
    var node = document.createTextNode('子ノードを挿入')
    demo.appendChild(node)

    var hr = document.createElement('hr')
    demo.insertBefore(hr, node)
</script>  

元のテキストノードの前に新しい要素ノードが追加されたことが確認できます。

image

  1. replaceChild (a, b)--ノードを置き換える

パラメータ a でパラメータ b を置き換え、a は新しいノード、b は古いノードを示します。

<div id="demo"></div>
<script>
    var demo = document.getElementById('demo')
    var node = document.createTextNode('子ノードを挿入')
    demo.appendChild(node)

    var h3 = document.createElement('h3')
    var h3node = document.createTextNode('タイトル')
    h3.appendChild(h3node)
    demo.replaceChild(h3, node)
</script>  

h3は新しいノード、nodeは古いノードで、画像から見ると b が a を置き換え、成功したことがわかります。

image

  1. removeChild--親ノードが子ノードを削除
<div id="demo">
    <div id="son"></div>
</div>

<script>
    var demo = document.getElementById('demo')
    var son = document.getElementById('son')
    demo.removeChild(son)
</script>  

f12 で確認すると、id が son の要素ノードがdemo.removeChild()によって削除されたことがわかります。

image

  1. removeAttribute--属性ノードを削除
<div id="demo" class="div"></div>

<script>
    var demo = document.getElementById('demo')
    demo.removeAttribute('class')
</script>  

class 属性が削除されたことが確認できます。

image

  1. テキストノードを削除
<div id="demo">テキスト</div>

<script>
    var demo = document.getElementById('demo')
    demo.removeChild(demo.childNodes[0])
</script>  

demo.childNodes[0]で demo の最初のノード、つまりテキストノードを取得し、removeChildで削除します。

image

  1. isEqualNode--二つの要素が等しいかどうかを判断
    isSameNode--二つの要素が同じかどうかを判断

二つはそれぞれ等しい同じを表します。

(1) isEqualNodeの等しいは、二つのノードが同じタイプで、等しい属性(nodeName, nodeValue など)を持ち、attributes や childNodes も等しい(等しい位置に同じ値が含まれる)ことを指します。
(2) isSameNodeの同じは、二つのノードが同じオブジェクトを参照していることを指します。

<form action="#">
    <input type="button" />
</form>

<form action="#">
    <input type="button" />
</form>

<form action="#" id="o">
    <input type="button" />
</form>

<form action="#" id="o">
    <input type="text" />
</form>

<script>
    var forms = document.forms;

    var form1 = forms[0];
    var form2 = forms[1];
    var form3 = forms[2];
    var form4 = forms[3];
    var _form1 = document.querySelectorAll('form')[0];


    console.log(form1.isSameNode(form1))  //true  二つのノードが同じオブジェクトを参照しています
    console.log(form1.isSameNode(_form1)) //true  二つのノードが同じオブジェクトを参照しています
    console.log(form1.isSameNode(form2))  //false 二つのノードが同じオブジェクトを参照していません

    console.log(form1.isEqualNode(form2)) //true  二つのノードが完全に等しい属性を持っています
    console.log(form1.isEqualNode(form3)) //false form1には等しいid属性がありません
    console.log(form3.isEqualNode(form4))  //false form4のchildNodesのinputはtextタイプで、form3とは異なります
</script>

例のコードから違いがわかります:

(1) isSameNodeは同じオブジェクトを参照している場合のみ同じで、二つの方法で同じオブジェクトを呼び出し、比較しても同じオブジェクトであるため、同じです。
(2) isEqualNodeは二つのオブジェクトの要素ノードが等しいかどうかを比較し、一致すれば等しい true となります。

  1. hasChildNodes ()--要素が子ノードを持っているかどうかを判断

demoが子ノードを持っているかどうかを判断し、その子ノードを出力します。

<div id="demo">
    <!-- <a></a> -->
</div>

<script>
    var demo = document.getElementById('demo')
    console.log(demo.hasChildNodes())
    console.log(demo.childNodes)
</script>

image

  1. contains (a)--指定された子ノード(パラメータ a)を含むかどうかを判断

id="a"の要素が存在するため、contains は成功しtrueを出力します。

id="b"の要素は存在しないため、falseが出力されます。

<div id="demo">
    <a id="a"></a>
    <a></a>
</div>

<script>
    var demo = document.getElementById('demo')
    var a = document.getElementById('a')
    console.log(demo.contains(a))   // true

    var b = document.getElementById('b')
    console.log(demo.contains(b))   // false
</script>

5. 属性ノード(Attr オブジェクト)#

<input type="text" id="int">

<script>
    var int = document.getElementById('int')

    // 1.属性値を取得
    console.log(int.getAttribute("type"))   
    // text
    
    // 2.属性ノードを取得
    console.log(int.getAttributeNode("type"))
    // type="text"
    
    // 3.属性値を設定
    int.setAttribute("value", "inputボックス")
    // <input type="text" id="int" value="inputボックス">

    // 4.属性ノードを設定
    let name = document.createAttribute("name");
    name.nodeValue = "uname";
    int.setAttributeNode(name);
    console.log(int.getAttributeNode('name').value) 
    // <input type="text" id="int" value="inputボックス" name="uname">

    // 5.属性ノードを削除
    console.log(int.removeAttribute('name'))
    // <input type="text" id="int" value="inputボックス">

    // 6.属性が存在するかどうかを判断
    console.log(int.hasAttributes())
    // true

    // 7.指定された属性が存在するかどうかを判断
    console.log(int.hasAttribute('value'))
    // true
</script>

注意:hasAttributehasAttributesの違い
hasAttributesは属性が存在するかどうかを判断し、
hasAttributeは指定された属性が存在するかどうかを判断します。

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。