一、获取 DOM 节点

  1. <!-- HTML结构 -->
  2. <div id="test-div">
  3. <div class="c-red">
  4. <p id="test-p">JavaScript</p>
  5. <p>Java</p>
  6. </div>
  7. <div class="c-red c-green">
  8. <p>Python</p>
  9. <p>Ruby</p>
  10. <p>Swift</p>
  11. </div>
  12. <div class="c-green">
  13. <p>Scheme</p>
  14. <p>Haskell</p>
  15. </div>
  16. </div>
  1. /**
  2. * 页面加载后执行
  3. */
  4. window.onload = function(){
  5. // 获取 <p>JavaScript</p>
  6. // 1. 通过 id 获取节点, id 是唯一的
  7. var jsOne = document.getElementById('test-p')
  8. // 2. 返回文档中与指定选择器或选择器组匹配的第一个 Element 对象。
  9. var jsTwo = document.querySelector('#test-p');
  10. // 获取 <p>Python</p>,<p>Ruby</p>,<p>Swift</p>
  11. // 1. 通过 class 名称,然后获取所有子节点
  12. var arrOne = document.getElementsByClassName('c-red c-green')[0].children;
  13. // 2. 返回文档中匹配指定 CSS 选择器的所有元素 class name 用 . 的形式,返回 NodeList 对象
  14. var arrTwo = document.querySelectorAll('.c-red.c-green > p');
  15. // 获取 <p>Haskell</p>
  16. // 1. c-green 的 class 名称有两个,因此我们获取后面那个,再获取最后一个子节点
  17. var haskellOne = document.getElementsByClassName("c-green")[1].lastElementChild;
  18. // 2. 使用 querySelectorAll 的方式
  19. var haskellTwo = document.querySelectorAll('.c-green')[1].lastElementChild;
  20. }

二、更新 DOM 节点

  1. <!-- HTML结构 -->
  2. <div id="test-div">
  3. <p id="test-js">javascript</p>
  4. <p>Java</p>
  5. </div>

修改 DOM 节点 css 样式

  1. var js = document.querySelector('#test-js');
  2. // js.innerHtml = 'JavaScript'
  3. js.innerText = 'JavaScript'
  4. // 修改 CSS 为: color: #ff0000, font-weight: bold
  5. js.style.color = '#ff0000';
  6. js.style.fontWeight = 'bold';

innerTextinnerHtml 都可以写入当前节点的值,区别在于 innerHtml 还可以写入 html 标签,如果在网络上获取,可能会被 XSS 攻击。

三、插入 DOM 节点

3.1 插入已经存在的 DOM 节点

如果原来的节点为空,可以用 innerHTML来增加节点。
如果原来的节点不为空,那么就不能用 innerHTML,因为它会直接替换掉原来的所有子节点,原来的就没了。

  1. <!-- HTML结构 -->
  2. <p id="js">JavaScript</p>
  3. <div id="list">
  4. <p id="java">Java</p>
  5. <p id="python">Python</p>
  6. <p id="scheme">Scheme</p>
  7. </div>

插入已经有的节点

  1. window.onload = function() {
  2. var js = document.getElementById('js');
  3. var list = document.getElementById('list');
  4. list.appendChild(js);
  5. }

会将原来的 <p id="js">JavaScript</p>删除,然后添加到 list 中。
执行后 html 结构如下:

  1. <!-- HTML结构 -->
  2. <div id="list">
  3. <p id="java">Java</p>
  4. <p id="python">Python</p>
  5. <p id="scheme">Scheme</p>
  6. <p id="js">JavaScript</p>
  7. </div>

大部分我们并不需要这样操作,而是插入新的节点。

3.2 插入新的节点

创建一个新节点,然后插入。

  1. window.onload = function() {
  2. var list = document.getElementById('list');
  3. // 创建一个新节点
  4. var haskell = document.createElement('p');
  5. haskell.id = 'haskell';
  6. haskell.innerText = 'Haskell';
  7. list.appendChild(haskell);

执行后 html 文档如下:

  1. <!-- HTML结构 -->
  2. <div id="list">
  3. <p id="java">Java</p>
  4. <p id="python">Python</p>
  5. <p id="scheme">Scheme</p>
  6. <p id="haskell">Haskell</p>
  7. </div>

3.3 动态增加样式

  1. var d = document.createElement('style');
  2. d.setAttribute('type', 'text/css');
  3. d.innerHTML = 'p { color: red }';
  4. document.getElementsByTagName('head')[0].appendChild(d);

3.3 插入节点到指定位置

  1. <div id="list">
  2. <p id="java">Java</p>
  3. <p id="python">Python</p>
  4. <p id="scheme">Scheme</p>
  5. </div>
  1. window.onload = function () {
  2. var list = document.getElementById('list');
  3. var ref = document.getElementById('python');
  4. var haskell = document.createElement('p');
  5. haskell.id = 'haskell';
  6. haskell.innerText = 'Haskell';
  7. // 将节点插入到 ref 节点之前
  8. list.insertBefore(haskell, ref);
  9. }

执行后,新的 html 文档如下:

  1. <!-- HTML结构 -->
  2. <div id="list">
  3. <p id="java">Java</p>
  4. <p id="haskell">Haskell</p>
  5. <p id="python">Python</p>
  6. <p id="scheme">Scheme</p>
  7. </div>

3.4 遍历子节点

  1. window.onload = function () {
  2. var i;
  3. var c;
  4. var list = document.getElementById('list');
  5. for (i = 0; i < list.children.length; i++) {
  6. c = list.children[i]; // 拿到第 i 个子节点
  7. console.log(c.innerHTML);
  8. }
  9. }

3.5 练习

对以下listli 文本的字符串顺序排列 DOM

  1. <!-- HTML结构 -->
  2. <ol id="test-list">
  3. <li class="lang">Scheme</li>
  4. <li class="lang">JavaScript</li>
  5. <li class="lang">Python</li>
  6. <li class="lang">Ruby</li>
  7. <li class="lang">Haskell</li>
  8. </ol>

思路:先获取所有的字符串,排序后,再修改文本值。

  1. window.onload = function () {
  2. var ol = document.getElementById("test-list");
  3. var arr = [];
  4. var li = ol.getElementsByClassName("lang");
  5. // 遍历
  6. for(let i = 0; i < li.length; i++){
  7. let liElementText = li[i].innerHTML;
  8. arr.push(liElementText);
  9. }
  10. console.log(arr); // output: ["Scheme", "JavaScript", "Python", "Ruby", "Haskell"]
  11. arr.sort();
  12. // 修改值
  13. for(let i = 0; i < arr.length; i++){
  14. let liElementCollection = document.getElementsByClassName("lang")
  15. liElementCollection[i].innerText = arr[i];
  16. }
  17. }

执行后,新的 html如下:

  1. <ol id="test-list">
  2. <li class="lang">Haskell</li>
  3. <li class="lang">JavaScript</li>
  4. <li class="lang">Python</li>
  5. <li class="lang">Ruby</li>
  6. <li class="lang">Scheme</li>
  7. </ol>

四、删除 DOM 节点

删除节点时需要获取当前节点和它的父节点。
调用父节点的 removeChild方法删除节点。

  1. <div id="parent">
  2. <p>First</p>
  3. <p>Second</p>
  4. </div>
  1. var parent = document.getElementById('parent');
  2. parent.removeChild(parent.children[0]);
  3. parent.removeChild(parent.children[1]); // <-- 浏览器报错

getElementById方法的返回值 Element 是实时更新的,删除第一个节点后,length 就变为 1,因此第二个删除就越界了。

练习

  1. <!-- HTML结构 -->
  2. <ul id="test-list">
  3. <li>JavaScript</li>
  4. <li>Swift</li>
  5. <li>HTML</li>
  6. <li>ANSI C</li>
  7. <li>CSS</li>
  8. <li>DirectX</li>
  9. </ul>

目的:留下 <li>JavaScript</li><li>HTML</li><li>CSS</li>,其他删除。

  1. window.onload = function () {
  2. let ulElement = document.getElementById('test-list');
  3. ulElement.removeChild(ulElement.children[1]);
  4. ulElement.removeChild(ulElement.children[2]);
  5. ulElement.removeChild(ulElement.children[3]);
  6. }

执行后,新的 html如下:

  1. <ul id="test-list">
  2. <li>JavaScript</li>
  3. <li>HTML</li>
  4. <li>CSS</li>
  5. </ul>

五、小结

5.1 获取节点

  • getElementById 返回一个匹配特定 ID 的元素, ID 是唯一的
  • getElementsByClassName 返回一个类数组对象
  • querySelector 返回文档中与指定选择器匹配的第一个 Element 对象。
  • querySelectorAll 返回 NodeList 对象

    5.2 更新节点

  • innerText 更新文本值

  • style 更新 css

    5.3 插入节点

  • appendChild 在父节点尾部位置插入节点。

  • insertBefore(newNode, referenceNode) 插入 newNode节点到 referenceNode节点之前。

    5.4 删除节点

    removeChild() 方法从 DOM 中删除一个子节点。返回删除的节点。