Js Dom
DOM
DOM 树
-
doucument object model文档对象模型
-
操作页面元素的属性与方法
-
DOM 的顶级是 document,可能会有更高的节点window,看情况
-
可以操作各种标签,文本,属性, 样式
获取DOM元素
- 非常规标签
- html/head/body
- document.documentElement
- document.head
- document.body
- html/head/body
- 常规标签
- 能用常规标签的方法去获取非常规标签,知识一般不这样用
- getElementById()
- 语法:查找范围.getElementById(‘id名称’)
- 返回值:
- 元素
- 或者null
- getElementsByTagName()
- 语法:查找范围.getElementsByTagName(‘标签名’)
- 返回值
- 所有范围内这个标签名组成的一个伪数组
- 或者空的伪数组
- getElementsByClassName()
- 语法:查找范围.getElementsByClassName(‘类名’)
- 返回值
- 所有范围内这个组成的一个伪数组
- 或者空的伪数组
- getElementsByName()
- 语法:查找范围.getElementsByName(‘元素name属性的值’)
- 返回值
- 所有范围内这个元素name属性的值组成的一个伪数组
- 或者空的伪数组
- querySelector()
- 语法:查找范围.querySelector(‘选择器’)
- 返回值
- 如果找到选择器匹配的内容,则返回第一个
- null
- IE低版本不支持
- querySelectorAll()
- 语法:查找范围.querySelectorAll(‘选择器’)
- 返回值
- 如果找到选择器匹配的元素,则返回全部
- 空的伪数组
- IE低版本不支持
元素的属性
- 什么是元素的属性
- 原生属性
- id/class/style/type/src/…
- 自定义属性
- aaa/abc/hhhh/…
- H5 自定义属性
- data-*
- 操作标签上的三种属性
- 原生属性
- 元素.属性名(class)除外,类名用 元素.className
- 增删查改
- 增/改 元素.属性名 = ‘值’
- 查 元素.属性名
- 自定义属性
- 不能直接点操作
- 增删查改
- 增/改 元素.setAttribute(‘属性名’,‘属性值’)
- 删 removeAttribute(‘属性名’)
- 查 getAttribute(‘属性名’) // 拿到的时候都是字符串
- 可以操作自定义属性,也可以操作原生属性(一般不这么用)
- H5 自定义属性
- 每一个元素身上有一个属性叫做dataset
- 里面包含了所有 H5 自定义属性
- key 是除了 data- 以外的部分
- value 就是这个属性的值
- 增删查改
- 增/改 元素.dataset.key = ‘value’
- 删 delete 元素.dataset.key
- 查 元素.dataset.key
操作元素类名
- 设置类名
- 设置/改 元素.className = ‘className’
- 追加类名 元素.className += ' secondClassName'
- 删除类名(好加不好去)
- 获取类名
- 截取字符串
- 按照空格切开,循环便利,找到想删除的那个
- 再写一遍
- H5 标准提供的API
- classList 元素.classList
-
- add()
- 元素.classList.add(‘你要添加的类名’)
-
- remove()
- 元素.classList.remove(‘你要移除的类名’)
-
- toggle()
- 元素.classList.toggle(‘你要切换的类名’)
- 如果有就删除,如果没有就添加(开关)
操作文本内容
- innerHTML
- 读写的属性
- 操作元素的超文本内容
- 读:获取元素内部所有的内容
- 文本+标签全部内容
- 以字符串的形式范围
- 语法:元素.innerHTML
- 写:设置元素内部所有的内容
- 完全覆盖的书写
- 语法:元素.innerHTML = ‘你要设置的内容’
- 出现 HTML 结构时会自动解析
- 读写的属性
- innerText
- 一个读写的属性
- 操作元素的文本内容
- 读:获取元素内部的所有文本内容
- 包括子元素后代元素里的文本内容
- 标签内容不获取
- 语法:元素.innerText
- 写:设置元素内部的文本内容
- 完全覆盖式的写
- 语法:元素.innerText = ‘你要设置的内容’
- 出现 HTML 结构时不会自动解析
- 读:获取元素内部的所有文本内容
- value
- 一个读写的属性
- 操作表单的元素的 value 值
- 读:获取表单元素的 value 值
- 语法:元素.value
- 写:设置表单元素的 value 值
- 语法:元素.value = ‘你要设置的值’
全选
<style>
*{
margin: 0;
padding: 0;
}
.box {
width:160px;
padding: 5px;
border: 1px solid #333;
margin: 100px auto;
}
.box >div{
padding: 15px;
}
</style>
<body>
<div class="box">
<div class="all">
全选:<input type="checkbox" name="" id="">
</div>
<hr/>
<div class="items">
选项1: <input type="checkbox"> <br/> 选项2:
<input type="checkbox"> <br/> 选项3:
<input type="checkbox"><br/> 选项4:
<input type="checkbox"><br/> 选项5:
<input type="checkbox"><br/>
</div>
</div>
</body>
<script>
let allBtn = document.querySelector('.all > input');
let itemsBtns = document.querySelectorAll('.items > input');
// 给 allTtn 绑定点击事件
allBtn.onclick = function() {
// 获取自己当前的状态
let type = allBtn.checked;
// 遍历循环 itemBtns
// for (let i = 0; i < itemsBtns.length; i++) {
// itemsBtns[i].checked = type;
// }
// 或者
itemsBtns.forEach(function(item) {
item.checked = type;
});
}
// 给每一个选项按钮添加点击事件
itemsBtns.forEach(function(item) {
item.onclick = function() {
// 判断是不是每一个都选中
let flag = true;
itemsBtns.forEach(function(item) {
if (!item.checked) flag = false;
})
console.log(flag);
allBtn.checked = flag;
}
});
</script>
选项卡
<style>
* {
margin: 0;
padding: 0;
}
ul,
ol,
li {
list-style: none;
}
.box {
width: 600px;
height: 400px;
border: 10px solid #3e3e3e;
margin: 50px auto;
/* overflow: hidden; */
}
.box>ul {
height: 50px;
width: 100%;
overflow: hidden;
}
.box>ul>li {
float: left;
width: 200px;
height: 100%;
text-align: center;
line-height: 50px;
font-size: 30px;
background-color: skyblue;
color: #fff;
cursor: pointer;
}
.box>ul>li.active {
background-color: orange;
}
.box>ol {
width: 100%;
height: 350px;
position: relative;
}
.box>ol>li {
width: 100%;
height: 100%;
background-color: purple;
text-align: center;
line-height: 350px;
font-size: 100px;
color: #fff;
position: absolute;
left: 0;
top: 0;
display: none;
}
.box>ol>li.active {
display: block;
}
</style>
<body>
<div class="box">
<ul>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ul>
<ol>
<li class="active">1</li>
<li>2</li>
<li>3</li>
</ol>
</div>
</body>
<script>
let btns = document.querySelectorAll('ul > li');
let tabs = document.querySelectorAll('ol > li');
btns.forEach(function(item, index) {
item.onclick = function() {
btns.forEach(function(b, i) {
b.className = '';
tabs[i].className = '';
})
item.className = 'active';
tabs[index].className = 'active';
}
});
</script>
返回顶部
<style>
* {
margin: 0;
padding: 0;
}
body {
height: 3000px;
}
.topBar {
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
color: #fff;
background-color: skyblue;
position: fixed;
font-size: 30px;
left: 0;
top: 0;
display: none;
}
.topBar.active {
display: block;
transition: 1s ease-in-out;
}
.goTop {
width: 50px;
height: 50px;
line-height: 25px;
font-size: 20px;
color: #fff;
background-color: pink;
position: fixed;
bottom: 50px;
right: 50px;
text-align: center;
display: none;
}
.goTop.active {
display: block;
}
</style>
</head>
<body>
<div class="topBar">顶部</div>
<div class="goTop">回到顶部</div>
<script>
let topBar = document.querySelector('.topBar');
let goTop = document.querySelector('.goTop');
window.onscroll = function() {
let scollTop = document.documentElement.scrollTop || document.body.scrollTop;
if (scollTop >= 300) {
// topBar.className = 'topBar active';
// goTop.className = 'goTop active';
topBar.classList.add('active');
goTop.classList.add('active');
} else {
// topBar.className = 'topBar';
// goTop.className = 'goTop';
topBar.classList.remove('active');
goTop.classList.remove('active');
}
}
goTop.onclick = function() {
window.scrollTo({
top: 0,
behavior: 'smooth'
})
}
</script>
</body>
操作元素样式
- 样式
- 行内样式
- 非行内样式
- 元素.style
- console.log(div.style)
- 只能获取到行内样式
- div.style.width
- 获取非行内样式
- window.getComputedStyle() 方法(标准浏览器)
- window.getComputedStyle(要获取样式的元素)
- 返回一个对象,里面包含所有可以设置的样式,每一个样式都有值,如果没有设置则返回默认值
- currentStyle 属性 (IE低版本)
- 通过点操作符获取样式的时候,如果样式名带有横线,则用驼峰命名法,如 background-color对应backgroundColor
- 如果是数组关联语法,则可以写横线, 如style[‘background-color’]
- window.getComputedStyle() 方法(标准浏览器)
- 短路表达式:方法或属性执行没有问题,只是拿不到值得时候||
function getStyle(ele, style){
if ('getComputedStyle' in window){
return window.getComputedStyle(ele)[style];
}
else{
retuen ele.currentStyle[style];
}
}
- 设置元素样式只能设置元素行内样式
- 元素.style.样式名 = ‘value‘
DOM节点
- DOM节点就是构成我们页面的每一个组成部分
- 元素/注释/文本等内容都是一个个节点
- 常用的四种节点
- 元素节点:页面中的每一个标签
- 文本节点:卸载标签里的文本内容
- 属性节点:写在元素上的每一个属性
- 注释节点:页面中书写的注释内容
- document
- 是一个页面中最大的节点,只能有一个
- 承载所有节点的容器,不属于元素
- 根节点
- html
- 一个页面中最大的元素节点
- 承载所有其他节点
- 根元素节点
- 元素节点
- head/body/div/….
- 只是不同标签在页面中表现形式不一样
- 特点:只是页面的标签
- 文本节点
- 每一段文本内容都是一个文本节点
- 包含换行和空格
- 一般作为元素节点的子节点存在,用来表示该元素节点在页面上显示的内容
- 属性节点
- 属性节点不作为独立节点出现,必须依赖元素节点
- 如果没有元素,属性节点就是文本
- 注释节点
- 作为独立节点出现
- 作为说明文本使用
- 节点操作
- 不光操作元素,还要操作 注释节点 文本节点 属性节点
- 获取节点(包括但不限于元素节点)
- 创建节点(通过JS语法来创造一个标签/文本/注释)
- 把我们创造的节点插入另一个节点中,出现父子结构
- 删除节点(把一个已经存在的节点移除)
- 替换节点(创造一个节点去替换一个已经存在的节点)
- 克隆节点(把一个已经存在的节点复制一份一模一样的)
获取节点
- 获得节点的属性
- childNodes
- 语法:元素.childNodes
- 得到元素所有的子节点
- children
- 语法:元素.children
- 得到子节点的所有元素节点
- firstChild
- 语法:元素.firstChild
- 得到元素的第一个子节点
- firstElementChild
- 语法:元素.firstElementChild
- 得到元素第一个子元素节点
- lastChild
- 语法:元素.lastChild
- 得到元素的最后一个子节点
- lastElementChild
- 语法:元素.lastElementChild
- 得到元素最后一个子元素节点
- perviousSibling
- 语法:元素.perviousSibling
- 得到元素的上一个兄弟节点
- perviousElementSibling
- 语法:元素.perviousElementSibling
- 得到元素的上一个兄弟元素
- nextSibling
- 语法:元素.nextSibling
- 得到元素的下一个兄弟节点
- nextElementSibling
- 语法:元素.nextSibling
- 得到元素的下一个兄弟元素
- parentNode
- 语法:元素.parentNode
- 得到该元素的父节点
- 父节点:大部分时间是元素,有时候是document
- parentElement
- 语法:元素.parentElement
- 得到该元素的父元素节点
- attributes
- 语法:元素.attributes
- 得到元素的所有属性节点
- childNodes
<body>
<p>div上面</p>
<div>
hello
<p>你好</p>
world
<p>世界</p>
<!-- -->
</div>
<p>div下面</p>
<script>
// 获取节点
let div = document.querySelector('div');
// 1. childNodes
// let child = div.childNodes;
// 2. children
// let childEle = div.children;
// console.log(childEle);
// 3. firstChild
// let first = div.firstChild;
// console.log(first);
// 4. firstElementChild
// let first = div.firstElementChild;
// console.log(first);
// 5. lastChild
// let last = div.lastChild;
// console.log(last);
// 6. lastElementChild
// let lastEle = div.lastElementChild;
// console.log(lastEle);
// 7. perviousSibling
// let pers = div.previousSibling
// console.log(pers);
// 8. perviousElementSibling
// let peres = div.previousElementSibling
// console.log(peres);
// 9. nextSibling
// let nextS = div.nextSibling
// console.log(nextS);
// 10. nextElementSibling
// let nextEleS = div.nextElementSibling
// console.log(nextEleS);
// 11. parentNode
// let parent = div.parentNode;
// console.log(parent);
// 12. parentElement
// let parentEle = div.parentElement;
// console.log(parentEle);
</script>
</body>
创建节点
- createElement()
- 语法:document.createElement(‘标签名’)
- 返回值:一个元素节点
- createTextNode()
- 语法:document.createTextNode(‘文本内容’)
- 返回值:一个文本节点,不是字符串
- createComment()
- 语法:document.createComment(‘注释内容’)
- 返回值:一个注释节点
- createAttribute()
- 语法:document.createAttribute(‘属性名’)
- 添加属性值,节点.value = ‘属性值’
- 返回值:一个属性节点
- 语法:document.createAttribute(‘属性名’)
后面三个用的少
插入节点
- appendChild()
- 语法:父节点.appendChild(子节点)
- 作用:把子节点插入到父节点里面,放在最后一个节点的位置
- insertBefore()
- 语法:父节点.insertBefore(要插入的子节点, 哪一个子节点前面)
- 作用:把子节点插入到指定父节点的指定子节点前面
删除节点
- 删除一个已经存在的节点 或者 可以在创建的节点里面删除
- removeChild()
- 语法:父节点.removeChild(子节点)
- 作用:把子节点从父节点里面移出
- remove()
- 语法:节点.remove()
- 作用:把自己移出父节点
替换节点
- 用一个节点替换一个已经存在的节点
- replaceChild()
- 语法:父节点.replaceChild(新节点, 旧节点)
- 作用:在父节点下,用新节点替换旧节点
克隆节点
- 把某一个节点复制一个一模一样的
- cloneNode()
- 语法:节点.cloneNode(参数)
- 参数选填,默认是 false
- 返回值:一个克隆好的节点
- 语法:节点.cloneNode(参数)
带有添加和删除功能的表格
<style>
* {
margin: 0;
padding: 0;
}
form {
width: 300px;
padding: 20px;
margin: 10px;
border: 10px solid skyblue;
}
form>button {
width: 100%;
height: 30px;
margin: 10px 0;
}
table {
width: 300px;
margin: 30px;
border: 2px solid pink;
text-align: center;
}
table>tbody>tr:nth-child(odd) {
background-color: #ccc;
}
table>tbody>tr:nth-child(even) {
background-color: orange;
}
</style>
</head>
<body>
<form action="">
姓名:<input type="text" class="username">
<br> 年龄:
<input type="text" class="age">
<br> 性别:
<input type="text" class="gender">
<br> 操作:
<button type="button" class="add">添加</button>
<br>
</form>
<table cellspacing="0">
<thead>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
<th>操作</th>
</thead>
<tbody>
<tr>
<td>张三</td>
<td>18</td>
<td>男</td>
<td><button class="del">删除</button></td>
</tr>
<tr>
<td>张四</td>
<td>20</td>
<td>女</td>
<td><button class="del">删除</button></td>
</tr>
<tr>
<td>张五</td>
<td>22</td>
<td>男</td>
<td><button class="del">删除</button></td>
</tr>
</tbody>
</table>
<script>
// 分析逻辑
/*
1. 点击添加按钮的时候
=> 拿到文本框的内容
=> 组装一个 tr 标签出来
=> 插入到 tbody 里面
2. 点击每一个删除按钮的时候
=> 找到当前删除按钮所在的 tr 标签,并移除
*/
// 1. 获取元素
let usernameInp = document.querySelector('.username');
let ageInp = document.querySelector('.age');
let genderInp = document.querySelector('.gender');
let addBtn = document.querySelector('.add');
let tbody = document.querySelector('tbody');
let dels = document.querySelectorAll('.del');
// 2. 添加业务逻辑
// 2.1 给 添加按钮 绑定点击事件
addBtn.onclick = function() {
// 2.2 获取内容
let username = usernameInp.value;
let age = ageInp.value;
let gender = genderInp.value;
// 2.3 判断非空
if (username === '' || age === '' || gender === '') {
alert('请完整填写表单');
return;
}
// 2.4 组装一个合法的节点
let tr = document.createElement('tr');
let td1 = document.createElement('td');
let td2 = document.createElement('td');
let td3 = document.createElement('td');
let td4 = document.createElement('td');
let button = document.createElement('button');
td1.innerHTML = username;
td2.innerHTML = age;
td3.innerHTML = gender;
button.innerHTML = '删除';
button.onclick = function() {
let tr = this.parentElement.parentElement;
// 把找到的 tr 删除
tr.remove();
}
tr.appendChild(td1);
tr.appendChild(td2);
tr.appendChild(td3);
td4.appendChild(button);
tr.appendChild(td4);
tbody.appendChild(tr);
// 2.5 表单置空
usernameInp.value = '';
ageInp.value = '';
genderInp.value = '';
}
// 3. 删除的业务逻辑
dels.forEach(function(btn) {
// 3.1 给每个delBtn添加点击事件
btn.onclick = function() {
let tr = this.parentElement.parentElement;
// 把找到的 tr 删除
tr.remove();
}
})
</script>
</body>
动态创建表格
<body>
<table>
<thead>
<tr>
<th>姓名</th>
<th>年龄</th>
<th>性别</th>
</tr>
</thead>
<tbody>
<tr>
<td>张三</td>
<td>18</td>
<td>男</td>
</tr>
<tr>
<td>张三</td>
<td>18</td>
<td>男</td>
</tr>
<tr>
<td>张三</td>
<td>18</td>
<td>男</td>
</tr>
</tbody>
</table>
<script>
// 动态创建表格
let userList = [{
name: '张三',
age: 18,
gender: '男'
}, {
name: '张四',
age: 20,
gender: '女'
}, {
name: '张五',
age: 22,
gender: '男'
}]
// 0. 获取元素
let tbody = document.querySelector('tbody');
let frg = document.createDocumentFragment();
// let div = document.createElement('div');
// 1. 遍历数组
userList.forEach(function(user) {
// 创建 tr
let tr = document.createElement('tr');
// 填充 tr 的内容
tr.innerHTML =
`
<td>${user.name}</td>
<td>${user.age}</td>
<td>${user.gender}</td>
`;
// div.appendChild(tr);
frg.appendChild(tr);
})
tbody.appendChild(frg);
</script>
</body>
- 操作 DOM 越多,性能越差
- 文档碎片(筐)
- 我们可以用JS创建一个文档碎片节点
- 可以承载节点
- 当你把筐向页面添加的时候
- 筐是不会进入页面的,而是把筐里面的内容倒进去
- 语法:document.createDocumentFragment()
- 返回值:一个文档碎片节点
获取元素尺寸
- 元素的占地面积
- 占地面积:内容区域 + padding + border
- 两组方式
- offsetWidth 和 offsetHeight
- 语法
- 元素.offsetWidth
- 元素.offsetHeight
- 得到元素 内容 + padding +border 的尺寸
- 注意:display:none 的时候得到的时候是0
- 因为这个时候不占位
- 语法
- clinetWidth 和 clinetHeight
- 语法
- 元素.clientWidth
- 元素.clientHeight
- 得到元素 内容 + padding 区域的尺寸
- 注意:display:none 以后是 0
- 语法
- offsetWidth 和 offsetHeight
获取元素偏移量
- 获取元素偏移量
- 一个元素相对于参考系的坐标位置
- offsetParent
- 语法:元素.offsetParent
- 拿到该元素获取偏移量的时候的参考父级
- 当你想给这个元素设置一个绝对定位的时候会根据谁定位,他的offsetParent 就是谁
- offsetLeft 和 offsetTop
- 语法:元素.offsetLeft 和 元素.offsetTop
- 得到对于参考父级的左边和上边的偏移量
获取浏览器窗口尺寸
- 获取浏览器窗口尺寸
- BOM 级别的获取
- innerWidth
- innerHeight
- 拿到的是包含滚动条的尺寸
- DOM 级别的的获取
- 其实就是获取页面的那一部分尺寸
- document.documentElement.clientWidth
- document.documentElement.clientHeight
- BOM 级别的获取
// 获取浏览器尺寸
// 包括滚动条
console.log('BOM: ');
console.log('width: ', window.innerWidth);
console.log('height: ', window.innerHeight);
console.log('DOM: ');
console.log('width: ', document.documentElement.clientWidth);
console.log('height: ', document.documentElement.clientHeight);
元素的常用事件
- 事件分类
- 鼠标事件
- 键盘事件
- 浏览器事件
- 表单时间
- 拖拽事件
- 触摸事件(移动端)
- 其他事件
- JS里面的所有原生事件没有大写字母
- 鼠标事件
- click(鼠标左键单击)
- dblclick(鼠标左键双击)
- contextmenu(鼠标右键单击)
- mousewheel(滚轮滚动事件)
- 上面是四个基本事件
- mousedown(鼠标按下)
- 不光是左键,右键也可以,滚轮键也可以,侧键也可以(有时候不可)
- mouseup(鼠标抬起)
- 不光是左键,右键也可以,滚轮键也可以,侧键也可以(有时候不可)
- mousemove(鼠标移动)
- mouseover
- mouseout
- mouseover
- mouseout
- mouseenter
- mouseleave
- …
- 键盘事件
- 不是所有元素都能触发
- 表单元素(有选中效果),document,window
- keydown(键盘按下, 中文输入法下也有效果)
- keyup(键盘抬起)
- keypress(键盘按下, 必须要能够准确嵌入到文本框里的,键入的内容要与你按下的内容一致)
- 浏览器事件
- load(页面加载完毕)
- scroll(滚动)
- resize(窗口尺寸改变)
- offline(网络断开)
- online(网络恢复)
- hashchange(hash值改变的时候)
- …
- 表单事件
- 表单时间绑定给 表单元素 和 form标签 的
- change(表单内容改变,当表单失去焦点的时候和聚焦的时候不一样)
- input(输入内容)
- focus(表单聚焦)
- blur(表单失焦)
- submit(表单提交事件)
- 绑定给 form 标签使用的
- reset(表单重置事件)
- 时间是绑定给 form 标签使用的
- 当你点击 reset 按钮才能触发
- 拖拽事件
- 一般元素想触发拖拽行为,要给元素加一个属性(img自带)
- draggable = “true”
- 需要两个元素才能完成一个完整的拖拽
- 拖拽元素
- 目标元素
- dragstart(拖拽开始)
- 绑定给拖拽元素的
- drag(拖拽移动)
- 绑定给拖拽元素的
- dragend(拖拽结束)
- 绑定给拖拽的元素的
- dragenter(拖拽进入目标元素)(光标)
- 绑定给目标元素
- dragleave(拖拽离开目标元素)
- 绑定给目标元素
- dragover(脱妆元素在目标元素里面移动)
- 绑定给目标元素
- drop(拖拽元素在目标元素内放手)
- 绑定给目标元素
- 必须要在 dragover 里面阻止默认行为
- 触摸事件
- 只能在移动端使用
- touchstart(触摸开始)
- touchmove(触摸结束)
- touchend(触摸开始)
- 其他事件
- transitionend(过度结束)
- 当你有过渡属性的时候
- 过渡结束触发
- 过渡结束触发,你过渡几个属性触发多少次
- selectstart(开始选择)
- 当你想在页面中框选文档的时候触发
- visibilitychange(窗口显示和隐藏)
- 只能绑定给document
- ……
- transitionend(过度结束)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
* {
margin: 0;
padding: 0;
}
.div {
width: 200px;
height: 200px;
background-color: skyblue;
transition: all 3s linear;
}
.dragp {
width: 200px;
height: 200px;
background-color: red;
}
/* .div:hover {
width: 500px;
height: 500px;
} */
</style>
</head>
<body>
<!-- <div class="div"></div>
<form action="">
<input type="text" name="aaa">
<button>提交</button>
<input type="reset">
</form> -->
<div draggable="true" class="dragdiv div">
</div>
qwertyuiop
<p class="dragp"></p>
<script>
// 获取元素
let div = document.querySelector('.div');
// 1. 鼠标事件
// 1.1 click
// div.onclick = function() {
// console.log('左键单击');
// }
// 1.2 dblclick
// div.ondblclick = function() {
// console.log('左键双击');
// }
// 1.3 contextmenu
// div.oncontextmenu = function() {
// console.log('右键单击');
// }
// 1.4 mousewheel(没有鼠标,测试不了)
// div.onmousewheel = function() {
// console.log('滚轮事件');
// }
// 1.5 mousedown
// div.onmousedown = function() {
// console.log('鼠标按下');
// }
// 1.6 mouseup
// div.onmouseup = function() {
// console.log('鼠标抬起');
// }
// 1.7 mousemove
// div.onmousemove = function() {
// console.log('鼠标移动');
// }
// 1.8 mouseover
// div.onmouseover = function() {
// console.log('鼠标移入');
// }
// 1.9 mouseout
// div.onmouseout = function() {
// console.log('鼠标移出');
// }
// 1.10 mouseenter
// div.onmouseenter =function (){
// console.log('鼠标移入');
// }
// 1.11 mouseleave
// div.onmouseleave = function (){
// console.log('鼠标移出');
// }
// 获取元素
let inp = document.querySelector('input');
// 键盘事件
// 2.1 keydown
// inp.onkeydown = function() {
// console.log('键盘按下');
// }
// 2.2 keyup
// inp.onkeyup = function() {
// console.log('键盘抬起');
// }
// 2.3 keypress
// inp.onkeypress = function() {
// console.log('键盘按下');
// }
// 3. 浏览器事件
// 3.4 offline
// window.onoffline = function() {
// console.log('断网了');
// }
// 3.5 online
// window.ononlone = function() {
// console.log('网络恢复了');
// }
// 3.6 hashchange
// window.onhashchange = function() {
// console.log('hash值改变了');
// }
// let inp = document.querySelector('input');
let form = document.querySelector('form');
// 4. 表单时间
// 4.1 change
// inp.onchange = function() {
// console.log('表单发生改变');
// }
// 4.2 input
// inp.oninput = function() {
// console.log('输入事件');
// }
// 4.3 focus
// inp.onfocus = function() {
// console.log('聚焦');
// }
// 4.4 blur
// inp.onblur = function() {
// console.log('失焦');
// }
// 4.5 submit
// form.onsubmit = function() {
// console.log('表单提交');
// // 阻止提交
// return false;
// }
// 4.6 reset
// form.onreset = function() {
// console.log('表单重置');
// }
// 5. 拖拽事件
let dragdiv = document.querySelector('.dragdiv');
let p = document.querySelector('.dragp');
// 5.1 dragstart
// dragdiv.ondragstart = function() {
// console.log('开始拖拽');
// }
// 5.2 drag
// dragdiv.ondrag = function() {
// console.log('正在拖拽');
// }
// 5.3 dragend
// dragdiv.ondragend = function() {
// console.log('拖拽结束');
// }
// 5.4 dragenter(光标)
// p.ondragenter = function() {
// console.log('光标进入');
// }
// 5.5 dragleave
// p.ondragleave = function() {
// console.log('光标离开');
// }
// 5.6 dragover
// p.ondragover = function(e) {
// // 阻止默认行为
// e.preventDefault();
// console.log('在目标元素中移动');
// }
// 5.7 drop
// p.ondrop = function() {
// console.log('在目标元素内放手');
// }
// 6. 触摸事件
// 6.1 touchstart
// div.ontouchstart = function() {
// console.log('触摸开始');
// }
// 6.2 touchmove
// div.ontouchmove = function() {
// console.log('触摸移动');
// }
// 6.3 touchend
// div.ontouchend = function() {
// console.log('触摸结束');
// }
// 7. 其他事件
// 7.1 transitionend
// div.ontransitionend = function() {
// console.log('过渡结束');
// }
// 7.2 selectstart
// document.onselectstart = function(e) {
// // 清除默认事件
// e.preventDefault();
// console.log('请支付后复制');
// }
// 7.3 visibilitychange
// document.onvisibilitychange = function() {
// console.log('显示状态改变了');
// }
</script>
</body>
</html>