JavaScript (三) DOM

275 阅读3分钟

三、DOM

  • 文档对象模型
  • 操作html标签的能力
  • 操作
    • 获取一个元素
    • 移除一个元素
    • 创建一个元素
    • 向页面添加一个元素
    • 给元素绑定一些元素
    • 获取元素的属性
    • 给元素添加一些css样式
  • 核心是document对象
  • document对象是浏览器内置的一个对象,里面存储专门用来操作元素的各种方法

1.获取一个元素

1.1 html元素

  • document.documentElement

1.2 head

  • document.head

1.3 body

  • document.body

1.4 获取id元素

  • document.getElementsById(id名称)
  • 无兼容性问题
  • 只能是一个对象,就算有两个或

1.5 获取class元素

  • document.getElementsByClassName(class名字)
  • 伪数组:长的像一个数组,实际上不是真正的数组,没有.map属性
  • 真正的数组有.map等属性
<body>
	<ul>
		<li class="li_name">111</li>
		<li class="li_name">111</li>
		<li class="li_name">111</li>
		<li class="li_name">111</li>
		<li class="li_name">111</li>
	</ul>

	<script>
		var class_name = document.getElementsByClassName("li_name")
		console.log(class_name[0].map) //undefined
                class_name[0].innerHTML = "hello" 
		var newitems = Array.from(class_name) //转换为字符串
		console.log(newitems.map) //ƒ map() { [native code] }
	</script>
</body>

1.6 获取标签名

  • document.getElementsByTagName(标签名称li)
  • 和获取class用法类似

1.7 获取name元素

  • document.getElementsByName(name名称)
  • 只适用于input标签
  • document.getElementsByName(name名称).value = 'HELLO'

1.8 querySelector

  • 对低版本浏览器不友好
  • 与css一样的操作
  • 多个同名则返回第一个遇到的对象
<body>
	<ul>
		<li class="li_name">1</li>
		<li class="li_name">2</li>
		<li class="li_name">3</li>
		<li class="li_name">4</li>
		<li class="li_name">5</li>
	</ul>

	<script>
		var item = document.querySelector("li")
		console.log(item) //<li class='li_name'>1</li>
	</script>
</body>

1.9 querySelectorAll

  • 相比上面的区别
    • 遇到多个同名的,返回所有
<body>
	<ul>
		<li class="li_name">1</li>
		<li class="li_name">2</li>
		<li class="li_name">3</li>
		<li class="li_name">4</li>
		<li class="li_name">5</li>
	</ul>

	<script>
		var item = document.querySelectorAll("ul li.li_name")
		console.log(item) // NodeList(5) [li.li_name, li.li_name, li.li_name, li.li_name, li.li_name]
	</script>
</body>

2.操作元素

2.1属性

  1. 元素自带(原生)属性
  2. 自定义属性
<div class="box" dkwwwwww="danorz">hello</div>
//class 元素属性 dkwwwwww 自定义属性
  1. 操作原生属性
<body>
	<div id="box" dkwwwwww="danorz">hello</div>
	<input type="text" value="hello" id="username" >


	<script>
		box.innerHTML = "222"
		username.value = "3333"
		username.type = "password"

	</script>
</body>
  1. 操作自定义属性
    • 设置属性setAttribute("key","value")
    • 获取属性getAttribute("key")
    • 移走属性removeAttribute("key")
    • 命名规则:data-XXX
    • 设置属性.dataset.新属性名 = 属性值
    • 删除属性delete .dataset.属性名
    • 获取属性.dataset
<body>
	<div id="box">hello</div>
	<div id="box2" data-aaa="a">yes</div>
	
	<script>
		box.setAttribute("dan","me")
		console.log(box.getAttribute("dan"))
		box.removeAttribute("dan")
		box2.dataset.bbb="b"
		delete box2.dataset.aaa
		console.log(box2.dataset)
	</script>
</body>
1.2.1 显示密码
<body>
	<input type="password" id="password">
	<button id="change">显示</button>
	
	<script>
		var password = document.getElementById('password')
		var change = document.querySelector('#change')
		console.log(password)
		change.onclick = function(){
			if (password.type === 'password'){
				password.type = 'text'
			} else {
				password.type = 'password'
			} 
		}
		
	</script>
</body>
1.2.2 购物车全选功能
<body>
	<input type="checkbox" id="all">全选
	<hr>
	<ul class="shop">
		<li>
			<input type="checkbox">goods1
		</li>
		<li>
			<input type="checkbox">goods2
		</li>
		<li>
			<input type="checkbox">goods3
		</li>
		<li>
			<input type="checkbox">goods4
		</li>
		<li>
			<input type="checkbox">goods5
		</li>
	</ul>
	
	<script>
		var all = document.getElementById('all')
		var items = document.querySelectorAll(".shop input")
		all.onclick = function(){
			console.log(items.length)
			if( all.checked == true ){
				for(var i = 0; i < items.length; i++){
					items[i].checked = true
				}
			} else {
				for(var i = 0; i < items.length; i++){
					items[i].checked = false
				}
			}
		}

		for (var i = 0; i<items.length ; i++){
			items[i].onclick = handler
		}

		function handler(){
			var count = 0
			for(var i =0; i<items.length; i++){
				if(items[i].checked) count++
			}

			if(count === items.length){
				all.checked = true
			} else {
				all.checked = false
			}
		}
		
	</script>
</body>

2.2 操作元素文本内容

  1. innerHTML
    • 拿到文本和标签
    • 设置:能设置标签和文本
  2. innerText
    • 只拿文本信息
    • 不解析HTML
    • 设置:文本
  3. value
    • 表单input、下拉选项select
2.2.1 渲染页面
<body>
	<ul></ul>
	
	<script>
		var filmList = [			{				url:'https://static.maizuo.com/pc/v5/usr/movie/149ddb9a7f64e06ed474d963cfc6c405.jpg?x-oss-process=image/quality,Q_70',				title:'消失的她',				grade:7.1			},			{				url:'https://static.maizuo.com/pc/v5/usr/movie/19dbbdc52057e722a4c6d76a788fc417.jpg?x-oss-process=image/quality,Q_70',				title:'我爱你!',				grade:7.4			},			{				url:'https://static.maizuo.com/pc/v5/usr/movie/b6be063ea8bb7d4ecd09299b800fe510.jpg?x-oss-process=image/quality,Q_70',				title:'八角笼中',				grade:7.3			}		]

		var filmItems = filmList.map(function(item){
			return `<li>
				<img src='${item.url}'>
				<h3>${item.title}</h3>
				<p>观众评分 ${item.grade}</p>
				</li>`
		})
		

		console.log(filmItems.join(""))

		var ul = document.querySelector('ul')
		ul.innerHTML = filmItems.join('')
	</script>
</body>

2.3 操作元素样式

  1. 行内样式
    • 获取 .style.样式
      • background-color两种写法backgroundColor style['background-color']
    • 设置样式 .style.样式 = "XX"
<body>
	<div id="box" style="width: 100px;color: blueviolet;background-color: blue;">111</div>
	
	<script>
		console.log(box.style.width)
		console.log(box.style.backgroundColor)
		console.log(box.style['background-color'])
		box.style.height = '1000px'
		console.log(box.style.height)

	</script>
</body>
  1. 内部样式、外部样式、行内样式
    • 只能读取,不能写
    • getComputedStyle(节点名称).css样式
      • background-color两种写法.backgroundColor getComputedStyle(节点名称)['background-color']
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>01.html</title>
	<style>
		#box {
			height: 100px;
			background-color: blue;
		}
	</style>
</head>
<body>
	<div id="box">111</div>
	
	<script>
		var a = getComputedStyle(box).height
		var b = getComputedStyle(box)['background-color']
		var c = getComputedStyle(box).backgroundColor
		console.log(a,b,c)//100px rgb(0, 0, 255) rgb(0, 0, 255)
	</script>
</body>
  1. ie浏览器 低版本
    • .currentStyle.css样式

2.4 操作元素类名

  1. className
    • 查看class类名.className
    • 修改类名 .className = " 新类名 " / .className += ' 新类名'
    • 有重复的不会去重
<body>
	<div id="box" class="item item1 item2 ">111</div>
	
	<script>
		console.log(box.className)// item item1 item2
		box.className = 'item item2'
		console.log(box.className)//item item2
		box.className += " item3"
		console.log(box.className)// item item2 item3
		box.className = "item item2 item3 item4"
		console.log(box.className) // item item2 item3 item4

	</script>
</body>
  1. classList
    • 有重复的能去重
    • 添加 .classList.add('item2')
    • 删除 .classList.remove('item2')
    • 切换 .classList.toggle("item2")
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>01.html</title>
	<style>
		.it2 {
			background-color: blue;
		}
	</style>
</head>
<body>
	<div id="box" class="item">111</div>
	<button id="btn" class="it">222</button>
	
	<script>
		console.log(box.classList)
		var a = box.classList.add('item2')
		console.log(box.classList)
		var b = box.classList.remove('item')
		console.log(box.classList)

		btn.onclick = function(){
			box.classList.toggle("it2")
		}


	</script>
</body>
2.4.1 简易选项卡
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>01.html</title>
	<style>
		* {
			margin: 0;
			padding: 0;
		}
		ul {
			display: flex;
			list-style: none;
		}
		li {
			height: 50px;
			line-height: 50px;
			text-align: center;
			flex: 1;
		}
		.active {
			color: red;
			border-bottom: 1px solid red;
		}
	</style>
</head>
<body>
	<ul>
		<li id="item" class="active">正在热映</li>
		<li id="item2" >即将上映</li>
	</ul>
	
	<script>
		var li1 = document.querySelector("#item")
		var li2 = document.querySelector("#item2")
		li1.onclick = function(){
			li2.classList.remove('active')
			li1.classList.add("active")
		}
		li2.onclick = function(){
			li1.classList.remove('active')
			li2.classList.add("active")
		}


	</script>
</body>
2.4.2 选项卡
<!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;
		}

		ul {
			list-style: none;
		}
		.header {
			display: flex;
			width: 500px;
		}

		.header li {
			flex: 1;
			height: 50px;
			line-height: 50px;
			text-align: center;
			border: 1px solid black;
		}

		.box {
			position: relative;
		}
		.box li {
			position: absolute;
			left: 0;
			top: 0;
			width: 500px;
			height: 200px;
			background-color: yellow;
			display: none;
		}

		.header .active {
			background-color: red;
		}
		.box .active {
			display: block;
		}
	</style>
</head>
<body>
	<ul class="header">
		<li class="active">1</li>
		<li>2</li>
		<li>3</li>
		<li>4</li>
	</ul>
	<ul class="box">
		<li class="active">111</li>
		<li>222</li>
		<li>333</li>
		<li>444</li>
	</ul>

	<script>
		var oHeaderItems = document.querySelectorAll('.header li')
		var oBoxItems = document.querySelectorAll('.box li')

		for (var i=0 ; i<oHeaderItems.length; i++) {
			oHeaderItems[i].dataset.index = i
			oBoxItems[i].dataset.index = i
			oHeaderItems[i].onclick = function(){
				var index = this.dataset.index
				for(var m=0; m<oHeaderItems.length; m++) {
					oHeaderItems[m].classList.remove('active')
					oBoxItems[m].classList.remove('active')
				}
				oHeaderItems[index].classList.add('active')
				oBoxItems[index].classList.add('active')
			}
		}
		console.log(i)
	</script>
</body>
</html>

3.DOM节点

  1. 分类:元素节点/文本节点/属性节点

3.1 元素节点

  • div p li ....
  • document 是根节点
    • 元素最大的节点
    • 所有节点都不是,是承载使用的节点
  • html 根元素节点
    • 一个页面最大的元素节点

3.2 文本节点

  • <div>XXXX</div>中的XXX就是文本节点
  • 换行符也算一个节点\n

3.3 属性节点

  • id class style...
    • <div class='job'>XXX</div>
  • 获取属性节点getAttribute('index')
  • 所有属性节点attributes
<body>
	<div id="box" index="1">
		rose
		<p id="box_next">i am a p tag</p>
		<!-- woshiyigezhushi -->
	</div>
	<script>
		console.log(box.getAttribute('index')) //1
		console.log(box.attributes)//NamedNodeMap {0: id, 1: index, id: id, index: index, length: 2}
		console.log(box.attributes[1]) //index='1'
	</script>
</body>

3.4 注释节点

  • <!- 我是一段注释-->

4.获取节点

  • 所有节点 childNodes
  • 所有元素 children
  • 第一个孩子节点 firstChild
  • 第一个元素节点 firstElementChild
  • 最后一个孩子节点lastChild
  • 最后有一个元素节点lastElementChild
  • 上一个兄弟节点previousSibling
  • 上一个元素节点previousElementSibling
  • 下一个兄弟节点 nextSibling
  • 下一个兄弟元素节点nextElementSibling
  • 父节点parentNode
  • 父元素节点parentElement
    • 拿不到就是null
<body>
	<div id="box">
		rose
		<p>i am a p tag</p>
		<!-- woshiyigezhushi -->
	</div>
	<div id="box1">rose<p>i am a p tag</p><!-- woshiyigezhushi --></div>
	<script>
		console.log(box.childNodes)//5个节点 查看data
		console.log(box1.childNodes)//3个节点
		console.log(box.children)
		console.log(box.firstChild)
		console.log(box.firstElementChild)
		console.log(box1.previousSibling) //#text
		console.log(box1.previousElementSibling) //<div id='box'>
		console.log(box.nextSibling)
		console.log(box.nextElementSibling)
		console.log(box.parentNode) //body
		console.log(box.parentElement)//body
	</script>
</body>

5. 操作DOM节点

5.1 创建节点

  • 创建孩子节点最后一个 apprendChild()
<body>
	<div id="box">
		<div id="child">i am first querncard !</div>
	</div>

	<script>
		var odiv = document.createElement('div')
		odiv.className = 'aaa'
		odiv.id = 'a'
		odiv.style.background = 'yellow'
		odiv.innerHTML = 'is you ?'
		console.log(odiv)
		box.appendChild(odiv)
	</script>
</body>
  • 插入当前节点之前 .insertBefore('要插入的节点', '谁的前面插入')
box.insertBefore(odiv,child)

5.2 删除节点

  • 删除节点 removeChild(节点对象)
box.removeChild(child)
  • 删除当前节点 remove()
box.remove()

5.3 替换节点

  • 替换节点 replaceChild(替换节点, 被替换节点)
<body>
	<div id="box">
		<div id="child">i am first querncard !</div>
	</div>

	<script>
		var odiv2 = document.createElement('div')
		odiv2.innerHTML = '222'
		box.replaceChild(odiv2,child)

	</script>
</body>

5.4 克隆节点

  • clonNode()
  • 默认: 克隆节点(false) 不克隆后代
  • true 克隆后代
<body>
	<div id="box">
		<div id="child">i am first querncard !</div>
	</div>

	<script>
		var oCloneBox = box.cloneNode(true)
		console.log(oCloneBox)
		document.body.appendChild(oCloneBox)
		oCloneBox.id = 'box2'
	</script>
</body>

5.5 案例: 动态删除

  • 每个li配一个button
  • 点击删除,删除当前li
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
	<style>
		ul {
			list-style: none;
		}
	</style>
</head>
<body>
	<ul id="box">

	</ul>

	<script>
		var arr = ['111','222','333']
		for(var i = 0; i < arr.length; i++) {
			var oli = document.createElement('li')
			var obutton = document.createElement('button')
			// 添加内容
			oli.innerHTML = arr[i]
			obutton.innerHTML = 'detele'
			oli.id = 'li' + i
			obutton.onclick = deloli
			box.appendChild(oli)
			oli.appendChild(obutton)

		}
		function deloli() {
			this.parentNode.remove()
		}
	</script>
</body>

6. 节点属性

nodeTypenodeNamenodeValue
元素节点1大写标签名 null
属性节点2属性名属性值
文本节点3#text文本内容
<body>
	<div class="box">hello world<!--chenruoshuang --></div>

	<script>
		var odiv = document.querySelector('.box')
		console.log(odiv.childNodes)
		for (var i = 0; i < odiv.childNodes.length; i++) {
			var a = odiv.childNodes[i].nodeType
			console.log(a)
		}
		
	</script>
</body>

7. 获取元素尺寸

  • offsetWidth : 内容+padding+border

  • offsetHeight : 内容+padding+border

    • 类型: 数字
    • border-sizing: width的长度
    • display:none 拿不到
  • clientWidth : 内容+padding

  • clientHeight : 内容+padding

    • 类型: 数字
    • border-sizing: width-border的长度
    • display:none 拿不到
<style>
	.box {
		width: 100px;
		height: 100px;
		padding: 10px;
		border: 5px solid red;
		background-color: yellow;	
	}
</style>

<body>
	<div class="box"></div>

	<script>
		var odiv = document.querySelector('.box')
		console.log(odiv.offsetWidth,odiv.offsetHeight)//130 130

	</script>
</body>
	<style>
		.box {
			width: 100px;
			height: 100px;
			padding: 10px;
			border: 5px solid red;
			background-color: yellow;
			box-sizing: border-box;
		}
		
	</style>

<body>
	<div class="box"></div>

	<script>
		var odiv = document.querySelector('.box')
		console.log(odiv.clientHeight,odiv.clientWidth)

	</script>
</body>

8. 定位距离

  • offsetLeft offsetTop offsetRight offsetBottom
  • 参考点: 定位父级
    • 若父级元素都没有定位position:relative,偏移量想到对于body节点
<style>
	* {
		margin: 0;
		padding: 0;
	}
	#box {
		width: 500px;
		height: 500px;			
		background-color: yellow;
		overflow: hidden;
	}
	#myparent {
		width: 300px;
		height: 300px;
		background-color: blue;
		overflow: hidden;
	}
	#child {
		width: 100px;
		height: 100px;
		background-color: red;
	}
	div {
		margin: 50px;
	}
	
</style>

<body>
	<div id="box">
		<div id="myparent">
			<div id="child">
			</div>
		</div>
	</div>

	<script>
		console.log(box.offsetTop,box.offsetLeft) // 50 50
		console.log(myparent.offsetTop,myparent.offsetLeft) // 100 100
		console.log(child.offsetTop,child.offsetLeft) // 150 150

	</script>
</body>

9. 边框的宽度

  • clientLeft clientRight clientTop clientBottom
<style>
	* {
		margin: 0;
		padding: 0;
	}
	ul {
		width: 200px;
		height: 200px;
		padding: 20px;
		border: 10px solid black;
		background-color: red;
		margin: 50px;
	}

</style>

<body>

	<ul id="list"></ul>
	<script>
		console.log(list.clientLeft,list.clientTop) // 10 10
	</script>
</body>
<style>
	* {
		margin: 0;
		padding: 0;
	}
	ul {
		width: 200px;
		height: 200px;
		padding: 20px;
		border: 10px solid black;
		background-color: red;
		margin: 50px;
		border-left-width: 50px;
		border-top-width: 50px;
	}
	
</style>

<body>

	<ul id="list"></ul>
	<script>
		console.log(list.clientLeft,list.clientTop) // 50 50
	</script>
</body>

10 案例 滚动加载数据

<style>
	* {
		margin: 0;
		padding: 0;
	}
	html,body {
		height: 100%;
	}
	ul li {
		overflow: left;
		height: 150px;
	}
	ul li img {
		float: left;
		width: 80px;
	}
</style>

<body>
	<h1>标题</h1>
	<ul id="list">	
	</ul>
	<script>
		var arr1 = [
			{
				name:'11',
				url: './img001.JPG'
			},
			{
				name:'22',
				url: './img001.JPG'
			},
			{
				name:'33',
				url: './img001.JPG'
			},
			{
				name:'44',
				url: './img001.JPG'
			},
			{
				name:'55',
				url: './img001.JPG'
			}
		]

		var arr2 = [
			{
				name:'66',
				url: './img001.JPG'
			},
			{
				name:'77',
				url: './img001.JPG'
			},
			{
				name:'88',
				url: './img001.JPG'
			},
			{
				name:'99',
				url: './img001.JPG'
			},
			{
				name:'00',
				url: './img001.JPG'
			}
		]
		renderHTML(arr1)
		function renderHTML(arr) {
			// list.innerHTML += arr.map((item) => {
			// 	return `<li>
			// 				<img src="${item.url}" alt="">
			// 				<h3>${item.name}</h3>
			// 			</li>`
			// }).join('')
			// += 会再次加载 界面会闪一下
			//用append则不会是在原有的基础上加上节点
			arr.forEach((item) => {
				var oli = document.createElement('li')
				oli.innerHTML = `<img src="${item.url}" alt="">
				<h3>${item.name}</h3>`
				list.appendChild(oli)
			})
			
		}
		var isLoading = false
		window.onscroll = () => {
			
			var listHeight = list.offsetHeight //整个list的高度 750 = 5 * 150
			var listTop = list.offsetTop // list距离body的top值,偏移量
			var scrollTop = document.documentElement.scrollTop || document.body.scrollTop// 屏幕滚动的距离
			var windowHeight = document.documentElement.clientHeight // 屏幕可以展示的宽度
			if (isLoading) return 
			// if (Math.round(windowHeight + scrollTop) >= (listHeight+listTop - 100)) {
			// 	console.log('到底了')
			// 	isLoading = true
			// }
			if ( (listHeight+listTop -Math.round(windowHeight + scrollTop) )<50) {
				console.log('到底了')
				isLoading = true

				setTimeout(() =>  {
					renderHTML(arr2)
					isLoading = false //下一次到底数据继续触发
				},1000) //在真实案例中会向后端请求
				
			}

			

		}
	</script>
</body>

11. 事件

11.1 绑定事件

  1. .事件
    • 缺点: 多个时,以最后一个为主
  2. .addEventListener('事件',function)
<body>
	<div id="box">点击我</div>
	<script>
		box.onclick = () => {
			console.log('11111')
		}
		box.onclick = () => {
			console.log('2222')
		}//下面的click事件会覆盖掉上面的点击事件
		box.addEventListener('click',()=>{
			console.log('3333')
		})// 可以绑定多个点击事件
		box.addEventListener('click',()=>{
			console.log('444')
		})//显示3个点击事件 2222 3333 444
	
	</script>
</body>

11.2 解绑事件

  1. this.onclick = null
<body>
	<button id="btn">点击我</button>
	<script>
		// btn.onclick = function() {
		// 	console.log('11111')
		// 	this.onclick = null
		// }
		
		btn.onclick = (e) => {
			console.log('11111')
			// console.log(e.target)
			e.target.onclick = null
			
		}
	
	</script>
</body>
  1. removeEventListener('事件',函数)
  • 有兼容性问题IE浏览器
<body>
	<button id="btn">点击我</button>
	<script>
		function handle (){
			console.log('111')
			this.removeEventListener('click',handle)
		}
		btn.addEventListener('click',handle)

	</script>
</body>
  • 兼容ie
<body>
	<button id="btn">点击我</button>
	<script>
		function handler (){
			console.log('111')
			btn.detachEvent('onclick',handler)
		}
		btn.attachEvent('onclick',handler)

	</script>
</body>

11.3 事件类型

  1. 鼠标事件
    • onclick
    • ondblclick 双击事件
    • oncontextmenu 右键单击
    • onmousedown 鼠标按下
    • onmousemove 鼠标移动
    • onmouseup 鼠标抬起
    • onmouseover onmouseout 移入移出
    • onmouseenter onmouseleave 移入移出
      • 区别: 前者孩子节点的移入移出也会显示; 后者不显示孩子节点的移入移出
<body>
	<button id="btn">点击我</button>
	<script>
		//鼠标事件

		// btn.ondblclick = () => {
		// 	console.log('ondblclick')
		// }

		// btn.oncontextmenu = () => {
		// 	console.log('oncontextmenu')
		// }

		// btn.onmousedown = () => {
		// 	console.log('onmousedown')
		// }

		// btn.onmousemove = () => {
		// 	console.log('onmousemove')
		// }

		// btn.onmouseup = () => {
		// 	console.log('onmouseup')
		// }

	</script>
</body>
<style>
        #box {
                width: 200px;
                height: 200px;
                background-color: yellow;
        }

        #child {
                width: 100px;
                height: 100px;
                background-color: purple;
        }
</style>

<body>
	<div id="box">
		<div id="child">

		</div>
	</div>
	<script>
		//鼠标事件

		// box.onmouseover = () => {
		// 	console.log('移入')
		// }
		// box.onmouseout = () => {
		// 	console.log('移出')
		// }

		// box.onmouseenter = () => {
		// 	console.log('移入')
		// }
		// box.onmouseleave = () => {
		// 	console.log('移出')
		// }

	</script>
</body>
  1. 键盘事件
    • onkeydown 按下键盘
    • onkeyup 松开键盘
<body>
	<input type="text" id="username">
	<script>
		//键盘事件
		username.onkeydown = () => {
			console.log("按下键盘",'判断是不是回车键')
		}

		username.onkeyup = () => {
			console.log("放开键盘",'判断是不是回车键')
		}

	</script>
</body>
  1. 浏览器事件

    • onload 页面全部资源加载完毕
    • onscroll 浏览器滚动的时候触发
  2. 表单事件

    • onfocus 获取焦点
    • onblur 失去焦点
    • onchange 对比获取焦点和失去焦点里面的内容不一样才会触发
    • oninput 内容不一样就触发
    • onreset 重置
    • onsubmit 提交
<input type="text" id="username">
<script>
        //表单事件
        username.onfocus = () => {
                console.log('获取焦点')
        }

        username.onblur = () => {
                console.log('失去焦点')
        }

        // username.onchange = () => {
        // 	console.log('onchange')
        // }

        username.oninput = () => {
                console.log('input')
        }


</script>
<body>
	<form action="" id="myform">
		<input type="text" id="username">
		<input type="reset">
		<input type="submit" value="提交">
	</form>
	
	<script>
		//表单事件
		myform.onsubmit = () => {
			console.log('submit')
			return false
		}
		myform.onreset = () => {
			console.log('reset')
		}

	</script>
</body>
  1. 移动事件
    • ontouchstart 开始触摸
    • ontouchomve 在移动
    • ontouchend 结束触摸
    • 左划右划等都是基于上述三个事件
    • ontouchcancel 在浏览网页时,突然有电话
<style>
        #box {
                width: 200px;
                height: 200px;
                background-color: yellow;
        }
</style>

<body>
	<div id="box"></div>
	
	<script>
		//触摸事件
		box.ontouchstart = () => {
			console.log('ontouchstart')
		}

		box.ontouchmove = () => {
			console.log('ontouchmove')
		}

		box.ontouchend = () => {
			console.log('ontouchend')
		}

		box.ontouchcancel = () => {
			console.log('touchcancle')
		}
	</script>
</body>

11.4 事件对象

  • clientX clientY 距离浏览器可视窗口左上角坐标值的距离,会随着滚动条变化而变化
  • pageX pageY 距离浏览器可视窗口的左上角坐标值
  • offsetX offsetY 相对于盒子的左上角坐标值,距离实际触发的元素左上角的距离
<style>
        * {
                margin: 0;
                padding: 0;
        }
        body {
                width: 2000px;
                height: 2000px;
        }
        div {
                width: 200px;
                height: 200px;
                background-color: blue;
                margin: 100px;
        }
        p {
                width: 100px;
                height: 100px;
                background-color: red;
                margin: 100px;
        }
</style>

<body>
	<div id="box">
		<p>

		</p>
	</div>
	<script>
		box.onclick = (evt) => {
			// console.log(evt)
			console.log(evt.clientX,evt.clientY,'clientX')
			console.log(evt.pageX,evt.pageY,'pageX')
			console.log(evt.offsetX,evt.offsetY,'offsetX')
		}
	</script>
</body>

11.5 案例:鼠标跟随

<style>
        * {
                margin: 0;
                padding: 0;
        }
        #box {
                width: 200px;
                height: 50px;
                background-color: yellow;
                position: relative;
                margin: 100px;
        }
        #box p {
                width: 300px;
                height: 200px;
                background-color: red;
                position: absolute;
                left: 100;
                top: 100;
                display: none;
                /* pointer-events: none; */
                /* 方法二: 防止穿透; 缺点:若后面有div标签,会把p标签盖住,层级低; 解决: z-index:number*/
        }
</style>
        
<body>
	<div id="box">
		chenrruoshuang的头像
		<p>
			chenruoshaung的介绍
		</p>
	</div>
	<script>
		box.onmouseover = function () {
			this.firstElementChild.style.display = 'block'
		} 
		
		box.onmouseout = function (evt) {
			this.firstElementChild.style.display = 'none'
		}

		box.onmousemove =function (evt) {
			// this.firstElementChild.style.left = evt.offsetX + 20 + 'px'
			// this.firstElementChild.style.top = evt.offsetY + 20 +'px'
			//方法一: + 20 防止触碰到p标签
			this.firstElementChild.style.left = evt.offsetX + 'px'
			this.firstElementChild.style.top = evt.offsetY +'px'
		}
	</script>
</body>

11.6 鼠标拖拽

  • 方法一
<style>
        * {
                margin: 0;
                padding: 0;

        }
        #box {
                width: 100px;
                height: 100px;
                background-color: skyblue;
                /* position: relative; */
                position: absolute;
        }

</style>

<body>
	<div id="box">
		
	</div>
	<script>
		box.onmousedown = function() {
			console.log('down')
			console.log(document)
			document.onmousemove = function(evt) {
				console.log('move')
				var x = evt.clientX - box.offsetWidth/2 
				var y = evt.clientY - box.offsetHeight/2
				if ( y <= 0 ) y = 0
				if ( x <= 0 ) x = 0
				if (y>= document.documentElement.clientHeight - box.offsetHeight) y = document.documentElement.clientHeight - box.offsetHeight
				if (x>= document.documentElement.clientWidth - box.offsetWidth) x = document.documentElement.clientWidth - box.offsetWidth

				box.style.left = x +'px'
				box.style.top = y + 'px'
			}
		}
		box.onmouseup = function() {
			console.log('up')
			document.onmousemove = null
		}
		
	</script>
</body>
  • 方法二
<style>
        * {
                margin: 0;
                padding: 0;

        }
        #box {
                width: 100px;
                height: 100px;
                background-color: skyblue;
                /* position: relative; */
                position: absolute;
        }

</style>

<body>
	<div id="box">
		
	</div>
<script>
		var isDown = false
		box.onmousedown = function() {
			isDown = true
			console.log('down')
			console.log(document)
		
		}
		box.onmouseup = function() {
			isDown = false
			console.log('up')
			// document.onmousemove = null
		}

		document.onmousemove = function(evt) {
			if(!isDown) return
			console.log('move')
			var x = evt.clientX - box.offsetWidth/2 
			var y = evt.clientY - box.offsetHeight/2
			if ( y <= 0 ) y = 0
			if ( x <= 0 ) x = 0
			if (y>= document.documentElement.clientHeight - box.offsetHeight) y = document.documentElement.clientHeight - box.offsetHeight
			if (x>= document.documentElement.clientWidth - box.offsetWidth) x = document.documentElement.clientWidth - box.offsetWidth

			box.style.left = x +'px'
			box.style.top = y + 'px'
		}
		
		
	</script>
</body>