Dom概念、Dom树、Dom查找

DOM概念

什么是DOM: Document Object Model,是W3C规定的专门操作网页内容的统一的API标准,用DOM操作网页内容,几乎兼容所有浏览器。

简述HTML DHTML XHTML XML的区别
HTML:专门编写网页内容的语言,标签名固定
XHTML:更严格的XHTML标准
DHTML:一切可以实现网页动态效果的技术的统称,包含:HTML+CSS+JS
XML:可扩展的标记语言,专门存储和传输格式化数据的结构化文档结构,标 签名自定义
JSON:用js对象的语法描述数据,用于互联网中的数据传输

DOM树

网页的所有内容,在内存中其实是以树形结构存储的,树型结构最适合保存上下级关系,且可无限向下延伸。

一. 如何创建

当浏览器读取到HTML内容时,会自动创建DOM树。

1.读到HTML文档时,先创建根节点:document,document对象是整棵DOM树的树根,所有网页内容,都是document节点的后代节点。

2.开始顺序读取HTML文档的内容,创建子节点,网页中一切内容都是DOM树上的节点对象。

二. 节点对象Node

三大属性

1.node.nodeType:表示节点的类型,值为数字(nodeType无法细致的区分每种元素的名称

 document:9
 元素节点:1
 属性节点:2
 文本节点:3
 DOCTYPE:10

2.node.nodeName:节点的名称

 document:#document
 元素节点:标签名(全大写)
 属性节点:属性名
 文本节点:#text
 DOCTYPE:html

3.node.nodeValue:节点的值,只用于获得属性的值和文本的内容

 document:null
 元素节点:null
 属性节点:属性值
 文本节点:文本内容
 DOCTYPE:null

节点关系

1.节点树

包含所有节点的树结构,一切文本都是节点对象,包括看不见的空字符,也是节点对象(tab,空格,换行)。

elem.parentNode => 获得elem的父节点,返回值: 唯一的一个父节点对象

elem.childNodes => 获得elem的所有直接子节点,返回值: 所有直接子节点组成的类数组对象(不支持数组api)

elem.firstChild => 获得elem的第一个子节点

elem.lastChild => 获得elem的最后一个子节点

elem.previousSibling => 获得elem的前一个兄弟节点

elem.nextSibling => 获得elem的后一个兄弟节点

2.元素树

仅包含元素节点的树结构,优点是仅包含元素节点,不受空文本的干扰;缺点是无法访问文本节点,解决方法elem.innerHTML—取元素节点中的文本内容(字符串)

elem.parentElement => 获得elem的父元素

elem.children => 获得elem的所有直接子元素,返回值: 所有直接子元素组成的类数组对象

elem.firstElementChild => 获得elem下的第一个子元素

elem.lastElementChild => 获得elem下的最后一个子元素

elem.previousElementSibling => 获得elem的前一个兄弟元素

elem.nextElementSibling => 获得elem的后一个兄弟元素

节点遍历

1.递归遍历(循环效率低)

由于children和childNodes都只能查找直接子节点,无法查找更深层次,如需遍历指定父节点下的所有子节点时,我们需要采用递归遍历,先定义函数,仅遍历直接子节点,再对每个直接子节点,再次调用当前遍历函数本身。

另一个问题是children和childNodes返回的所有直接子节点对象,保存在一个类数组对象中,是一个动态集合,动态集合的缺点是不实际存储对象的完整属性,每次访问动态集合时,都会反复去DOM树查找。解决方法是遍历时,首先将length属性的值保存在变量中,用变量作为循环条件。

for(var i = 0, len = children.length; i < len; i ++){}

遍历时采取深度优先遍历,即每次同时碰到子元素和兄弟元素时,总是优先遍历子元素。所有子元素遍历完,才返回遍历兄弟元素。

2.节点迭代器: NodeIterator

NodeIterator按照深度优先的原则,依次读取指定父节点下的每个节点。

首先创建NodeIterator对象:

// 所有节点
var iterator = document.createNodeIterator(parent, NodeFilter.SHOW_ALL,null, false);

//所有元素节点
var iterator = document.createNodeIterator(parent, NodeFilter.SHOW_ELEMENT,null, false);

反复调用迭代器的nextNode()方法获取下一个节点对象

// 让iterator跳到下一个节点。到头返回null
var currNode=iterator.nextNode();

iterator.previousNode();//退一个节点

nextNode方法返回的是当前节点,调用一次nextNode,只向前跳一个节点,如果没有后续节点,返回null。

do{
   var node = iterator.nextNode();
   if (node != null) {
    console.log(node.nodeName);
   } else break;
} while (true)

3.TreeWalker(基本用法和NodeIterator完全一样)

// 提供了向四周跳转的方法
var walker=document.creatTreeWalker(parent,NodeFilter.SHOW_ALL,null,false);
walker.parentNode();
walker.firstChild();
walker.lastChilde();
walker.previousSibling();
walker.nextSibling();

Dom查找

1.不需要查找就可直接获得的元素

<html> document.documentElement

<head> document.head

<body> document.body

2.按HTML查找

id查找:

// id查找只能用在document对象上
var elem = document.getElementById("id值");

标签名查找多个子元素:

// 可用在任意父元素上,不仅查找直接子元素,且查找所有后代中的元素
var elem = 任意parent.getElementsByTagName("标签名");

name属性查找:

// 只能用document调用
// 返回值动态集合,循环时要先用变量保存length
var elems = parent.getElementsByName("name");

class属性查找:

// 可在任意父元素上调用
// 不仅找直接子元素,且在所有后代中查找
// 返回动态集合,循环时要先用变量保存length
var elems = parent.getElementsByClassName("class");

3.用选择器查找

仅查找一个元素:

var elem = parent.querySelector("selector");

查找多个元素:

// 返回的是非动态集合,不会导致反复遍历DOM树
var elems = parent.querySelectorAll("selector");
// 可在任何父元素上调用
// 有浏览器的兼容性限制

getXXX vs Selector Api
执行效率:getXXX效率比SelectorAPI高
getXXX返回动态集合,不需要准备所有数据就可返回结果——快
selectorAPI,准备好所有相关数据,再返回——慢
返回值:
getXXX->动态集合,可能造成反复遍历DOM树
selectorAPI->非动态集合,不会导致反复遍历DOM树
如何选择:
如果一次getXXX查找即可找到结果时,首选getXXX
如果需要多次getXXX才能找到结果时,首选Selector API

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值