1. 事件对象
event 对象代表事件的状态,比如键盘按键的状态、鼠标的位置、鼠标按钮的状态。
eventTarget.onclick = function() {event}
eventTarget.addEventListener('click', function(event) {})
// 这个event就是事件对象,可以写成 e 或 evt
这个event 是个形参,系统帮我们设定为事件对象,不需要传递实参过去。
当我们注册事件时,event对象就会被系统自动创建,并依次传递给事件监听器(事件处理函数)。
2. 兼容性问题
- 标准浏览器中是浏览器给方法传递的参数,只需定义形参e就可以获取到。
- 在IE6~8中,浏览器不会给方法传递参数,如果需要,需要到window.event 中获取查找。
解决:e = e || window.event;
e.target 和 this 的区别
事件对象属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象 (标准) |
e.srcElement | 返回触发事件的对象 (非标准ie6~8使用) |
e.type | 返回事件的类型 比如 click mouseover 不带on |
e.cancelBubble | 该属性防止冒泡 (非标准ie6~8使用) |
e.returnValue | 该属性阻止默认事件(默认行为) (非标准ie6~8使用)比如不让链接跳转 |
e.preventDefault() | 该方法阻止默认事件(默认行为) (标准)比如不让链接跳转 |
e.stopPropagation() | 防止冒泡 (标准) |
<body>
<div>123</div>
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
//常见事件对象的属性和方法
//e.target 返回的是触发事件的对象(元素) this 返回的是绑定事件的对象(元素)
//区别:e.target点击了哪个元素,就返回哪个元素 this哪个元素绑定了这个点击事件,就返回谁
var div = document.querySelector('div');
div.addEventListener('click', function (e) {
console.log(e.target);
console.log(this);
})
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
//给ul绑定事件 this指向ul
console.log(this);
//e.target 指向点击的那个对象 谁触发了这个事件 点击的是li e.target指向的就是li
console.log(e.target);
})
//兼容性
/* div.onclick = function (e) {
e = e || window.event;
var target = e.target || e.srcElement;
console.log(e.target);
} */
</script>
</body>
3. 阻止默认行为
<body>
<div>123</div>
<a href="http://www.baidu.com">百度</a>
<form action="http://www.baidu.com">
<input type="submit" value="提交" name="sub">
</form>
<script>
//1. 返回事件类型
var div = document.querySelector('div');
div.addEventListener('click', fn);
div.addEventListener('mouseover', fn);
div.addEventListener('mouseout', fn);
function fn(e) {
console.log(e.type);
}
//2. 阻止默认行为 让链接不跳转或者提交按钮不提交
var a = document.querySelector('a');
a.addEventListener('click', function (e) {
e.preventDefault(); //DOM标准
})
//3. 传统方式
a.onclick = function (e) {
//普通浏览器 e.preventDefault();
e.preventDefault();
//低版本浏览器 ie6~8 returnValue
e.returnValue;
//可以利用return false 也能阻止默认行为 没有兼容性问题 return后面的代码不执行
return false;
alert(1);
}
</script>
</body>
4. 阻止事件冒泡
两种:
- 标准写法:利用事件对象里面的
stopPropagation()
方法
e.stopPropagation()
- 非标准写法:IE6~8 利用事件对象
cancelBubble
属性
e.cancelBubble = true;
兼容性问题
if (e && e.stopPropagation) {
e.stopPropagation();
} else {
window.event.cancelBubble = true;
}
5. 事件委托(代理、委派)
原理:不是每个子节点单独设置事件监听器,而是事件监听器设置在父节点上,然后利用冒泡原理影响设置每个子节点。
作用:只操作一次DOM,提高了程序的性能。
<body>
<ul>
<li>我爱你不后悔</li>
<li>我爱你不后悔</li>
<li>我爱你不后悔</li>
<li>我爱你不后悔</li>
</ul>
<script>
//给父节点添加侦听器,利用事件冒泡影响每一个子节点
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
//alert('我爱你不后悔');
// e.target 得到点击的对象
e.target.style.backgroundColor = 'pink';
})
</script>
</body>
6. 禁止选择文字和右键菜单
- 禁止鼠标右键菜单
contextmenu 主要控制应该何时显示上下文菜单,主要用于程序员取消默认的上下文菜单 - 禁止选中文字
<body>
把你藏在心头
<script>
//1. 禁止右键菜单
document.addEventListener('contextmenu', function (e) {
e.preventDefault();
})
//2.禁止选中文字
document.addEventListener('selectstart', function (e) {
e.preventDefault();
})
</script>
</body>
7. 鼠标事件对象
event 对象代表事件的状态,跟事件相关的一系列信息的集合。
MouseEvent
和键盘事件对象KeyboardEvent
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对于浏览器窗可视区的X坐标 |
e.clientY | 返回鼠标相对于浏览器窗可视区的Y坐标 |
e.pageX | 返回鼠标相对于文档页面的X坐标(IE9+支持) |
e.pageY | 返回鼠标相对于文档页面Y坐标(IE9+支持) |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
<script>
//鼠标事件对象
document.addEventListener('click', function (e) {
//1.client鼠标在可视区的xy坐标
console.log(e.clientX);
console.log(e.clientY);
//2.page鼠标在页面文档的xy坐标
console.log(e.pageX);
console.log(e.pageY);
//3.page鼠标在电脑屏幕的xy坐标
console.log(e.screenX);
console.log(e.screenY);
})
</script>
跟随鼠标的天使
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<style>
img {
position: absolute;
top: 2px;
}
</style>
</head>
<body>
<img src="https://www.bing.com/th/id/OGC.32facf6220a4bdd91e2c7612ed04ef55?pid=1.7&rurl=https%3a%2f%2fqq.yh31.com%2ftp%2fzjbq%2f201712261445270050.gif&ehk=1x6IV4gOxcQgC%2fagq7tt8hA269tTbWu878dfu39o8O4%3d"
alt="">
<script>
var pic = document.querySelector('img');
document.addEventListener('mousemove', function (e) {
//鼠标移动1px 就会触发这个事件
//console.log(1);
var x = e.pageX;
var y = e.pageY;
console.log('x坐标是' + x, 'y坐标是' + y);
//加单位px
pic.style.left = x - 160 + 'px';
pic.style.top = y - 100 + 'px';
})
</script>
</body>
</html>
8. 常用键盘事件
键盘事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
onkeypress | 某个键盘按键被按下时触发(但是它不识别功能键 比如 ctrl shift 箭头等) |
<script>
//常用的键盘事件
//1. keyup
document.addEventListener('keyup', function () {
console.log('我弹起了');
})
//2. keydown
document.addEventListener('keydown', function () {
console.log('我按下了down');
})
//3. keypress 不能识别功能键
document.addEventListener('keypress', function () {
console.log('我按下了press');
})
//4.执行顺序:keydown->keypress->keyup
</script>
如果使用addEventListener 不需要加on
9. 键盘事件对象
键盘事件对象属性 | 说明 |
---|---|
keyCode | 返回该键的ASCII码值 |
注意:
- onkeydown 和 onkeyup 不区分大小写,onkeypress 区分
- 更多的使用keyup 和 keydown
<script>
//键盘事件对象中的keyCode属性可以得到相应键的ASCII码值
//1.keyup 和 keydown 事件不区分大小写字母 a和A都是65
//keypress事件区分大小写 a65 A97
document.addEventListener('keyup', function (e) {
//console.log(e);
console.log('up:' + e.keyCode);
})
document.addEventListener('keypress', function (e) {
//console.log(e);
console.log('press:' + e.keyCode);
})
</script>
模拟京东按键输入内容案例
<body>
<input type="text">
<script>
var search = document.querySelector('input');
document.addEventListener('keyup', function (e) {
//console.log(e.keyCode);
if (e.keyCode === 83) {
search.focus();
}
})
</script>
</body>
点击s键会聚焦
模拟京东快递单号查询案例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title></title>
<style>
* {
margin: 0;
padding: 0;
}
.search {
position: relative;
width: 178px;
margin: 100px;
}
.con {
display: none;
position: absolute;
top: -40px;
width: 171px;
border: 1px solid rgba(0, 0, 0, .2);
box-shadow: 0 2px 4px rgba(0, 0, 0, .2);
padding: 5px 0;
font-size: 18px;
line-height: 20px;
color: #333;
}
.con::before {
content: '';
width: 0;
height: 0;
position: absolute;
top: 28px;
left: 18px;
border: 8px solid #000;
border-style: solid dashed dashed;
border-color: #fff transparent transparent;
}
</style>
</head>
<body>
<div class="search">
<div class="con">123</div>
<input type="text" placeholder="请输入您的快递单号" class="jd">
</div>
<script>
var con = document.querySelector('.con');
var jd_input = document.querySelector('.jd');
jd_input.addEventListener('keyup', function () {
if (this.value == '') {
con.style.display = 'none';
} else {
con.style.display = 'block';
con.innerText = this.value;
}
})
//当失去焦点,隐藏盒子
jd_input.addEventListener('blur', function () {
con.style.display = 'none';
})
//当获得焦点,显示盒子
jd_input.addEventListener('focus', function () {
if (this.value !== '') {
con.style.display = 'block';
}
})
</script>
</body>
</html>