javascript dom

节点类型

在这里插入图片描述

一共有 12 个节点类型,每个节点都有nodeType属性
下面是节点常量

  • Node.ELEMENT_NODE (1)元素节点 document.createElement("li")
  • Node.ATTRIBUTE_NODE (2) 属性节点 document.createAttribute("align")
  • Node.TEXT_NODE (3) 文本节点 document.createTextNode('text')
  • Node.CDATA_SECTION_NODE (4) CDATA 区块 XML 中才有
  • Node.ENTITY_REFERENCE_NODE (5)
  • Node.ENTITY_NODE (6)
  • Node.PROCESSING_INSTRUCTION_NODE (7)
  • Node.COMMENT_NODE (8) 注释节点 document.createComment('注释')
  • Node.DOCUMENT_NODE (9) document 节点
  • Node.DOCUMENT_TYPE_NODE (10) doctype 节点 不支持动态创建
  • Node.DOCUMENT_FRAGMENT_NODE (11) 文档片段 fragment 节点 document.createDocumentFragment()
  • Node.NOTATION_NODE (12)
<div class="nodeDiv">
			<p>第一元素节点</p>
			<div class="childDiv">第四个子节点</div>
			<!-- 注释节点 -->
		</div>
		<script>
			const nodeDiv = document.querySelector(".nodeDiv")
			const childDiv = document.querySelector(".childDiv")
			console.log(nodeDiv.nodeType) //1
			console.log(nodeDiv.nodeName) //DIV
			console.log(nodeDiv.nodeValue) //null
			console.log(nodeDiv.childNodes) // NodeList(5)[text,p,text,div,text,comment,text]
			console.log(nodeDiv.firstChild) //#text
			console.log(nodeDiv.lastChild) // #text
			console.log(nodeDiv.hasChildNodes()) // true 是否有子节点
			console.log(nodeDiv.ownerDocument) // #document 获取文档节点
			console.log(nodeDiv.parentNode) //body
			console.log(childDiv.previousSibling) // #text
			console.log(childDiv.previousElementSibling) // p
			console.log(childDiv.nextSibling) // #text
			console.log(childDiv.nextElementSibling) // null
			console.log(childDiv.parentNode) //div.nodeDiv

使用文档片段优化代码

<div class="app">
	<ul></ul>
</div>
<script>
	const phones = ["huawei", "xiaomi", "oppo"]
	const ul = document.querySelector(".app ul")
	const fragment = document.createDocumentFragment()
	phones.forEach((item) => {
		let li = document.createElement("li")
		let text = document.createTextNode(`${item}`)
		li.appendChild(text)
		fragment.appendChild(li)
	})
	ul.appendChild(fragment)
</script>

javascript 动态创建样式

let css = `
			body {
				margin:0;
				padding:0;
			}
			.app {
				width: 80%;
				margin: 0 auto;
				color:red;
			}`
function craeteStyles(css) {
	const style = document.createElement("style")
	style.type = "text/css"
	style.appendChild(document.createTextNode(css))
	const head = document.querySelector("head")
	head.appendChild(style)
}
craeteStyles(css)

将字符串解析为dom的方法

  1. 使用innerHTML
    document.body.innerHTML = '<div>使用innerHTML</div>'
  2. 使用 DOMParser
    注意DOMParser将字符串解析为document文档,并不是dom
let domString = `
        <div class='userInfo'>
          <p>username</p>
          <p>password</p>
        </div>
      `
const parser = new DOMParser()
const doc = parser.parseFromString(domString, "text/html")
const div = doc.querySelector(".userInfo")
你不能直接插doc,因为它并不是一个dom,你需要选择这个document中的某个节点
console.log(doc) //#documnet
console.log(div)
document.body.appendChild(div)

MutationObserver 监听 dom 更新

dom 更新时异步执行回调
mutationRecords 记录到底是什么发生了变化

let observer = new MutationObserver((mutationRecords) => {
	console.log("<body> attributes changed")
	console.log(mutationRecords)
})
// 监听body上面的属性,属性更新就触发回调
observer.observe(document.body, { attributes: true })
document.body.className = "foo"
console.log("Changed body class")

获取节点

  1. 获取html节点
    document.documentElement
  2. 获取head节点
    document.head
  3. 获取body节点
    document.body
  4. 获取指定元素节点
  • document.getElementById() 通过id获取指定节点
  • document.getElementsByClassName()通过类名获取节点集合HTMLCollection
    HTMLCollection是一个类数组可以使用Array.from()转真数组
    或者使用call来调用数组上的方法
  • document.getElementsByTagName() 通过标签名获取节点集合
  • document.getElementsByName() 通过name获取元素集合
  • document.querySelector() 通过css选择器来获取标签
  • document.querySelectorAll()

创建节点

  1. document.createElement() 创建标签节点
  2. document.createTextNode('text') 创建文本节点

挂载节点

element.append() 追加一组子节点
element.appendChild(ele)
element.insertBefore(element,target) 在某个节点前面插入节点
element.replaceChild(新的节点,旧的节点) 替换节点

克隆节点

element.cloneNode(true/false) 当为false只克隆目标节点,当为true克隆目标节点及其子孙节点

删除节点

element.removeChild() 删除某个子节点
element.remove() 删除当前节点,以及子孙节点

NodeList 与HTMLCollection

NodeListHTMLCollection
静态集合/实时集合实时集合
Node.childNodes返回动态集合,document.querySelectorAll 返回静态集合Node.children
类数组类数组
有forEach没有forEach

实时集合指,dom更新集合实时更新
对于实时集合最好是使用Array.from()创建副本再进行操作

属性与样式

元素自定义属性

h5规定自定义属性需要以data-开头
获取元素的自定义属性对象dataset
element.dataset

  1. 获取节点状态
    Element.getAttribute(key)
  2. 为节点添加修改状态
    Element.setAttribute(key,value)
  3. 移除状态
    Element.removeAttribute(key)

样式

style对象只能获取行内样式
getComputedStyle(element)获取节点样式
替换类名样式className
classList
element.classList.add() 添加样式
element.classList.remove() 移除样式
element.classList.target() 没有就添加,有就移除
element/classList.contains() 是否有这个样式

焦点管理

document.activeElement ,始终包含当前拥有焦点的DOM元
素。
document.hasFocus() 表示文档是否拥有焦点:

元素尺寸

元素偏移量

  • element.getBoundingClientRect(). 获取元素的大小及相对视口的位置 小数
  • offsetHeight 获取元素的高度height=content+padding+border 这是整数含滚动条
  • offsetLeft 相对于相对定位的父容器的位置
  • offsetTop 相对于相对定位的父容器的位置
  • offsetWidth 获取元素的宽度width=content+padding+border 这是整数含滚动条

客户端尺寸

  • clientHeight不包括border和滚动条
  • clientWidth

滚动尺寸

  • scrollHeight
  • scrollLeft
  • scrollTop
  • scrollWidth
API计算方式
clientWidth/clientHeight元素内容+padding 不含border和滚动条
clientTop/clientLeftborder-top-width/border-left-width
offsetParent返回第一个有定位的父元素
offsetWidth/offsetHeight元素内容+padding+border+滚动条
offsetTop/offsetLeft当前元素到offsetParent边框的距离
scrollWidth/scrollHeight元素内部的高宽(包括溢出部分)
scrollTop/scrollLeft表示滚动条滚动的距离
getBoundingClientRect()返回元素的大小(不含border)以及相对视口的位置

检查滚动条是否滚动到底
scrollTop + clientHeight >= scrollHeight
Math.abs(element.scrollHeight - element.clientHeight - element.scrollTop) < 1

事件

事件捕获,事件冒泡,事件流

  1. 事件捕获windown—>document---->html—>body—>....—>targetDIV
    它是从面到点的传播,这样的目的是方便拦截事件
  2. 事件冒泡windown<—document<----html<—body<—....<—targetDIV
    它是从点到面的传播
  3. 事件流:事件捕获—>目标元素---->事件冒泡(事件流也是事件执行顺序)
    下面案列中,由于按钮本身并没有注册事件处理程序,因此 click 事件冒泡到 document.body ,从而触发了在它上面注册的处理程序。
document.body.onclick = function(event) {
// currentTarget时绑定事件的元素
console.log(event.currentTarget === document.body); // true
console.log(this === document.body); // true
// event.target是点击目标
console.log(event.target === document.getElementById("myBtn")); // true
}

阻止表单默认行为

  1. button,inputtype属性改为button
  2. 在事件监听器中(事件处理函数)中使用event.preventDefault()

阻止事件传播

1.event.stopPropagation() 阻止事件冒泡和捕获传递,当前元素的其它事件可以触发
2. event.stopImmediatePropagation 阻止事件冒泡和捕获传递,当前元素的其它事件不可出触发

添加、移除事件程序

// 添加事件处理程序
btn.onclick=(event)=>{
}
// 移除事件
btn.onclick=null
// 添加事件监听器
btn.addEventListener('click',(event)=>{
})
// 移除事件监听器
inpt.removeEventListener('click',listener)

创建事件

创建自定义事件

  • event = document.createEvent(type);

  • event = new Event(typeArg, eventInit)

  • event = new CustomEvent(typeArg, customEventInit);
    绑定事件
    element.addEventListener(event,hander)
    触发事件
    dispatchEvent(event)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值