10.13.JS-DOM(二):dom选择器,节点类型

1,678 阅读3分钟

DOM基本操作

  • 对节点的增删改查
    • 查看元素节点
      • document代表整个文档
      • document.getElementById() // 元素id在IE8以下的浏览器,不区分id大小写,而且匹配name属性的元素
      • .getElementByTagName() // 标签名
      • .getElementByName(); // 需注意,只有部分标签name可生效(表单,表单元素,img,iframe)
      • .getElementByClassName() // 类名 -> IE8和IE8以下IE版本中没有,可以多个class
      • .querySelector() // css选择器 在IE7和IE7以下版本中没有,静态选择器
      • .querySelectorAll() // css选择器 在IE7和IE7以下版本中没有
  • 遍历节点树
    • parentNode -> 父节点(最顶端的parentNode为#document)
    • childNodes -> 子节点们
    • firstChild -> 第一个子节点
    • lastChild -> 最后一个子节点
    • nextSibling -> 后一个兄弟节点 previousSibling -> 前一个兄弟节点
  • 基于元素节点树的遍历
    • parentElement -> 返回当前元素的父元素节点(IE不兼容)
    • children -> 只返回当前元素的元素子节点
    • node.childElementCount === node.children.length 当前元素节点的子元素节点个数(IE不兼容)
    • firstElementChild -> 返回的是第一个元素节点(IE不兼容)
    • lastElementChild -> 返回的是最后一个元素节点(IE不兼容)
    • nextElementSibling/previousElementSibling -> 返回后一个/前一个兄弟元素节点(IE不兼容)
  • 节点的类型
    • 元素节点 1
    • 属性节点 2
    • 文本节点 3
    • 注释节点 8
    • document 9
    • DocumentFragment 11
  • 节点的四个属性
    • nodeName
      • 元素的标签名,以大写形式表示,只读
    • nodeValue
      • Text节点或Comment节点的文本内容,可读写
    • nodeType
      • 该节点的类型,只读
    • attributes
      • Element 节点的属性集合
  • 节点的最后一个方法 Node.hasChildNodes()

返回子元素节点对象

<div>
  123
  <!-- This is comment -->
  <strong></strong>
  <span></span>
</div>
<script>
  var div = document.getElementsByTagName("div")[0];
  // 返回子元素节点对象
  function retElementChild(node) {
    var temp = {
      length: 0,
      push: Array.prototype.push,
      splice: Array.prototype.splice
    },
      child = node.childNodes,
      len = child.length;
    for (var i = 0; i < len; i++) {
      if (child[i].nodeType === 1) {
        temp.push(child[i]);
      }
    }
    return temp;
  }
  console.log(retElementChild(div));
</script>

DOM结构树

  • Node -> Document(文档) -> HTMLDocument
  • Node -> CharacterData -> Text/Comment
  • Node -> Element(文档中的元素) -> HTMLElement -> HTMLHeadElement/HTMLBodyElement/HTMLTitleElement/HTMLParagraphElement/HTMLInputElement/HTMLTableElement...
  • Node -> Attr

方法

  1. getElementById 方法定义在Document.prototype上,即Element节点上不能使用。
  2. getElementByName 方法定义在HTMLDocument.prototype上,即非html中的document不能使用(xml document,Element)
  3. getElementsByTagName 方法定义在Document.prototype和Element.prototype上
  4. HTMLDocument.prototype定义了一些常用的属性,body.head 分别指代HTML文档中的标签
  5. Document.prototype上定义了documentElement属性,指代文档的跟元素,在HTML文档中,它总指代元素
  6. getElementsByClassName、querySelectAll、querySelector在Document.prototype,Element.prototype类中均有定义

封装函数,返回元素e的第n层祖先元素节点 parentElement

function retParent(elem, n) {
  while (elem && n) {
    elem = elem.parentElement;
    n--;
  }
  return elem;
}

编辑函数,封装myChildren功能,解决以前部分浏览器的兼容性问题

Element.prototype.myChildren = function () {
  var child = this.childNodes;
  var len = child.length;
  var arr = [];
  for (var i = 0; i < len; i++) {
    if (child[i].nodeType == 1) {
      arr.push(child[i]);
    }
  }
  return arr;
}

封装函数,返回元素e的第n个兄弟元素节点,n为正,返回后面的兄弟元素节点;n为负,返回前面的;n为0,返回自己。

function retSibling(e, n) {
  while (n && e) {
    if (n > 0) {
      if (e.nextElementSibling) {
        e = e.nextElementSibling;
      } else {
        for (e = e.nextSibling; e && e.nodeType != 1; e = e.nextSibling);
      }
      n--;
    } else {
      if (e.previousElementSibling) {
        e = e.previousElementSibling;
      } else {
        for (e = e.previousSibling; e && e.nodeType != 1; e = e.previousSibling);
      }
      n++;
    }
  }
  return e;
}

增、插、删、替换

  • document.createElement();
  • document.createTextNode();
  • document.createComment();
  • document.createDocumentFragment();
  • parentNode.appendChild();
  • parentNode.insertBefore(a,b);
  • parent.removeChild();
  • child.remove();
  • 替换
  • parent.replaceChild(new,origin)

Element节点

  • innerHTML、innerText(火狐不兼容)/textContent(老版本IE不好使)
  • Element节点的一些方法
  • ele.setAttribute()
  • ele.getAttribute()

js生成DOM结构

// 请编写一点JavaScript脚本生成下面这段DOM结构。要求:使用标准的DOM方法或属性
//<div class="example">
//  <p class="slogan">ll</p>
//</div>
var div = document.createElement('div');
var p = document.createElement('p');
div.setAttribute('class','example');
p.setAttribute('class','slogan');
var text = document.createTextNode('ll');
p.appendChild(text);
div.appendChild(p);
document.body.appendChild(div);

对目标节点内部的节点顺序逆序 appendChild

Element.prototype.reverseChild = function () {
  var child = this.children,
    len = child.length;
  for (var i = len - 2; i >= 0; i--) {
    this.appendChild(child[i])
  }
  return this;
}

封装函数insertAfter();功能类似insertBefore(); appendChild

Element.prototype.insertAfter = function (targetNode, afterNode) {
  var beforeNode = afterNode.nextElementSibling;
  if (beforeNode == null) {
    this.appendChild(targetNode);
  } else {
    this.insertBefore(targetNode, beforeNode);
  }
}