20200901 王维

学习总结

1.DOM作用

文档对象模型,是HTML和XML文档的编程接口(API),是一套专门操作网页内容的对象和函数的统称,实现增、删、改、查和事件绑定五件事

2.节点对象三大属性

nodeType节点的类型 返回节点类型的常数值 但是无法进一步判断元素的名称

文档节点返回9 元素节点返回1 属性节点返回2 文本节点返回3

nodeName节点名称 文档节点返回#document 元素节点返回全大写标签名 属性节点返回属性名 文本节点返回#text

nodeValue节点值 文档节点和元素节点返回null 属性节点返回属性值 文本节点返回文本内容

3.DOM操作流程

①先在头脑中构建DOM树

②查找触发事件的元素

③绑定事件处理函数 事件处理函数中的this指触发事件的当前元素

④查找要操作的元素

4.查

不需要查找直接获得的节点

document 根节点 document.documentElement HTML节点 document.head 头部head节点 document.body 网页主题body节点

document.form[i] 表单节点i

按节点关系查找 已获得一个树上的节点对象,通过关系,查找想要的另外一个节点对象的过程

节点树

包含所有网页内容(节点)的树结构

父子

elem.parentNode 查找当前节点的父节点

elem.childNodes 查找当前节点的直接直接子节点,返回的是一个类数组对象

elem.firstChild 当前节点的第一个子节点

elem.lastChild 当前节点的最后一个子节点

兄弟

elem.previousSibling 当前节点的哥哥节点

elem.nextSibling 当前节点的弟弟节点

优点:网页结构完整

缺点:代码的格式使得存在很多空白字符,是文本节点对象#text,极大妨碍正常的查找

解决方法:元素树

元素树

仅包含元素节点的树结构,是节点树的子集。内存中只有一颗完整的树,元素树只是在节点树的基础上,新增了仅指向元素的属性。

父子

父子

elem.parentElement 查找当前元素的父元素

elem.children 查找当前元素的直接直接子元素,返回的是一个类数组对象

elem.firstElementChild 当前元素的第一个子元素

elem.lastElementChild 当前元素的最后一个子元素

兄弟

elem.previousElementSibling 当前元素的哥哥元素

elem.nextElementSibling 当前元素的弟弟元素

优点:不包含看不见的文本节点,不干扰查找

缺点:不包含一切文本节点,兼容性存在问题

childNodes和children的区别

同:返回的都是动态集合,不实际存储数据,每次访问集合,都是重新查找DOM树 优点:首次查找返回速度快,缺点:反复访问集合导致反复查找DOM树

异:childNodes是标准属性,但会指定节点的子节点集合,包括HTML节点,属性,文本节点

children是非标准属性,返回指定元素的子元素集合,只返HTML节点,虽然不标准,但是得到几乎所有浏览器支持

递归遍历

深度优先遍历(DFS算法)优先访问子节点,直到最深处的子节点访问到了,再回溯到未被访问的分支,继续执行遍历 DOM遍历

广度优先遍历(BFS算法)优先访问兄弟节点,直到所有兄弟访问到了,再访问子节点,继续执行遍历

document.createNodeIterator(root,whatToShow,filter,false); // 节点原生遍历

①root:遍历起始点处的根节点

②whatToShow:遍历的类型 NodeFilter.SHOW_ALL:搜索所有节点 NodeFilter.SHOW_ELEMENT:搜索元素节点 NodeFilter.SHOW_TEXT:搜索文本节点

③filter:过滤器,需要过滤掉哪些,可以不写

注意:createNodeIterator遍历的时候包含自身元素

按HTML查找

按ID查找 var elem=document.getElementById("id")

标签名查找 var elems=parent.getElementsByTagName("标签名")

按class var elems=parent.getElementsByClassName("class")

按name var elems=document.getElementsByName("name")

问题 一次只能按一个条件查找。如果查找条件复杂,元素藏得很深,还需要筛选时,按HTML特征查找,就会需要很多次查找,才能找到想要的元素,这样代码就过于繁琐

按选择器查找

查找一个元素 var elem=parent.querySelector("selector")

查找多个元素 var elems=parent.querySelectorAll("selector")

HTML查找和选择器查找比较

返回值 按HTML,返回动态集合,不实际存储所有内容,只返回本次所需的内容,如果重复访问集合,就需要重新查找DOM树,优点是首次查找速度快,缺点是反复访问集合,会导致反复查找DOM树(会根据页面元素的变化而变化);按选择器查找,返回非动态集合,可以直接存储所有数据,即使反复访问集合,也不需要反复查找DOM树

首次查询效率 按HTML效率更高,仅返回需要的内容,不需要准备完整数据;按选择器低,第一次要返回完整数据

简易型 按HTML繁琐;selector API简单

使用场景 如果只凭一个条件即可获得想要的元素时,首选按HTML查找;如果需要多级复杂条件查找才能获得想要的元素时,用selector API

5.改

内容

elem.innerHTML

elem.textContent

elem.innerText

elem.value

属性

核心DOM

获取属性 var value=elem.getAttribute("属性名")

修改属性 elem.setAttribute("属性名",属性值)

移除属性 elem.removeAttribute("属性名")

判断是否含有属性 var bool=elem.hasAttribute("属性名")

HTML DOM

获取属性 elem.属性名

修改属性 elem.属性名=值

判断是否包含属性 elem.属性名!==""

移除属性 elem.属性名=""

注意 class属性,不能直接用 “ . ” 访问,因为class属性是ES中的关键词,所以DOM不能再使用class作为属性。如果操作页面上的class属性,只能改名为“ .className”。多个使用 元素.classList

自定义属性

普通自定义属性 不能用HTML DOM打 . 的方式访问自定义扩展属性,因为自定义扩展属性是后天添加的,HTML DOM 无法提前预知自定义属性的名称,自然就不能提前在元素对象中准备好属性,所以不能用 "元素.自定义属性"方式访问。

只能用核心DOM any.getAttribute("属性名") 和 any.setAttribute("属性名","值")

因为getAttribute和setAttribute()和内存中的元素对象无关,而是每次都临时去页面上的HTML代码中开始标签中查找属性,而不是在对象中直接读取现成的属性

HTML5自定义属性 如果添加自定义属性时,添加了data-前缀,则可用dataset自动收集所有data-开头的属性,然后用 . 访问

提示:elem.dataset.属性名

样式

内联样式 elem.style.css属性名=“属性值”

内部/外部样式表

// 获取页面中的所有样式

var sheet=document.styleSheets[i];

// 获取页面中的具体样式表,如果获得的是keyframes,就需要继续找子rule

var rule=sheet.cssRules[i];

// 通过rule下的style属性修改属性值

rule.style.样式属性=值

最好的修改样式的方法 如果批量修改多个css属性时,首选用class,修改class属性,批量应用样式

6.增

创建新元素对象 var elem=document.createElement("标签名")

设置关键属性

将元素添加到DOM树 parent.appendChild(child)父元素末尾追加 parent.insertBefore(child,oldChild)父元素下一个现有旧元素之前 parent.replaceChild(child,oldChild)新元素替换父元素下一个现有旧元素

问题

每操作一次DOM树,都会导致重排重绘。如果数据量大,又频繁操作DOM树,会导致重排重绘不过来

解决方法

尽量少的操作DOM树,如果同时添加父元素和子元素,应该先暂存内存中,将所有子元素添加到父元素,最后将父元素一次性添加到DOM树上,只需要重排重绘一次。如果父元素已经在DOM树上了,而要添加多个平级子元素,需要借助文档片段对象

步骤

①创建文档片段对象 var frag=document.createDocumentFragment();

②将多个平级子元素临时添加到文档片段对象中 frag.appendChild(child)

③将文档片段整体一次性添加到DOM树上指定父元素下 parent.appendChild(frag)

注意:frag不会成为页面元素,添加子元素后,frag自动释放

7.删

parent.removeChild(child)

心得体会

需要记忆的方法太多,需要多加练习,才能熟练掌握,然后还要掌握各个方法之间的异同和优缺点,在使用时方便选择最优的方法,反正就是多练,孰能生巧,DOM学习后,结合之前学的知识,由于掌握不熟练感觉自己对网页的掌控力一下就下降了

评论


© 2021 成都云创动力科技有限公司 蜀ICP备20006351号-1