阅读 68

前端DOM基础

DOM文档对象模型HTML和XML文档的编程接口,表示由多层节点构成的文档,通过他开发者可以添加、删除和修改页面的各大部分。可以理解为抽象层的一种真正跨平台、语言无关的表示和操作网页的方式。

JavaScript是一种脚本语言,DOM是HTML文档的节点属性及其获得和操作的规范。JavaScript通常是通过DOM来获得和操作HTML属性的。

  • DOM0:不是W3C规范。

  • DOM1:开始是W3C规范。专注于HTML文档和XML文档,Node

  • DOM2:增加了style样式表对象模型、扩展了方法(e.g:getElementById)、event

  • DOM3:增加了内容模型 (DTD 、Schemas) 和文档验证Validation、键盘事件

任何HTML或XML文档都可以用DOM表示为一个由节点构成的层级结构

每个文档只能有一个文档元素,在HTML中是< html >元素,在XML中任何元素都可以成为文档元素。 document.firstChild == document.Element ==html

DOM

  • attribute是作为HTML标签的属性

  • property是DOM元素在JavaScript中作为对象的属性

  • 对于HTML的标准属性来说,这两者是同步的,会自动更新。但是对于自定义的属性来说,不同步。

创建元素的三种方法:

  1. document.write("标签的代码及内容");替换当前页面的所有

  2. 对象.innerHTML="标签的代码及内容"; 替换对象的子DOM

  3. document.createElement("标签的代码及内容"); 需要自己手动挂载到DOM树上

Node

所有DOM节点类型都必须实现Node接口,在js中实现Node类型,所有节点类型都继承它

每个节点都有nodeType属性,表示该节点类型,12个数值常量:

  1. ELEMENT_NODE

  2. ATTRIBUTE_NODE

  3. TEXT_NODE

  4. CDATA_SECTION_NODECDATA区块

  5. ENTITY_REFERENCE_NODE

  6. ENTITY_NODE

  7. PROCESSING_INSTRUCTION_NODE

  8. COMMENT_NODE   注释

  9. DOCUMENT_NODE

  10. .DOCUMENT_TYPE_NODE

  11. DOCUMENT_FRAGMENT_NODE

  12. NOTATION_NODE

浏览器并不一定支持所有节点类型

节点关系

ownerDocument指向代表整个文档的文档节点的指针,可以迅速访问文档节点。 childNodes属性指向一个NodeList实例(一个类数组对象,可通过 [下标] 访问) parentNodes属性指向父元素 previousSibling、nextSibling属性运用在同胞节点之间 复制代码

操纵节点关系 每个节点都有一个ownerDocument属性表示所属文档,调用appendChild的时候如果ownerDocument不是指向当前文档就会报错。

importNode()将外部文档的一个节点拷贝一份,再appendChild

fatherN.appendChild(newN);//给父节点添加一个末尾子节点 fatherN.insertBefore(newN,fatherN.firstChild);//插入到指定子节点前面 fatherN.replaceChild(newN,fatherN.firstChild);//替换首个子节点 fatherN.removeChild(fatherN.firstChild);//删除 复制代码

  • 将在文档中的节点传给appendChild,这个节点的会被移动

  • insertBefore的参照节点null时,等同于appendChild

其他

cloneNode(布尔值);  //返回调用他的节点的副本 true 深复制,即复制节点及整个子DOM树 false 返回节点属于文档所有没有指定父节点 normalize();//检查修复节点的所有后代,删除空文本节点,合并一些节点 节点的比较 isSameNode();//相等,比较id外的属性 isEqualNode();//相同 复制代码

Document对象 _9

Document对象的属性

文档信息

document.URL//当前页面的完整URL document.domain//页面的域名,与URL相关 document.referrer//链接到当前页面的前页面的URL document.readyState 复制代码

domain属性是可以设置值的,但是

  1. 不能设置URL中不包含的值。

  2. 域名放松可以,收紧报错。p2p.wor.com=>wor.com可以,反之报错

Document对象的方法

定位元素

document.getElementById(“要求大小写一致”);//查找的第一个元素 document.getElementByTagName("img");//HTML返回了类似NodeList的HTMLCollection对象,该对象除了下标访问,还提供了namedItem("元素name属性值“)。 document.getElementByName("元素name值");//常见于单选按钮 document.querySelector(".myclass"); document.getElementByTagName("*");//返回所有元素 复制代码

document.activeElement文档焦点 文档加载中null 加载完成,默认设置为document.body 复制代码

DOM兼容性检测 document.implementation属性值是一个对象,提供了与浏览器DOM实现相关的信息和能力

DOM有多个level和多个部分,因此确定浏览器实现了哪些部分很重要

文档写入 在页面加载中向页面动态添加内容,常用于动态包含外部资源,如:JavaScript文件。可以创建DOM元素。

document.write("字符串参数”); document.writeLn("字符串参数”); 复制代码

注意在页面渲染期间是追加,但是页面加载完成之后调用就是重写页面。

<html> <head>   <title>Write example</title>   <script>     function newContent() {       document.open();       document.write("<h1>Out with the old, in with the new!</h1>");       document.close();     }   </script> </head> <body onload="newContent();">   <p>Some original document content.</p> </body> </html> 复制代码

Element类型 _1

getAttribute(); setAttribute(); removeAttribute(); document.createElement(“div");//接受tag名参数 复制代码

创建出来之后还需要添加到DOM树中,才会被浏览器渲染

Text类型 _3

包含文本内容的元素会有一个文本子节点

let element =document.createElement("div"); let textN=document.creatTextNode("hello"); element.appendChild(textN); document.body.appendChild(element); 复制代码

拆分文本节点

splitText(i);//i及以后 、i前 复制代码

Comment _8

createComment("sssss");

DocumentFragment类型

唯一在标记中没有对应表示的类型,充当节点暂时的仓库

MutationObserver接口

观察元素、元素属性、文本的变化,在DOM被修改时候异步执行回调函数

// 选择需要观察变动的节点 const targetNode = document.getElementById('some-id'); // 观察器的配置(需要观察什么变动) const config = { attributes: true, childList: true, subtree: true }; // 当观察到变动时执行的回调函数 const callback = function(mutationsList, observer) { // Use traditional 'for loops' for IE 11     for(let mutation of mutationsList) {         if (mutation.type === 'childList') {             console.log('A child node has been added or removed.');         }         else if (mutation.type === 'attributes') {             console.log('The ' + mutation.attributeName + ' attribute was modified.');         }     } }; // 创建一个观察器实例并传入回调函数 const observer = new MutationObserver(callback); // 以上述配置开始观察目标节点 observer.observe(targetNode, config); // 之后,可停止观察 observer.disconnect(); 复制代码

childList子节点、subtree子树、

每次回调都会收到一个MutationRecord实例的数组(可能同时多个满足观察条件的事件、时间顺序),实例包含的信息包括发生了什么变化,以及DOM的哪一部分受到影响。

核心是异步回调记录队列模型,为了在大量变化事件发生时不影响性能,每次变化的信息(由观察者实例决定)会保存在MutationRecord实例中,然后添加到观察者注册的记录队列(所有DOM变化事件的有序列表)。当前面没有已排期的微任务回调时,才会将记录队列上的回调作为微任务调度到任务队列上。

takeRecords()方法可以清空记录队列

MutationEvent定义了一组会在各种DOM变化时触发的事件,由于浏览器事件的实现机制,这个接口出现了严重的性能问题。所以DOM Level3推出了MutationObserver。

  • MutationObserver实例与目标节点之间的引用关系是非对称的。

  • MutationObserver拥有对要观察的目标节点的弱引用,所以不会妨碍垃圾回收程序回收目标节点。

  • 然而,目标节点却拥有对MutationObserver的强引用,如果目标节点从DOM中被移除,随后关联的MutationObserver也被垃圾回收。

DOM元素尺寸:offsetWidth、clientWidth、scrollWidth

后文尺寸除了标记可写的之外 都是只读,每次访问都要重新计算。访问过多会影响性能,多次使用同一值时最好保存在局量中。

浏览器优化: 由于每次回流都会造成额外的计算消耗,因此多数浏览器都会通过队列化修改并批量执行来优化回流过程。直到过了一段时间或者操作达到了一个阈值,才清空队列。但是获取布局信息的操作会强制队列刷新,比如访问以下属性或者使用以下方法:

  • offsetTop、offsetLeft、offsetWidth、offsetHeight

  • scrollTop、scrollLeft、scrollWidth、scrollHeight

  • clientTop、clientLeft、clientWidth、clientHeight

  • width、height

  • getComputedStyle()

  • getBoundingClientRect()

在这里插入图片描述

offsetTop、scrollLeft、clientLeft。clientLeft的值就等于border-left的值

偏移尺寸:所有视觉空间

以边框为界定来算

  • offsetTop 元素上边框外侧距离父元素上边框内侧的像素数

  • offsetLeft

当元素的父辈中没有存在position属性(除了static),含义就是该元素的margin与borde之间分界到网页文档左侧之间的距离;当某个元素的父辈中存在position属性(除了static),含义就是钙元素的的margin与borde之间分界到最近父辈元素border与padding之间分界之间的距离。

可以通过这两属性获取元素在页面中的偏移量

function getLeft(ele){     let left=ele.offsetLeft;     let current=ele.offsetParent;     while(current!=null){//在DOM树中逐级上溯,一直加到根元素         left+=current.offsetLeft;         current=current.offsetParent;     }     return left; } 复制代码

  • offsetHeight元素垂直方向上占用的像素数,包括高度、水平滚动条的高度(注意是水平)、上下边框

  • offsetWidth包括边框的长宽

客户端尺寸:内部视口大小

内容+内边距,不包含滚动条

浏览器视口大小:

  • clientWidth

  • clientHeight

在不需要滚动的元素上,与滚动尺寸无差。

滚动尺寸

元素内容滚动距离的信息。有些元素例如html,无需代码自动滚动,但其他元素则需要使用CSS的overflow属性令其滚动

  • scrollHeight

  • scrollWidth

元素内容的大小

  • scrollLeft

  • scrollTop 元素的内容顶部(卷起来的)到它的视口可见内容(的顶部)的距离的度量。

可写,用于确定当前元素滚动的位置,未滚动的时候都等于0

滚动回顶部

function scrollToTop(ele){     if(ele.scrollTop!=0){         ele.scrollTop=0;     } } 返回顶部:element.scrollTop = 0 到底部:element.scrollTop = element.scrollHeight - element.clientHeight 复制代码

确定大小

浏览器在每个元素上都暴露了getBoundingClientRect()方法,返回一个DOMRect对象, 包括6个属性:left、top、right、bottom相对于视口的位置,作为坐标位置,确定四个角 height、width


作者:贾明恣
链接:https://juejin.cn/post/7028067942281510919

文章分类
前端
文章标签
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐