[前端笔记020]JavaScript之DOM

资源

DOM基础知识

  • DOM是web api的一部分,中文叫文档对象模型。通过web api中定义的对象可以完成对网页的操作。模型指对象之间的关系,父子,兄弟这种,会形成一个关系树。
  • 节点:每一个对象都是一个节点,有不同的类型,文档,元素,文本,属性等。所有节点的共同父类是node类
  • document对象代表整个网页,是浏览器提供的切入口,其父节点是window
  • const btn=document.getElementById(‘btn’);btn.innerText=‘Click ME’;这样就修改了按钮的文字内容。

document

  • 原型链上存在的对象的属性和方法都可以通过document调用,document的原型链为
    HTMLDocument->Document->Node->EventTarget->Object.__proto__->null
  • 部分属性:1.document.documentElement,HTML根元素。2.document.head 3.document.title 4.document.body 5.document.links ,获取所有超链接,6。。。。

元素节点对象

  • 每个标签就是一个元素节点
  • 通过document来获取已有的元素节点:
    1. document.getElementById(),根据id来获取元素节点。
    2. document.getElementsByClassName(),根据class属性值获取一组元素节点,返回的是一个类数组对象,这个一个实时更新的集合,网页中添加了新元素时,集合也会实时刷新。
    3. document.getElementsByTagName(),根据标签名获取一组元素节点,传参为*时获取全部元素节点,其他同2。
    4. document.getElementsByName(),根据name属性值获取一组元素节点,不常用,主要用于表单项,其他同2
    5. document.querySelectorAll(),根据选择器查询元素,返回类数组,实时更新
    6. document.querySelector(),根据选择器查询第一个符合的元素,返回节点对象。减少了使用索引的麻烦。
  • document.createElement(),根据标签名创建元素节点,该标签还未被添加到页面中
  • div元素的原型链,HTMLDivElement->HTMLElement->Element->Node->EventTarget->Object.__proto__->null
  • 通过元素节点获取其他节点的方法,部分方法与document类似,将document替换即可,与document不同是只能获取元素节点的后代节点。
  • 其他方法:
    1. element.childNodes()获取当前元素的子节点(包括文本节点和空白的换行节点),不常用。
    2. element.children(),获取当前元素的子元素
    3. element.firstChild(),第一个子节点,会获取到空白节点,不实用
    4. element.firstElementChild/element.lastElementChild,获取当前元素的第一个/最后一个子元素。
    5. element.nextElementSibling/element.previousElementSibling,获取当前元素的下一个/前一个兄弟元素。
    6. element.parentNode/element.parentElement,获取父节点/父元素,只在获取到根元素html以上的时候有区别,再往上,一个是document,一个是null
    7. element.tagName,获取当前元素的标签名

文本节点

  • 网页中的所有文本内容都是文本节点
  • 可以通过元素来获取文本节点,但不这么做,一般直接通过元素去修改文本节点的值。
  • 修改文本的三个属性,element.textContent/element.innerText,获取或修改元素中的文本内容,内容有标签时会自动转义,content获取标签中的内容,不考虑CSS样式,inner会考虑样式,比如不会获取到display:none的内容,会触发网页重排计算CSS样式,所以性能会稍差一点;element.innerHTML,获取或修改元素中的html代码,有xss注入风险

属性节点

  • 每个属性都是一个属性对象,一个元素节点可能有多个属性节点,一般通过元素完成对属性的修改
  • 方式1:读取,元素.属性名(class属性使用className来读取),读取布尔值如disabled属性时,会返回true或false;修改,元素.属性名=属性值
  • 方式2:读取,元素.getArrtribute(属性名),这里class的读取直接使用class即可;修改,元素.setArrtribute(属性名,属性值),对于布尔值的修改,会一直是true,想要改为false需要使用删除功能;删除,元素.removeArrtribute(属性名);

事件

  • 事件:交互行为,点击按钮,鼠标移动等。通过为事件绑定响应函数来完成和用户之间的交互。
  • 绑定响应函数的方式:
    1. 直接在元素的属性中设置,代码写在属性中:οnclick=‘’
    2. 通过为元素的指定属性设置回调函数,一个事件只能绑定一个响应函数,btn.οnclick=function(){}
    3. 通过元素addEventListener()方法绑定,btn.addEventListener(‘click’,function(){}),可以绑定多个。
  • 响应函数绑定给谁,this就是谁(箭头函数除外)。

文档的加载

  • 网页自上向下加载,JS代码编写在网页上面时,网页还没加载完毕,会出现无法获取到dom对象的的情况。解决方法:
    1. 将script标签编写到body的最后,常用
    2. 非要写在head里,可以编写到window.onload的回调函数中,该函数会在网页加载完毕后触发,所有文档加载完毕后触发
    3. 使用document的DOMContentLoaded,这个只能写在aaddEventListener()方法中,例document.aaddEventListener(‘DOMContentLoaded’,function(){}),当前文档加载完毕后触发。
    4. 将代码编写到外部的js文件中,然后引入标签中加入defer属性,<script defer src=""></script>当前文档加载完毕后执行,但比3执行的更早,常用

实例

  • 在list中添加li,用li替换元素,删除元素
//根据标签名创建节点
const li = document.creatElement("li")
//向li中添加文本与id属性
li.textContent="ts"
li.id="ts"
//放入ul中,appendChild用于给一个节点添加子节点
list.appendChild(li) 用于给一个节点添加子节点
//方法2,insertAdjacentElement,两个参数,第一个为位置信息,有beforeend,afterbegin等,第二个为插入的节点
//将li插到了最后
list.insertAdjacentElement("beforeend",li)
//方法3,insertAdjacentHTML(),两个参数,第一个位置信息,第二个要插入的HTML代码
list.insertAdjacentHTML("beforeend","<li id='ts'>tx</li>")

//li替换swk,replaceWith使用一个元素替换当前元素
const swk=document.getElementById("swk")
swk.replaceWith("li")
//移除swk
swk.remove()
超链接问题
  • 点击超链接默认跳转,在xxx.xxx=function(){}的形式中使用,return false 来阻止跳转,但在xxx.aaddEventListener()中return false 无法取消默认跳转
  • 也可以直接将超链接改为javascript:;来取消跳转
  • confirm()弹出框有取消和确认按钮,alert()只有确认选项,可以根据confirm的返回值进行下一步操作。
复制添加节点
  • insertAdjacentHTML(‘位置’,‘html代码’)+模板字符串的方式,容易被XSS攻击;解决方法是,针对用户输入的内容,通过创建对象的方式添加,创建对象后,使用innerText和textContent来将用户输入的内容转义,防止XSS攻击
  • 节点的复制,可以使用const newXXX=xxx.cloneNode()的方式来对节点进行复制,会复制节点的所有特点包括属性,默认复制当前节点,而不会复制节点的子节点,可以传递true作为参数,这样也会将元素的子节点一起复制。复制后添加前,需要手动改一下id等不能重复的属性。
JS修改/读取CSS样式
  • 修改样式的方法,box1.style.样式名=样式,这样修改的样式为内联样式,如果CSS样式表中的样式加了!important,则JS的修改不会生效,所以慎用!important
  • 如果样式名中含有-,则需要将样式名改为驼峰命名法,如background-color -> backgroundColor
  • box1.style.样式名可以读取到内联样式,但没有内联样式时什么也读不到
  • 读取生效的样式时使用,const Obj=getComputedStyle(节点对象,[伪元素]),返回一个对象,对象包含了当前元素所有生效的样式,之后使用Obj.样式名即可读取,获取的都是带单位的,需要注意转换。获取到的值有可能是auto,需要确认。
  • 以下函数获取的都是数值,可以直接计算
  • 元素.clientHeight/元素.clientWidth,获取元素内部的宽度和高度,包括内容区和内边距
  • 元素.offsetHeight/元素.offsetWidth,获取元素可见框的宽度和高度,包括内容区,内边距和边框
  • 元素.scrollHeight/元素.scrollWidth,获取元素滚动区域的宽度和高度
  • 元素.offsetParent,获取元素的定位父元素,定位父元素指离当前元素最近的开启了定位的祖先元素,如果所有的元素都没开启定位,则返回body
  • 元素.offsetTop/元素.offsetLeft,获取元素相对于其定位父元素的偏移量
  • 元素.scrollTop/元素.scrollLeft,获取元素滚动条的偏移量
操作class
  • 除了直接修改样式,也可以通过修改class属性来间接的修改样式;这样可以一次性修改多个样式,也可以对js和CSS解耦,发生变动时,只修改类即可,例,box1.className+=’ box2’,注意box2前有空格
  • 更常用的是,使用元素.classList,元素.classList是一个对象,提供了对当前元素的类的各种操作方法,
  • 元素.classList.add(“box2”,“box3”,“box4”),添加一个或多个class
  • 元素.classList.remove(),移除元素的一个或多个类
  • 元素.classList.toggle(),切换元素中的类,有就去掉,没有就加上
  • 元素.classList.replace(),替换类
  • 元素.classList.contains(),检查是否有某个class

事件对象

  • 事件对象,浏览器在事件触发时所创建的对象,封装了事件相关的各种信息,如鼠标位置,键盘按键等;浏览器在创建事件对象后,会将事件对象作为响应函数的参数传递,所以可以在事件的回调函数中定义一个形参来接收事件对象,如box.οnmοusemοve=funciton(event){event.clientX;event.clientY;}获取到鼠标的位置,注意无单位
  • 多个事件对象有个共同的祖先,Event,常用的方法如下
  • event.target 触发事件的对象
  • event.currentTarget 绑定事件的对象,同this
  • event.stopPropagation() 停止事件的传导,即事件的冒泡/触发
  • event.preventDefault() 取消默认行为,比如超链接的跳转
  • 事件的冒泡:当元素的某个事件被触发后,其祖先元素上的相同事件也会被触发,与元素的样式无关,只和结构有关。
  • 事件的委派:只绑定一次事件,即可让所有的元素,包括现在的和未来的都具有这个事件,而不需要循环绑定;方法将函数直接绑定给document,然后在绑定函数中判断是否为目标触发元素,来实现事件的委派
  • 事件传播机制,三阶段,1.捕获阶段,从祖先元素向目标元素进行事件的捕获,默认情况下,事件不会在此阶段触发。2.目标阶段,触发事件的对象。3.冒泡阶段,由目标元素向祖先元素进行事件的冒泡
  • 如果希望在捕获阶段触发事件,可以将addEventListener的第三个参数设置为true
  • 可以使用event.eventPhase来查看目标所属的阶段,返回数字,分别代表三个阶段。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值