文档对象模型(Document Object Model)
// get方式获取一组元素的都是伪数组
// 返回HTMLCollection,它是即时更新的,当其所包含的文档结构发生改变时,它会自动更新。
let lis = document.getElementsByTagName(tag)
// 选择第一个匹配的元素
let div = document.getElementById(id)
// 也是实时更新
let lis = document.getElementsByClassName(class)
// 选择第一个匹配的元素(css怎么获取它就怎么获取)
let div = document.querySelector(css选择器)
// 选择一组元素(类数组)
// 返回NodeList(静态的不会实时更新),它是H5以后新增的可以使用forEach去遍历
// 通过这种方式获取的才是静态的,但是通过实时更新的父元素点出来的孩子们,即使是NodeList也是实时的
let div = document.querySelectorAll(css选择器)
// 获取html 文档对象
document.documentElement
// 获取body标签
document.body
鼠标事件
// 1.鼠标左键按下(点击事件)
btn.onclick = function(){}
// 2.鼠标右键点击(在右键菜单显示前触发)
contextmenu
// 3.鼠标双击事件
dblclick
// 4.鼠标按下事件
mousedown
// 5.鼠标抬起事件
mouseup
// 6.鼠标移入事件
mouseover
// 7.鼠标移入事件(不冒泡,目标元素不冒给自己,其他元素的相同事件不会触发自己)
mouseenter
// 8.鼠标移动触发
mousemove
// 9.鼠标移出事件
mouseout
// 10.鼠标移出事件(不冒泡)
mouseleave
// 11.在鼠标上触发任意按钮触发
mouseup
// 12.鼠标滚轮事件
wheel
// 15.文档视图或者一个元素在滚动时触发,鼠标键盘都可以
scroll
表单事件
// 1.元素获得焦点
focus
// 2.元素失去焦点
blur
// 3.输入事件(每次输入都会触发)
input
// 4.当用户更改表单,并提交时触发
change
// 5.剪切
cut
// 6.拷贝
copy
// 7.粘贴
paste
键盘事件
// 键盘按下,keyCode不区分字母大小写
keydown
// 键盘按下(它不识别功能键 ctrl,shift等)
keypress
// 键盘抬起
keyup
// 三个事件的执行顺序
keydown -- keypress -- keyup
移动端事件
// 手指触摸到一个DOM元素时触发(按下)
touchstart
// 手指在一个DOM元素上滑动时触发
touchmove
// 手指从一个DOM元素上移开时触发(抬起)
touchend
全局事件
// document开头的事件
传统注册方式
监听注册方式
w3c 标准推荐方式
addEventListener() 它是一个方法,不需要加 on
IE9 之前的IE不支持此方法,可以使用attachEvent() 代替,需要加 on
同一个元素可以注册多个监听器,按注册顺序依次执行
element.addEventListener("click",funcion,事件流)
传统方式:element.onclick = null
监听方式:element.removeEventListener(“click”,function)
兼容性的删除方式:detachEvent(“onclick”,function)
这里的function必须和添加事件的function是同一个
注意,事件流是元素父子关系(元素嵌套关系),而不是层叠关系
默认事件为冒泡事件(从内向外)
// addEventListener 一共有三个参数
element.addEventListener("click",funcion,事件流)
// 事件流,默认为false,为事件冒泡(先执行自己的,在执行父元素的)
// 如果为true,那么就为事件捕获(先执行父元素的,在执行自己的)
在使用事件方法时,可以传入一个参数event(事件对象)
- event.type:返回事件类型
- event.target:返回目标对象
- event.currentTarget:返回注册事件的对象,不一定是目标事件,可能是冒泡的,等同于this
- event.preventDefault():阻止默认事件,比如a元素的跳转
- event.stopPropagation():阻止事件冒泡(都是给目标对象添加)
this与event.target的区别:this是函数调用者,event.target是目标对象(比如给ul添加事件使用this改变样式的话,只能改变ul的样式,用target的话点哪个li就只改变哪个li)
鼠标事件属性 | 说明 |
---|---|
event.clientX | 返回鼠标相对于浏览器窗口,可视区域的 X 坐标( 浏览器窗口 ) |
event.clientY | 返回鼠标相对于浏览器窗口,可视区域的 Y 坐标 |
event.pageX | 返回鼠标相对于文档页面 X 坐标,IE9+支持( 文档内容 ) |
event.pageY | 返回鼠标相对于文档页面 Y 坐标,IE9+支持 |
event.screenX | 返回鼠标相对于电脑屏幕的 X 坐标( 电脑屏幕 ) |
event.screenY | 返回鼠标相对于电脑屏幕的 Y 坐标 |
触摸列表 | 说明 |
---|---|
touches | 正在触摸屏幕的所有手指的一个列表 |
targetTouches | 正在触摸当前DOM元素上的手指的一个列表 |
changedTouches | 手指状态发生了改变的列表,从无到有,从有到无变化 |
事件委托是利用了事件冒泡的特征
还拿ul举例子,比如我想给ul下面很多个li标签添加事件,可以只给ul添加事件,就相当于利用冒泡的特性给每一个li都加了事件(这里要注意,目标对象的事件不一定是自己的事件,也可以是父元素给委托的事件)
// 获取标签结构中的自定义属性值,也可以获取标签自身的属性值
element.getAttribute("自定义属性名")
// 为标签添加(修改)自定义的属性名和属性值,有就修改,没有就添加
element.setAttribute("自定义属性名", "自定义属性值")
// 删除标签中的自定义属性
element.removeAttribute("自定义属性名")
// 注意:设置的时候必须以 data-xxx的格式
// 所有以data-开头的属性都可以使用dataset去增删改查
// 获取
element.dataset.xxx
// 修改(添加)
element.dataset.xxx = value
// 删除
delete element.dataset.xxx
创建(三种方式)
// 创建节点对象(这个时候还没上树)
document.createELement("标签名")
// 创建文档片段,会创建一个空白的文档,可以用来装载元素
document.createDocumentFragment()
// 会覆盖node中原有的内容
// innerText和innerHTML差不多,只是innerText不能识别标签
// textContent和outerHTML和上面两个都是差不多的,textContent兼容性好一些
node.innerHTML = 标签内容
// 对整个页面进行重绘
document.write(标签内容)
追加
// 追加节点对象(上树)
parentNode.append("元素对象或字符串") // 如果是字符串就是添加文本节点
parentNode.appendChild("元素对象") // 只能是元素对象
parentNode.prepend() // 和 append 一样不过是添加到最前面
插入
// 第一种
// 插入指定元素之前(上树)
parentNode.insertBefore(ele,指定元素)
// 第二种
// 这个方法不会覆盖之前的html内容
// position,有四个参数
// 'beforebegin':元素自身的前面。
// 'afterbegin':插入元素内部的第一个子节点之前。
// 'beforeend':插入元素内部的最后一个子节点之后。
// 'afterend':元素自身的后面。
// text:要插入的HTML元素
// 这三个的插入方法都是差不多的
// 使用 insertAdjacentHTML 插入用户输入的HTML内容的时候,需要转义之后才能使用
element.insertAdjacentHTML(position, text);
// 插入的元素
element.insertAdjacentElement(position, element);
// 插入的文本
element.insertAdjacentText(position, text);
<p>
foo
p>
// 第三种(还在实验中)
// 插入当前目标元素之前或之后
element.before("元素对象或字符串")
element.after("元素对象或字符串")
// 当为true时为深层克隆,克隆当前节点和子节点,并返回克隆的节点
node.cloneNode(true)
// 当为false时为浅层克隆,只克隆当前节点(标签、属性和类名)
node.cloneNode(false)
Node.replaceChild(newChild, oldChild)
// externalNode:需要提取的节点
// 然后把 node 插入到新的位置
node = document.adoptNode(externalNode);
offset 翻译过来就是偏移量, 我们使用 offset系列相关属性可以动态的得到该元素的位置( 偏移 )、大小等。
offset系列属性 | 作用 |
---|---|
ele.offsetParent | 返回具有定位元素的父级元素,如果上层一直没有则返回body |
ele.offsetTop | 返回元素相对带有定位父元素上方的偏移,子border到父border |
ele.offsetLeft | 返回元素相对带有定位父元素左方的偏移,如果没有就是body |
ele.offsetWidth | 返回自身content+padding+border的宽度,返回值不带单位 |
ele.offsetHeight | 返回自身content+padding+border的高度,返回值不带单位 |
client 翻译过来就是客户端,我们使用 client 系列的相关属性来获取元素可视区的相关信息。通过 client 系列的相关属性可以动态的得到该元素的边框大小、元素大小等。
client系列属性 | 作用 |
---|---|
ele.clientTop | 返回该元素上边框的大小 |
ele.clientLeft | 返回该元素左边框的大小 |
ele.clientWidth | 返回自身content+padding的宽度,返回值不带单位 |
ele.clientHeight | 返回自身content+padding的宽度,返回值不带单位 |
scroll 翻译过来就是滚动的,我们使用 scroll 系列的相关属性可以动态的得到该元素的大小、滚动距离等。
scroll系列属性 | 作用 |
---|---|
ele.scrollTop | 返回自身被卷去上侧的距离 |
ele.scrollLeft | 返回自身被卷去左侧的距离 |
ele.scrollWidth | 返回自身content的宽度 |
ele.scrollHeight | 返回自身content的高度 |
ele.scrollTo(x,y),手动滚动dom元素
// 像类名与ID直接元素点就可以使用,一般其他的样式要style点才可以
// 类名
className // 返回类名,可读可写
classList // 将属性作为列表来返回
/*
classList 可以使用
add(class):添加类名
remove(class):删除类名
toggle(class):切换类名,如果有类名删除没有就添加
contains(class):判断是否存在类名,返回布尔值
*/
// ID
id // 返回id,可读可写
// 1. 通过属性修改
// 上面说到 DOM 提供的有很多获取元素宽高等一些属性
// 但是 style 可以获取行内样式,也可以添加行内样式
// background-color:像这种样式需要转为大驼峰
element.style.backgroundColor = "red" // 可读可写
// 2. 通过 API 修改
/*
propertyName:需要添加或修改的属性,有则修改无则添加,和 css 一样写法
value(可选):需要修改或填的属性值,如果不填为空
priority(可选):设置 css 优先级 "important"
css 变量通过 js 去设置,需要使用这种方式,直接 style 点不行
*/
element.style.setProperty(propertyName, [value], [priority]);
<div class="box">div>
<script>
// 获取box元素
let box = document.querySelector(".box")
// 获取box的全部样式(计算后的样式)
let boxStyle = window.getComputedStyle(box)
// 获取box伪元素的全部样式
let afterStyle = window.getComputedStyle(box, "::after")
// 这种方式是只读的
script>