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
自定义属性
普通自定义属性
只能用核心DOM any.getAttribute("属性名") 和 any.setAttribute("属性名","值")
因为getAttribute和setAttribute()和内存中的元素对象无关,而是每次都临时去页面上的HTML代码中开始标签中查找属性,而不是在对象中直接读取现成的属性
HTML5自定义属性
提示: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学习后,结合之前学的知识,由于掌握不熟练感觉自己对网页的掌控力一下就下降了
近期评论