DOM (一)
什么是DOM(Document Object Model):专门操作网页内容的API
HTML:专门编写网页内容的语言
DHTML:所有实现网页动态效果的技术的统称
XHTML:更严格的HTML标准
XML:可扩展的标记语言--可以自定义标签名的语言
DHML 模型
- BOM(Browser Object Model):专门操作浏览器窗口的API,没有标准,所有用的很少
- DOM(Document Object Model):专门操作网页内容的API
- DOM:本来是可以操作一切结构化文档:HTML和XML
核心DOM:可以操作一切结构化文档的API
万能!但API繁琐
增删改查
HTML DOM:专门操作网页内容的API
其实是基于核心DOM的简化版本
API简洁!仅对复杂HTML元素提供了简化 -- 不是万能
实际开发中:优先使用HTML DOM
HTML DOM实现不了的,用核心DOM补充*
一、DOM tree
概念:保存所有网页内容的树状结构,网页中每个内容(元素、文本、属性...)都是树上的节点
DOM tree 的加载过程:
- [ ] 1、在开始加载网页内容前,先创建document节点,document节点是整棵DOM树的树根(查找、创建)
- [ ] 2、顺序读取网页内容,在document节点下,追加子节点
节点间关系
- [ ] 父子:parentNOde childNodes fristChild lastChild
- [ ] 兄弟:previousSibling nextSibling 强调:除了parentNode外,其余都会受空字符的干扰
遍历节点树:对每个子节点执行相同的操作
递归
概念:函数内,又调用了自己;
何时使用:遍历不确定层级深度树形结构时
如何实现递归:
- [ ] 1、先实现比列直接子节点的方法:
- [ ] childNodes是动态集合,只有访问动态集合,都会导致重新查找DOM树
- [ ] 优点:快速返回查找结果
- [ ] 缺点:每次访问动态集合,都要导致重新查找DOM树--效率低
- [ ] 遍历时:都要先将length属性存在变量中
- [ ] 2、对每个子节点,在执行和父节点相同的操作 算法:深度优先!优先遍历当前节点的子节点,子节点遍历完,才跳到兄弟节点
递归vs循环
- [ ] 1、递归:
- [ ] 优点:直观,易用
- [ ] 缺点:占用更多资源,效率低!
- [ ] 2、循环:
- [ ] 优点:几乎不占资源,效率高!
- [ ] 缺点:难度高,代码量大
一、DOM-递归
元素树:仅包含元素节点的树结构
何时使用:只希望访问元素节点时,就使用元素树
如何使用:
1、父子:parentElementNode
children 兼容IE8
firstElementChild
lastElementChild
2、兄弟:previousElementSibling
nextElementSibling
遍历API:
- 1、NodeItertor:按照深度优先的元素,依次遍历每个节点
- 如何使用:2步
- 1、创建NodeIterator
var iterator=document.createNodeIterator( parent, NodeFilter.SHOW_ALL/NodeFilter.SHOW_ELEMENT null,false );- 2、调用iterator的前进和后退方法,获得前一个或后一个节点对象 var node=iterator.nextNode();//下一个
强调:迭代器开始前,站在parent之前的位置 第一次nextNode()后,才会站在parent上开始遍历
如果nextNode返回null,说明遍历结束
var node=iterator.previousNode();
强调:previousNode如果仅调用一次,就留在原地 连续previousNode两次,才退一步- 2、TreeWalker:基本用法和NodeIterator完全相同
- 1、TreeWalker一开始就已经站在开始节点上
- 2、不但可前后移动,还可以向任意方向移动
- parentNode() firstChild() lastChild() previousSibling() nextSibling()
DOM-查找
1 按HTML查找
- ID
- 2、标签名
- name
- class属性
如果没有找到,返回空集合,length为0
2、Selector API:按CSS选择器查找元素 -- JQuery核心
- 何时使用:只要查找复杂时,最好用Selector API
- 如何使用:2个API
- 1.确定只会找到一个元素时,最好用Selector API
var elem=document.querySelector("任意css选择器") 万一选择器匹配多个,只返回第一个 强调:如果没找到,返回null- 2、希望查找多个选择器匹配的元素时
var elem=document.querySelectorAll("任意css选择器") 强调:querySelectorAll返回非动态集合 保存了完整的元素属性,每次访问非动态集合,不会导致重新检索DOM树
如果没有找到、返回空集合,length=0 缺点:返回的效率低
元素的内容
- 1、elem.innerHTML:获取或设置元素的开始标签到结束标签之间的HTML代码内容,没有兼容性问题;
- 何时使用:只要获得完整的HTML原文时;只要批量设置元素内容时,都要用innerHTML先拼接好字符串,在一次性赋值
- elem.textContent:获取或设置元素开始标签之间的纯文本的正文
- 忽略HTML标签:将特殊符号翻译为正文
- 有兼容性问题:老IE:elem.innerText
属性
DOM元素的所有属性节点都保存在一个集合中:attributes
可用下标或属性名访问每一个属性;
- 1、读取属性值:
核心DOM:elem.attributes[下标/"属性名"] //AttrNode- 1、elem.attributes[下标/"属性名"].value
- 2.*elem.getAttribute("属性名") //value
- elem.getAttributeNode("属性名") //AttrNode
elem.getAttributeNode("属性名").value //value
何时使用:万能即可获得标准属性,又可以获得自定义属性
HTML DOM:elem.属性名 - 只能获得标准属性
强调:凡是从页面读取到的属性值都是字符串
- 2、设置属性值:
核心DOM:- *elem.setAttribute("属性名","属性值")
- elem.setAttributeNode(attrNode)
何时使用:万能的,即可设置标准属性,又可以设置自定义属性
HTML DOM:elem.属性名=属性值 - 只能设置标准属性
强调:无论读取还是写入class属性
核心DOM:elem.get/setAttribute("class");
HTML DOM:elem.className
因为html的标准属性和JS对象中的内置属性class冲突,HTML-DOM中的class被迫改为className
- 3、移除属性
- 核心DOM:elem.removeAttribute("属性名");
何时使用:万能
HTML DOM:elem.属性名="" -- 相当于移除
何时使用:只能移除标准属性
- 核心DOM:elem.removeAttribute("属性名");
- 4、判断有没有
- 核心DOM:elem.hasAttribute("属性名") //返回bool
强调:万能,即可判断判断标准属性,又可以判断自定义属性
HTML DOM:elem.属性名!="";
- 核心DOM:elem.hasAttribute("属性名") //返回bool
样式
内联样式:优先级最高,会覆盖其他地方的样式,仅仅当前元素可用,不影响其他元素
获取:elem.style.css属性名
强调:带横线的属性名,都要去掉横线,变为驼峰命名,仅能获得内联样式,无法获得继承或层叠来的外部样式;
设置:elem.style.css属性名=‘属性名’
强调:一般程序修改样式,优先修改内联样式(1、优先级高2、不影响其他元素)
添加和删除元素
1、添加单个元素:3步
1、创建一个空元素
语法:var elem=document.createElement('标签名');
比如:var a = document.createElement('a');
<a></a>2、设置必要的属性
语法:elem.属性名=值;
elem.onclick=function(){...}
比如:
a.href="http://www.baidu.com"
a.innerHTML="百度一下"
<a href="http://www.baidu.com">百度一下</>将新元素,加载到指定的DOM树上的父元素
语法:parent(父元素放入名字).appendChild(elem) //将我们的elem追加到parent的最后一个子元素
parent.insertBefore(elem,已有元素) //将elem插入在"已有元素"前面 > parent.replaceChild(elem,已有元素) //将elem替换"已有元素"的位置强调:每一次修改DOM树,都会导致重新layout,频繁修改DOM树,会降低效率 解决:先在内存,将DOM树拼好,再整体加到DOM树里面
批量添加多个平级
- 1、创建一个文档片段:Document Fragment
文档片段:内存中临时存储多个DOM元素的临时父元素
何时使用:只要添加多个拼接子元素的时候,都要先将子元素,放入到我们的文档片段中保存(缓存)。
var frag=document.createDomentFragment();- 2、将子元素追加到文档片段里,临时保存
frag.appendChild(子元素);
其实frag的用法和普通父元素是完全一样- 3、将文档片段整体追加到页面
parent.appendChild(frag);
强调:Fragment不会出现在DOM树上
删除子元素:parent.removeChild(子元素);
HTML DOM
1、创建img元素:
var img=new Image();
<img>
img.src="";
强调:不是所有元素都可以new!只有个别可以
2、select对象:代表一个select元素
属性:option:获得select下所有的option子元素的集合!(下标访问、length属性、遍历)
方法:add(option):将option添加到select下,相当于:appendChild(option)
事件:onchange:当选中项发生改变的时候触发
3、option对象:代表select下面一个option
var opt= new Option(innerHTML,value)
相当于:
var opt=document.createElement("option")
opt.innerHTML
opt.value
简写:创建option后,立刻追加到select中
select.add(new Option(text,value));
4、table对象:代表HTML的table元素
属性:rows获得所有的行
方法:insertRow(i) 返回tableRow对象
deleteRow(i)删除掉下标选的行
5、tableRow对象:代表html表格行
属性:cells 获得所有的格(td)
innerHTML
rowIndex 获取当前tr在整个table中的下标
方法:insertCell(i) 返回tableCell对象
deleteCell(i) 删除掉下标为i的td
7、form对象:代表的是一个form元素
获得form元素:document.forms[i/"id"/"name"]
方法:submit();手动提交
事件:onsubmit:当正式提交表单之前,自动触发,专门用来在表单条件前,实现验证
查找表单里面的元素:form.elements[i/"id"/"name"]
可简写:form.id/name
只能找到带name属性的数据采集元素(input)或按钮
elem.focus();//让指定元素获得焦点