js大神不愿意告诉你dom的那些事

2023-06-02 0 804

DOM

甚么是DOM

Document Object Model

专门针对操作方式FTP的API国际标准

W3C

为何

国际标准化相同应用程序操作方式FTP的API

用DOM操作方式FTP,基本上大部份应用程序100%相容

DOM Tree

网页中大部份人文本都是结点(Node)第一类

大部份人结点第一类都储存在两个洼瓣内部结构中

根结点

document

结点第一类三大特性

nodeType

结点的类别

何时能

推论结点类别

document 9 elem 1 attr 2 text 3

难题:

难以更进一步推论原素的中文名称

化解

另见:

nodeName

结点中文名称

何时能

只要更进一步推论原素的中文名称

document #document elem 全大写标签名 attr 特性名 text #text

nodeValue

结点值

document null elem null attr 特性值 text 文本文本

DOM操作方式

构建DOM树

查找触发事件的原素

绑定事件

查找要操作方式的原素

修改

增加

删除

事件处理函数中的this

自动获得触发事件的当前原素

查找

不需要查找可直接获得的结点

document

document.documentElement

html

document.head

document.body

document.forms[i/”id”]

form

按结点间关系查找

何时能

已经获得两个结点,要找周围的相关结点时

结点树

包含大部份FTP(结点)的树内部结构

2大类关系

1. 父子

elem.parentNode

最靠谱

elem.childNodes

*直接*子结点

elem.firstChild

elem.lastChild

2. 兄弟

elem.previousSibling

elem.nextSibling

优: 完整

难题:

受看不见的空字符的干扰

化解

原素树

仅包含原素结点的树内部结构

不是一棵新树,仅是结点树的子集

何时能

只关心原素,不关心文本时

2大类关系

1. 父子

elem.parentElement

没有node结尾

elem.children

IE8+

elem.firstElementChild

elem.lastElementChild

2. 兄弟

elem.previousElementSibling

elem.nextElementSibling

优: 不受看不见的空字符的干扰

缺: 不包含大部份人文本结点

可用.innerHTML

相容性难题: IE9+

childNodes和children

都返回动态集合(live collection)

不实际储存数据,每次访问集合,都重新查找DOM树

优:

首次查找返回速度快

缺:

反复访问集合,会导致反复查找DOM树

遍历

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

递归遍历

何时能

只要遍历两个父结点下大部份后代结点

如何

//Step1: 仅遍历parent的直接子结点 function getChildren1(parent){ console.log(parent.nodeType!=3?

parent.nodeName:parent.nodeValue); var children=parent.childNodes; for(var i=0,len=children.length;i<len;i++){ //Step2: 为每个子结点调用和父结点完全相同的函数 arguments.callee(children[i]); } }

深度优先遍历

当同时有子结点和兄弟结点时,优先遍历子结点。大部份子结点遍历完,才遍历兄弟结点

难题: 递归的效率是极低

化解: 可用循环代替递归

function getChilddren2(parent){ //Step1: 创建迭代器第一类 var iterator=

document.createNodeIterator( parent, NodeFilter.SHOW_ALL , null, false .SHOW_ELEMENT ); var node; while((node=iterator.nextNode())!=null){ //node获得当前正在遍历的结点 console.log(node.nodeType!=3?

node.nodeName:node.nodeValue); } }

难题:

只能遍历大部份,如需筛选,得自己写推论

化解:

如何按条件查询

按HTML查找

按id

var elem=document.getElementById(“id”)

返回两个原素第一类

如果找不到,返回null

强调: 只能用在document上

按标签名

var elems=

parent.getElementsByTagName(“标签名”)

返回动态集合

如果找不到,返回空集合

强调:

可用在任意父结点上

不仅查找直接子结点,且查找大部份后代结点

按name

var elems=document.getElementsByName(“name”)

强调:

只能在document上调用

按class

var elems=parent.getElementsByClassName(“class”)

返回动态集合

如果找不到,返回空集合

强调:

可用在任意父结点上

不仅查找直接子结点,且查找大部份后代结点

只要class中包含指定的类名,就选择

相容性难题

IE9+

难题:

一次只能用两个条件查找,如果查找条件复杂时,会步骤繁琐

按选择器查找

Selector API

只找两个

var elem=parent.querySelector(“selector”)

找大部份符合条件的多个

var elems=parent.querySelectorAll(“selector”)

返回非动态集合

强调:

可在任意父原素上调用

受制于应用程序对选择器的相容性

按HTML vs 按选择器

1. 返回值:

按HTML

返回动态集合

selector API

返回非动态集合

直接储存大部份数据,反复访问集合,不需要反复查找DOM树

2. 首次查询效率

按HTML更高

仅返回需要的文本,不需要准备完整数据

selector API低

第一次要返回完整数据

3. 易用性:

按HTML繁琐

selector API简单

何时能

如果只凭两个条件即可获得想要的原素时,首选按HTML查找

如果需要多级复杂条件查找才能获得想要的原素时,用selector API

修改

文本

.innerHTML

.textContent

去掉大部份标签

翻译转义字符为正文

IE8:

.innerText

表单原素的文本

.value

特性

国际标准特性

核心DOM

操作方式大部份人内部结构化文档的通用API

即可操作方式HTML,又可操作方式XML

了解

var attrNode=elem.attributes[i/特性名] .getAttributeNode(“特性名”)

var value=attrNode.value

var value=elem.getAttribute(“特性名”)

修改

elem.setAttribute(“特性名”,特性值)

如果特性不存在,也可set

推论是否包含

var bool=elem.hasAttribute(“特性名”)

移除

elem.removeAttribute(“特性名”)

只移除开始标签中的attribute,不删除内存中第一类的property

特点

万能

繁琐

化解

HTML DOM

专门针对操作方式HTML文档的简化版API

只对部分常用API进行简化

如何

elem.特性名

大部份HTML国际标准特性都被封装在HTML DOM第一类中,可直接用.访问。用法普通第一类的特性完全一样

特点:

简单

不是万能

需要核心DOM的补充

状态特性

disabled, checked, selected

难题:

核心DOM不能操作方式:

化解:

HTML DOM

elem.状态

.checked .selected .disabled

选择器:

查找指定状态的原素

:checked :selected :disabled

扩展(自定义)特性

何时能

代替id,原素,class选择器,给多个原素添加行为

HTML DOM难以访问扩展特性

核心DOM

HTML5

定义:

data-特性名=”值”

访问:

elem.dataset.特性名

查找

CSS特性选择器

[data-特性名=值]

样式

内联样式:

elem.style.css特性名

强调:

css特性名要去横线变驼峰

何时能

专门针对用于修改内联样式

不影响其他原素的样式

优先级最高

难题:

难以访问从样式表层叠或继承来的完整样式

化解

计算后的样式:

最终应用到原素上的完整样式

包括大部份内联,内部,外部样式

将相对单位的值,计算为绝对单位

何时能

var style=getComputedStyle(elem第一类)

var value=style.样式特性名

强调:

通过getComputedStyle获得的样式第一类是只读

内部/外部样式表

修改样式表中的样式

var sheet=document.styleSheets[i]

var rule=sheet.cssRules[i]

如果获得的是keyframes,就需要继续找子rule

rule.style.样式特性=值

最好的修改样式的做法

修改class特性,批量应用样式

添加和删除

3步

创建新原素第一类

var elem=document.createElement(“标签名”)

设置关键特性

将原素添加到DOM树

parent.appendChild(child)

parent.insertBefore(child,oldChild)

parent.replaceChild(child,oldChild)

难题:

每操作方式一次DOM树,都会导致重新layout

化解

优化

尽量少的操作方式DOM树

如果同时添加父原素和子原素

先在内存中将子原素添加到父元素

再将父原素一次性添加到DOM树上

如果同时添加多个平级子原素

使用文档片段

甚么是

内存中临时储存多个子原素的虚拟父原素

3步:

创建文档片段

var frag=document.createDocumentFragment();

将子原素临时添加到frag中

frag.appendChild(child)

将frag添加到DOM树

parent.appendChild(frag)

强调:

frag不会成为页面原素,添加子原素后,frag自动释放

删除

parent.removeChild(child)

child.parentNode.removeChild(child)

HTML DOM常用第一类

Image

var img=new Image();

Select/Option

特性

value

当前选中项的value

如果选中项没有value,则使用文本

selectedIndex

当前选中项的下标

options

获得当前select下大部份option的集合

length

相当于.options.length

获得option的个数

清空option

.length=0

事件

onchange

当选中项发生改变时

方法

sel.add(option)

不支持文档片段

sel.remove(i)

Option

创建

var opt=new Option(text,value)

特性

text,value,index

Table/…

创建

var thead=.createTHead()

var tbody=.createTBody()

var tfoot=.createTFoot()

删除

.deleteTHead()

.deleteTFoot()

.tHead

.tBodies[i]

.tFoot

行分组

创建

var tr=.insertRow(i)

固定套路

1. 末尾追加一行: insertRow()

2. 开头插入一行: insertRow(0)

删除

.deleteRow(i)

难题

i难以自动获得

化解

首选

table.deleteRow(tr.rowIndex)

.rows

tr

创建

var td=.insertCell(i)

删除

.deleteCell(i)

.cells

删除行

行分组.deleteRow(i)

i是相对于当前行分组内的位置

table.deleteRow(tr.rowIndex)

rowIndex是相对于整个表中的位置

Form

var form=document.forms[i/id]

特性:

.elements

获得大部份表单原素的集合

input textarea select button

.length

.elements.length

获得大部份表单原素的个数

方法:

form.submit()

代替submit按钮,在程序中手动提交表单

Element

获得表单中的原素

获得任意表单原素:

form.elements[i/id/name]

如果表单原素有name特性

form.name

方法

.focus()

.blur()

事件

onsubmit

在最终提交表单之前触发

js大神不愿意告诉你dom的那些事

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务