今日学习任务
[ ] 1.案例拖拽盒子
[ ] (1)拖拽事件流程
- (2)拖拽盒子原理
- (3)案例:拖拽登陆框
- 2.阻止a标签默认跳转两种常用方式
- 3.注册/移除多个同名事件(addEventListener)
[ ] 4.事件冒泡
[ ] (1)事件冒泡介绍
- (2)事件冒泡利用(事件委托)
- (3)事件冒泡影响
- (4)阻止事件冒泡
[ ] 5.事件捕获
[ ] (1)事件捕获介绍
- (2)事件三个阶段
[ ] 6.事件对象补充属性
[ ] (1)事件类型type
- (2)键盘事件与获取按键
01-案例:拖拽盒子
1.1-拖拽盒子01
思路分析
本小节知识点:鼠标拖拽
复习鼠标事件:
- onclick:鼠标点下去并且弹起来触发(单击一次)
- ondblclick:鼠标连续点击两次(双击)
- onmousedown:鼠标按下就触发
- onmouseup: 鼠标弹起触发
- onmouseover:鼠标移入
- onmouseout:鼠标移出
- onmousemove:鼠标移动
- 鼠标拖拽:(1)先按下 (2)然后移动 (3)最后松开
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
#father {
width: 200px;
height: 400px;
background-color: skyblue;
position: absolute;
top: 0px;
left: 0px;
}
#son {
width: 200px;
height: 100px;
background-color: hotpink;
cursor: move;
}
</style>
</head>
<body>
<div id="father">
<div id="son"></div>
</div>
<script>
/*
复习鼠标事件
鼠标单击:onclick 按下+松开 = 单击一次
鼠标双击:ondblclick
鼠标移入:onmouseover
鼠标移出:onmouseout
鼠标移动:onmousemove
鼠标按下: onmousedown
鼠标松开: onmouseup
拖拽事件
1.鼠标按下 : 给元素注册
2.鼠标移动 : (1)给页面注册 (2)需要在按下的事件处理中注册
3.鼠标松开 : 在按下事件处理中注册
*/
let son = document.getElementById('son');// 与父元素对其 offsetLeft:0
let father = document.getElementById('father');// 父元素 offsetLeft:到body的距离
// son.onclick = function(){
// console.log('鼠标单击');
// };
//1.鼠标按下
son.onmousedown = function (e) {
//1级链
console.log('鼠标按下了');
//1.鼠标按下:求蓝线 = 红线(e.pageX) - 绿线(father.offsetLeft)
let x = e.pageX - father.offsetLeft;
let y = e.pageY - father.offsetTop;
//2.鼠标移动
document.onmousemove = function (e) {
//2级链
//2.求黑线 = 红线(e.pageX) - 蓝线
father.style.left = e.pageX - x + 'px';
father.style.top = e.pageY - y + 'px';
// console.log('鼠标移动');
// console.log(e);
};
//3.鼠标松开
//鼠标松开也可以在按下之后注册:因为如果鼠标没有按下,不可能触发松开事件
son.onmouseup = function () {
console.log('鼠标松开');
//移除鼠标移动事件
document.onmousemove = null;
};
};
</script>
</body>
</html>
1.2-拖拽盒子02(元素有margin)
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
#father {
width: 200px;
height: 400px;
background-color: skyblue;
position: absolute;
top: 0px;
left: 0px;
margin: 50px;
}
#son {
width: 200px;
height: 100px;
background-color: hotpink;
cursor: move;
}
</style>
</head>
<body>
<div id="father">
<div id="son"></div>
</div>
<script>
/*
复习鼠标事件
鼠标单击:onclick 按下+松开 = 单击一次
鼠标双击:ondblclick
鼠标移入:onmouseover
鼠标移出:onmouseout
鼠标移动:onmousemove
鼠标按下: onmousedown
鼠标松开: onmouseup
拖拽事件
1.鼠标按下 : 给元素注册
2.鼠标移动 : (1)给页面注册 (2)需要在按下的事件处理中注册
3.鼠标松开 : 在按下事件处理中注册
*/
let son = document.getElementById('son');// 与父元素对其 offsetLeft:0
let father = document.getElementById('father');// 父元素 offsetLeft:到body的距离
// son.onclick = function(){
// console.log('鼠标单击');
// };
/*发现问题:为什么元素添加margin之后,拖拽会有顿闪效果
分析问题: 元素定位是按照margin左上角来定位
解决问题: 如果元素有margin,则应该减去margin
*/
//1.鼠标按下
son.onmousedown = function (e) {
//1级链
console.log('鼠标按下了');
//1.鼠标按下:求蓝线 = 红线(e.pageX) - 绿线(father.offsetLeft)
let x = e.pageX - father.offsetLeft;
let y = e.pageY - father.offsetTop;
//2.鼠标移动
document.onmousemove = function (e) {
//2级链
//2.求黑线 = 红线(e.pageX) - 蓝线
father.style.left = e.pageX - x - 50 + 'px';
father.style.top = e.pageY - y -50 + 'px';
// console.log('鼠标移动');
// console.log(e);
};
//3.鼠标松开
//鼠标松开也可以在按下之后注册:因为如果鼠标没有按下,不可能触发松开事件
son.onmouseup = function () {
console.log('鼠标松开');
//移除鼠标移动事件
document.onmousemove = null;
};
};
</script>
</body>
</html>
1.3-案例:拖拽登录验证
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.wrap {
width: 360px;
height: 180px;
margin: 50px auto;
border: 1px solid black;
position: relative;
}
.wrap .icon {
position: absolute;
left: 0;
top: 60px;
}
.wrap .progress {
width: 100%;
height: 40px;
position: relative;
top: -4px;
background-color: pink;
}
.cube {
position: absolute;
width: 40px;
height: 40px;
background-color: red;
cursor: pointer;
}
.bar {
position: absolute;
width: 0px;
height: 40px;
background-color: green;
}
</style>
</head>
<body>
<div class="wrap">
<img src="./images/drag01.png" alt="">
<img class="icon" src="./images/drag02.png" alt="">
<div class="progress">
<div class="bar"></div>
<div class="cube"></div>
</div>
</div>
<script>
/*
1.分析需求(交互):
拖拽小方块cube :
a. cube小方块 水平移动
b. bar进度条变宽
c. icon小图片对应(移动距离一致)水平移动
d. 检测icon小图片位置是否正确
2.思路分析(事件三要素)
获取元素:事件源:
注册事件:事件类型
事件处理:
*/
//1.获取元素
let wrap = document.querySelector('.wrap');
let cube = document.querySelector('.cube');
let bar = document.querySelector('.bar');
let icon = document.querySelector('.icon');
//2.注册拖拽事件
//(1)注册鼠标按下
cube.onmousedown = function (e) {
e = e || window.event;
//记录鼠标按下时的 e.pageX
let x = e.pageX;
//(2)注册鼠标移动:页面
document.onmousemove = function (e) {
e = e || window.event;
//a. 蓝线距离 = 鼠标移动e.pageX - 鼠标按下e.pageX
let x1 = e.pageX - x;
//b. 边界检测
x1 = x1 <= 0 ? 0 : x1;
/* 最大位移 = 父盒子宽度 - 小方块宽度 */
let maxLeft = wrap.offsetWidth - cube.offsetWidth;
x1 = x1 >= maxLeft ? maxLeft : x1;
//c. 小方块移动
cube.style.left = x1 + 'px';
//d. 进度条变宽
bar.style.width = x1 + 'px';
//e. 小图标对应移动
icon.style.left = x1 + 'px';
};
//(3)注册鼠标松开
document.onmouseup = function () {
//移除鼠标移动
document.onmousemove = null;
//检测小图标位置是否正确
if(icon.offsetLeft > 150 && icon.offsetLeft < 160){
alert('验证成功,即将跳转登录页');
//刷新页面
window.location.href = 'http://www.itheima.com';
}else{
alert('验证失败,请重新验证');
//刷新页面
window.location.reload();
}
};
};
</script>
</body>
</html>
02-阻止a标签默认跳转
1.1-阻止a标签跳转两种常用方式
- 默认情况下,点击a标签会跳转到一个新的网页,这叫做超链接
- 某些情况下,我们只希望拿到a标签的样式(鼠标放上去有小手,用户很直观的知道这可以点击),而不希望跳转到新的网页这个时候我们就可以阻止a标签的跳转
以下几种不需要死记硬背,实际开发习惯任何一种即可
原理了解即可:
- 第一种:给a标签添加点击事件,在点击事件中return false(建议使用,用于任意跳转a标签)
- 第二种:给a标签的href属性设置一个伪链接(一般不用,用于页内跳转的a标签)
课外拓展
- 打电话:tel:
- 发邮件:mailto:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--默认情况下,点击a标签会跳转到一个新的网页,这叫做超链接
某些情况下,我们只希望拿到a标签的样式(鼠标放上去有小手,用户很直观的知道这可以点击),而不希望跳转到新的网页
这个时候我们就可以阻止a标签的跳转
以下几种不需要死记硬背,实际开发习惯任何一种即可
* 原理了解即可:第一种:给a标签添加点击事件,在点击事件中return false
第二种:给a标签的href属性设置一个伪链接
-->
<!--行内写法-->
<a href="#" target="_blank" onclick="alert('哈哈,有SB点击我了');return false;">跳转1</a>
<!--注意:只要是行内写法,就需要在行内return false-->
<a href="#" target="_blank" onclick="test1();return false;">跳转2</a>
<!--内联写法,直接在函数中return false即可-->
<a href="#" target="_blank" id="link">跳转3</a>
<!--设置href属性伪链接:主要此时不要使用target='_blank',要不然无效-->
<a href="javascript:void(0)">跳转4</a>
<a href="javascript:;">跳转5</a>
</body>
<script>
function test1 ( ) {
alert('今晚');
}
let link = document.getElementById('link');
link.onclick = function ( ) {
alert('大吉');
return false;
}
</script>
</html>
1.2-案例:页面换肤
需求:点击上方小图,下方展示对应大图
思路:
- 1.将图片的路径放入a标签的href属性中,并且禁用a标签的默认跳转
- 2.给每一个a标签添加点击事件
- 3.点击时,取出本次点击的a标签的href属性的值,赋值给下方大图的src属性
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.small {
width: 180px;
}
li {
float: left;
list-style: none;
margin-right: 20px;
}
ul {
width: 1000px;
margin: 0 auto;
height: 160px;
}
.father {
width: 1000px;
margin: 0 auto;
}
.father #bigPic {
width: 1000px;
}
</style>
</head>
<body>
<ul id="ul1">
<li><a href="images/01.jpg"><img src="images/01.jpg" alt="" class="small"/></a></li>
<li><a href="images/02.jpg"><img src="images/02.jpg" alt="" class="small"/></a></li>
<li><a href="images/03.jpg"><img src="images/03.jpg" alt="" class="small"/></a></li>
<li><a href="images/04.jpg"><img src="images/04.jpg" alt="" class="small"/></a></li>
<li><a href="images/05.jpg"><img src="images/05.jpg" alt="" class="small"/></a></li>
</ul>
<div class="father">
<img src="images/01.jpg" alt="" id="bigPic"/>
</div>
<script>
/*
1.分析需求(交互):点击上方a标签:取出a标签中img元素的src属性赋值给下方大图的src
2.思路分析(事件三要素)
获取元素:事件源:
注册事件:事件类型
事件处理:
*/
//1.获取元素
let aList = document.querySelectorAll('a');
let bigPic = document.querySelector('#bigPic')
//2.注册事件
for(let i = 0;i<aList.length;i++){
aList[i].onclick = function(){
//3.事件处理:取出a标签中img元素的src属性赋值给下方大图的src
console.log(this);
//第一种方式:通过children取出a标签子元素img标签的src属性值
//bigPic.src = this.children[0].src;
//另一种方式:一旦阻止a标签默认跳转。href属性失效,但是可以用来存储自定义数据
bigPic.src = this.href;
return false;
};
};
</script>
</body>
</html>
03-注册/移除多个同名事件(addEventListener)
1.1-addEventListener注册事件
- 本小节知识点:如何给一个元素添加多个相同事件
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<input type="button" value="点我" id="btn"/>
</body>
</html>
<script>
/*本小节知识点:如何给一个元素添加多个相同事件
*/
let btn = document.getElementById ( "btn" )
//用这样的方式添加相同的事件,后面的会覆盖前面的
// btn.onclick = function () {
//
// alert("点一次200块");
// }
//
// btn.onclick = function () {
//
// alert("点我干啥?");
// }
//可以给同名的事件,绑定多个事件处理程序
//语法:对象.addEventListener(参数1,参数2,参数3);
//参数1:事件名(字符串),不要加on 例如:click 、 mouseover 、mouseout
//参数2:事件处理程序(函数名),当事件触发后哪个函数来处理
//参数3:是一个bool类型,可以不传,默认为fasle(代表冒泡)跟冒泡和捕获有关
//如果有同名事件不会覆盖,而是会依次执行
//IE8及以前的版本不支持
/*
btn.addEventListener ( "click", function ( e ) {
e = e || window.event
alert ( "嘿嘿嘿" )
console.log ( e )
}, false )
btn.addEventListener ( "click", function () {
alert ( "哈哈哈" )
} )
//如果传入已经存在的函数,那么直接写函数名,千万不要写小括号
btn.addEventListener ( "click", sayHi, false )
function sayHi ( e ) {
e = e || window.event
alert ( "你来追我呀!" )
console.log ( e )
}
*/
//只有IE8以前支持的方法,其他的都不支持
//只有2个参数
//参数1:事件名(字符串),但是要加on
//参数2:事件处理程序。事件触发时哪个函数来响应
//后面的先执行,前面的后执行
/*
btn.attachEvent("onclick", function () {
alert("祝中间的早晚偷情成功");
});
btn.attachEvent("onclick", function () {
alert("祝隔壁老王和我隔壁的幸福");
});
*/
/*兼容性封装*/
/** 给元素添加多个相同的事件
* @param obj:元素 eventName:事件名 fn:事件处理函数
* @return 无
*/
function addEvent(obj, eventName, fn) {
//能力检测
if (obj.addEventListener) { //非IE8
obj.addEventListener(eventName, fn);
} else if (obj.attachEvent) { //IE8
obj.attachEvent("on" + eventName, fn);
} else { //默认方式
obj["on" + eventName] = fn;
}
}
</script>
1.2-removeEventListener移除事件
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>标题</title>
</head>
<body>
<input type="button" value="按钮" id="btn"/>
<script>
let btn = document.getElementById("btn");
//1.on+事件名称的方式
// btn.onclick = function () {
// alert("哈哈");
// btn.onclick = null; //移除事件。
// }
//2.元素名.addEventListener注册的事件,移除方式
//元素名.removeEventListener(参数1,参数2,参数3);
//参数1:事件名称
//参数2:事件处理程序
//参数3:布尔类型的值
// function test() {
// alert("哈哈");
// }
// btn.addEventListener("click", test,false);
// btn.removeEventListener("click",test,false)
//3.元素名.attachEvent注册的事件移除方式
//元素名.detachEvent(参数1,参数2)
//参数1:事件名称 是加了on的方式
//参数2:事件处理程序。
// function test2(){
// alert("哈哈哈哈哈哈啊....");
// }
// btn.attachEvent("onclick",test2);
// btn.detachEvent("onclick",test2);
//4.移除事件,不同的添加方式,使用不同的方式移除,所以要做兼容处理。
function removeEventListener(obj,type,listener){
//能力检测
if(obj.removeEventListener){
obj.removeEventListener(type,listener,false);
}else if(obj.detachEvent){
obj.detachEvent("on"+type,listener);
}else {
obj["on"+type] = null;
}
}
//5.对封装的函数做一个测试
function ceshi(){
alert("呵呵呵嘻嘻嘻嘻....cs移出事件函数....");
}
addEventListener(btn,"click",ceshi);
removeEventListener(btn,"click",ceshi);
//4.给某一个元素注册多个相同的事件,不同的浏览器有不同的方式,所以要做兼容。
function addEventListener(obj,type,listener){
//能力检测
if(obj.addEventListener){
obj.addEventListener(type,listener,false);
}else if(obj.attachEvent){
obj.attachEvent("on"+type,listener);
}else {
obj["on"+type] = listener;
}
}
</script>
</body>
</html>
04-事件冒泡
1.1-事件冒泡介绍
本小节知识点:介绍什么是事件冒泡
事件冒泡:如果一个元素的事件被触发,那么他的所有父级元素的同名事件也会被依次触发
元素->父元素->body->html->document->window
- 事件冒泡一直存在,只不过以前我们没有给父级元素加同名事件
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
#box{
width: 300px;
height: 300px;
background-color: hotpink;
position: relative;
}
#son{
width: 100px;
height: 100px;
position: absolute;
left: 350px;
top: 350px;
background-color: yellowgreen;
}
</style>
</head>
<body>
<div id="box">
<input type="button" value="点我" id="btn"/>
<div id="son"></div>
</div>
</body>
</html>
<script>
/*本小节知识点:介绍什么是事件冒泡
* 事件冒泡:如果一个元素的事件被触发,那么他的所有父级元素的同名事件也会被依次触发
* 元素->父元素->body->html->window
*事件冒泡一直存在,只不过以前我们没有给父级元素加同名事件
*/
window.onclick = function () {
alert("window被点击了");
}
document.onclick = function () {
alert("文档被点击了");
}
document.documentElement.onclick = function () {
alert("html被点击了");
}
document.body.onclick = function () {
alert("body被点击了");
}
document.getElementById("box").onclick = function () {
alert("我是骚粉的大盒子");
};
document.getElementById("btn").onclick = function () {
alert("我是小按钮");
};
document.getElementById("son").onclick = function () {
alert("我是又黄又绿的小盒子");
};
</script>
1.2-事件冒泡利用(事件委托)
本小节知识点:介绍事件冒泡的好处
事件冒泡好处:如果想给父元素的多个子元素添加事件,我们可以只需要给父元素添加事件即可,然后
通过获取事件源(e.target)就可以得知是哪一个子元素触发了这个事件
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
<ul id="ul1">
<li>隔壁老王1</li>
<li>隔壁老王2</li>
<li>隔壁老王3</li>
<li>隔壁老王4</li>
<li>隔壁老王5</li>
</ul>
</body>
</html>
<script>
/*本小节知识点:介绍事件冒泡的好处
事件冒泡好处:如果想给父元素的多个子元素添加事件,我们可以只需要给父元素添加事件即可,然后
通过获取事件源(e.target)就可以得知是哪一个子元素触发了这个事件
*/
let ul = document.getElementById("ul1");
//1.如果想给ul中的每一个li标签添加点击事件,以前的做法需要遍历ul的li标签逐个添加
// for (let i = 0; i < ul.children.length; i++) {
//
// ul.children[i].onclick = function () {
//
// alert(this.innerHTML);
// }
// }
//2.使用时间冒泡:只需要给父元素添加点击事件即可
ul.onclick = function (e) {
e = e || window.event;
let target = e.target || e.srcElement;
console.log(target.innerHTML);
//target:事件源:触发本次事件的源头
alert(e.target.innerHTML);
}
</script>
1.3-事件冒泡影响
本小节知识点:介绍事件冒泡的影响
- 事件冒泡会导致需求冲突:例如我想要添加一个功能,弹出登录窗之后点击body空白区域让登陆窗消失
- 此时a标签弹出登录窗的点击事件会触发body的点击事件,导致登陆窗一出来就消失
- 解决方案:阻止事件冒泡(下一小节知识点)
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
.login-header {
width: 100%;
text-align: center;
height: 30px;
font-size: 24px;
line-height: 30px;
}
html, body, ul, li, ol, dl, dt, dd, div, p, span, h1, h2, h3, h4, h5, h6, a {
padding: 0px;
margin: 0px;
}
.login {
width: 512px;
position: absolute;
border: #ebebeb solid 1px;
height: 280px;
left: 50%;
right: 50%;
background: #ffffff;
box-shadow: 0px 0px 20px #ddd;
z-index: 9999;
margin-left: -256px;
margin-top: 140px;
display: none;
}
.login-title {
width: 100%;
margin: 10px 0px 0px 0px;
text-align: center;
line-height: 40px;
height: 40px;
font-size: 18px;
position: relative;
cursor: move;
}
.login-input-content {
margin-top: 20px;
}
.login-button {
width: 50%;
margin: 30px auto 0px auto;
line-height: 40px;
font-size: 14px;
border: #ebebeb 1px solid;
text-align: center;
}
.login-bg {
width: 100%;
height: 100%;
position: fixed;
top: 0px;
left: 0px;
background: #000000;
opacity: 0.3;
display: none;
}
a {
text-decoration: none;
color: #000000;
}
.login-button a {
display: block;
}
.login-input input.list-input {
float: left;
line-height: 35px;
height: 35px;
width: 350px;
border: #ebebeb 1px solid;
text-indent: 5px;
}
.login-input {
overflow: hidden;
margin: 0px 0px 20px 0px;
}
.login-input label {
float: left;
width: 90px;
padding-right: 10px;
text-align: right;
line-height: 35px;
height: 35px;
font-size: 14px;
}
.login-title span {
position: absolute;
font-size: 12px;
right: -20px;
top: -30px;
background: #ffffff;
border: #ebebeb solid 1px;
width: 40px;
height: 40px;
border-radius: 20px;
}
</style>
</head>
<body>
<div class="login-header">
<a id="link" href="javascript:void(0);">点击,弹出登录框</a>
</div>
<div id="login" class="login">
<div id="title" class="login-title">登录会员
<span>
<a id="closeBtn" href="javascript:void(0);" class="close-login"> 关闭</a>
</span>
</div>
<div class="login-input-content">
<div class="login-input">
<label>用户名:</label>
<input type="text" placeholder="请输入用户名" name="info[username]" id="username" class="list-input">
</div>
<div class="login-input">
<label>登录密码:</label>
<input type="password" placeholder="请输入登录密码" name="info[password]" id="password" class="list-input">
</div>
</div>
<div id="loginBtn" class="login-button"><a href="javascript:void(0);" id="login-button-submit">登录会员</a></div>
</div>
<div id="bg" class="login-bg"></div>
<script src="common.js"></script>
<script>
/*本小节知识点:介绍事件冒泡的影响
事件冒泡会导致需求冲突:例如我想要添加一个功能,弹出登录窗之后点击body空白区域让登陆窗消失
此时a标签弹出登录窗的点击事件会触发body的点击事件,导致登陆窗一出来就消失
解决方案:阻止事件冒泡(下一小节知识点)
*/
//找到弹出窗口的a标签
let open = document.getElementById("link");//点击弹出登录窗口
//找到整个登录窗口
let login = document.getElementById("login");//需要移动
//找到背景阴影
let bg = document.getElementById("bg");//弹出登录窗后需要修改颜色
//找到登录的标题部分
let title = document.getElementById("title");//需要拖拽
/*添加需求:点击页面空白区域让登录窗消失 */
window.onclick = function () {
login.style.display = "none";
bg.style.display = "none";
}
//a标签点击事件
open.onclick = function (e) {
login.style.display = "block";
bg.style.display = "block";
//阻止事件冒泡
e.stopPropagation();
}
//关闭按钮点击事件
document.getElementById("closeBtn").onclick = function () {
login.style.display = "none";
bg.style.display = "none";
};
//title按下事件
title.onmousedown = function (e) {
e = e || window.event;
let x = getPagePoint(e).pageX - login.offsetLeft;
let y = getPagePoint(e).pageY - login.offsetTop;
//页面添加鼠标移动事件
document.onmousemove = function (event) {
event = event || window.event;
//login大盒子的margin-left: -256px, margin-top: 140px
//1 - -256 = 257 减去负数就相当于加这个数 (负负得正)
login.style.left = getPagePoint(event).pageX - x + 256 + "px";
login.style.top = getPagePoint(event).pageY - y - 140 + "px";
}
//鼠标弹起后停止移动事件
this.onmouseup = function () {
document.onmousemove = null;
}
}
</script>
</body>
</html>
1.4-阻止事件冒泡
本小节知识点:阻止事件冒泡
- 阻止事件冒泡:让同名事件不要在父元素中冒泡(触发)
* 说人话:点击一个元素只会触发当前元素的事件,不会触发父元素的同名事件
语法: 事件对象.stopPropagation() IE8及之前不支持
事件对象.cancelBubble = true IE8之前支持
注意:如果想要阻止事件冒泡,一定要在触发事件的函数中接收事件对象
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
#box{
width: 300px;
height: 300px;
background-color: hotpink;
position: relative;
}
#son{
width: 100px;
height: 100px;
position: absolute;
left: 350px;
top: 350px;
background-color: yellowgreen;
}
</style>
</head>
<body>
<div id="box">
<input type="button" value="点我" id="btn"/>
<div id="son"></div>
</div>
</body>
</html>
<script>
/*本小节知识点:阻止事件冒泡
* 阻止事件冒泡:让同名事件不要在父元素中冒泡(触发)
* 说人话:点击一个元素只会触发当前元素的事件,不会触发父元素的同名事件
* 语法: 事件对象.stopPropagation() IE8及之前不支持
* 事件对象.cancelBubble = true IE8之前支持
*
* 注意:如果想要阻止事件冒泡,一定要在触发事件的函数中接收事件对象
*/
window.onclick = function () {
alert("window被点击了");
}
document.onclick = function () {
alert("文档被点击了");
}
document.documentElement.onclick = function () {
alert("html被点击了");
}
document.body.onclick = function () {
alert("body被点击了");
}
document.getElementById("box").onclick = function (e) {
e = e || window.event;
alert("我是骚粉的大盒子");
// e.stopPropagation();
//e.cancelBubble = true;//IE8及之前
stopPropagation(e);//兼容性封装函数
//阻止事件冒泡的这行代码可以写在这个事件函数的任意位置,一般习惯写在最后面
};
document.getElementById("btn").onclick = function () {
alert("我是小按钮");
};
document.getElementById("son").onclick = function () {
alert("我是又黄又绿的小盒子");
};
/** 阻止事件冒泡兼容性封装
* @param e:事件对象
* @return 无
*/
function stopPropagation( e) {
e = e || window.event;
if(e.stopPropagation){
e.stopPropagation();
}else{
e.cancelBubble = true;
}
}
</script>
05-事件捕获
1.1-事件捕获介绍
本小节知识点:事件捕获
- 1.事件冒泡:从触发事件元素,一级一级往上找父元素触发同名事件,如果有就触发
2.事件捕获:从最顶级的父元素一级一级往下找子元素触发同名事件,直到触发事件的元素为止
- 事件捕获与事件冒泡触发事件的顺序完全相反
3.事件捕获,只能通过addEventListener并且参数写true才是事件捕获
- 其他都是冒泡(不是通过addEventListener添加、addEventListener参数为false)
- 4.事件对象.stopPropagation() 除了可以阻止冒泡还可以阻止捕获
- 5.IE8及以前没有捕获!
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
#box {
width: 300px;
height: 300px;
background-color: hotpink;
position: relative;
}
#son {
width: 100px;
height: 100px;
position: absolute;
left: 350px;
top: 350px;
background-color: yellowgreen;
}
</style>
</head>
<body>
<div id="box">
<div id="son"></div>
</div>
</body>
</html>
<script>
/*本小节知识点:事件捕获
1.事件冒泡:从触发事件元素,一级一级往上找父元素触发同名事件,如果有就触发
2.事件捕获:从最顶级的父元素一级一级往下找子元素触发同名事件,直到触发事件的元素为止
* 事件捕获与事件冒泡触发事件的顺序完全相反
3.事件捕获,只能通过addEventListener并且参数写true才是事件捕获
* 其他都是冒泡(不是通过addEventListener添加、addEventListener参数为false)
4.事件对象.stopPropagation() 除了可以阻止冒泡还可以阻止捕获
5.IE8及以前没有捕获!
*/
let box = document.getElementById("box");
let son = document.getElementById("son");
window.addEventListener("click", function () {
alert("这是window");
},true)
document.addEventListener("click", function () {
alert("这是document");
},true)
document.documentElement.addEventListener("click", function (e) {
e = e || window.event;
alert("这是html");
e.stopPropagation();//阻止事件冒泡和事件捕获
},true)
document.body.addEventListener("click", function () {
alert("这是body");
},true)
//参数3:默认是false,代表是支持事件冒泡
box.addEventListener("click", function () {
alert("这是box");
},true)
son.addEventListener("click", function () {
alert("这是son");
},true)
</script>
1.2-事件三个阶段
本小节知识点:介绍事件的三个阶段
1.事件一共有三个阶段:事件的执行顺序
- 1—捕获阶段 :
- 2—目标阶段 :
- 3—冒泡阶段 :
- 2.事件对象.eventPhase 可以获得触发这个事件时,到底是哪个阶段
- 3.先从最顶级往下一级一级捕获,然后到目标的捕获,目标的冒泡,再一级一级往上冒泡
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>标题</title>
<style>
.one {
width: 200px;
height: 200px;
background-color: pink;
}
.son {
width: 100px;
height: 100px;
background-color: green;
position: absolute;
left: 250px;
top: 250px;
}
</style>
</head>
<body>
<div class="one" id="box">
<input type="button" value="按钮" id="btn"/>
<div class="son" id="son"></div>
</div>
<script>
/*本小节知识点:介绍事件的三个阶段
1.事件一共有三个阶段:事件的执行顺序
1--捕获阶段 :
2--目标阶段 :
3--冒泡阶段 :
2.事件对象.eventPhase 可以获得触发这个事件时,到底是哪个阶段
3.先从最顶级往下一级一级捕获,然后到目标的捕获,目标的冒泡,再一级一级往上冒泡
*/
let box = document.getElementById("box");
let btn = document.getElementById("btn");
let son = document.getElementById("son");
document.addEventListener("click",function (e) {
alert("document"+ e.eventPhase);
},true) ;//true表示事件捕获,所以是阶段1,并且优先执行
document.body.addEventListener("click", function (e) {
alert("哈哈,我是body"+ e.eventPhase);
},false);
box.addEventListener("click",function (e) {
alert("哈哈哈,我是粉色的盒子box..."+ e.eventPhase);
},false);
btn.addEventListener("click",function (e) {
alert("哈哈哈,我是按钮btn..."+ e.eventPhase);
},false);
son.addEventListener("click",function (e) {
alert("嘻嘻嘻,我是绿色的盒子son"+ e.eventPhase);
},false);
</script>
</body>
</html>
06-事件对象补充属性(事件类型、键盘按键)
1.1-事件类型e.type
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<!--
事件对象.type 能获取到触发事件的事件名
-->
</head>
<body>
<input type="button" value="按钮" id="btn"/>
</body>
</html>
<script>
let btn = document.getElementById('btn');
/*
btn.onclick = function (e) {
console.log("我被点了");
console.log(e.type);//获取事件名,获取到的是click
};
btn.onmouseover = function (e) {
console.log(e.type);//mouseover
};
*/
btn.onclick = f1;
btn.onmouseover = f1;
function f1(e){
//如果是点击触发的,那么就是click,如果是鼠标移入触发的就是mouseover
console.log(e.type);
}
</script>
1.2-键盘事件及获取键盘按键
本小节知识点:介绍键盘的事件和获取按键
1.键盘事件
- onkeydown:键盘按下触发
- onkeyup:键盘弹起触发
- onkeypress:键盘按下并弹起会触发
onkeydown和onkeypress的区别:了解即可
- onkeypress可以过滤掉特殊的功能键例如删除、F1-F12,shift,alt键等等,onkeydown不会过滤
- onkeypress可以区分大小写,但是onkeydown永远都是大写(不管大小写状态)
2.如何获取你到底按的是哪个键?
- 通过事件对象获取 语法: 事件对象.keyCode
- 获取到的是键盘对应字符的ascii码
- ascii码转字符:String.fromCharCode(code)
3.有三个属性都可以获取到按下的键
keyCode(IE8及之前),charCode,which
所以为了保证一定能获取到,就做兼容
let code = e.keyCode || e.charCode || e.which;
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
</head>
<body>
</body>
</html>
<script>
/*本小节知识点:介绍键盘的事件和获取按键
1.键盘事件
onkeydown:键盘按下触发
onkeyup:键盘弹起触发
onkeypress:键盘按下并弹起会触发(用的比较多)
onkeydown和onkeypress的区别:了解即可
1.onkeypress可以过滤掉特殊的功能键例如删除、F1-F12,shift,alt键等等,onkeydown不会过滤
2.onkeypress可以区分大小写,但是onkeydown永远都是大写(不管大小写状态)
2. 如何获取你到底按的是哪个键?
* 通过事件对象获取 语法: 事件对象.keyCode
* 获取到的是键盘对应字符的ascii码
* ascii码转字符:String.fromCharCode(code)
3.有三个属性都可以获取到按下的键
keyCode(IE8及之前),charCode,which
keydown\keyup:keyCode
keypress:charCode
所以为了保证一定能获取到,就做兼容
let code = e.keyCode || e.charCode || e.which;
*/
document.onkeypress = function (e) {
e = e || window.event
let code = e.keyCode || e.charCode || e.which;
console.log("press触发了 : " + code);
//根据ASCII码转换成字符
console.log(String.fromCharCode(code));
};
//打开浏览器,按下任何键就触发了
document.onkeydown = function (e) {
e = e || window.event
console.log("down触发了 : " + e.keyCode);
console.log(String.fromCharCode(e.keyCode));
};
</script>
1.3-右键事件
网页默认都有右键事件,是一个菜单
右键事件:contextmenu
阻止右键默认的事件:e.preventDefault()
自定义右键菜单
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title></title>
<style>
* {
padding: 0;
margin: 0;
}
.box {
display: none;
position: fixed;
width: 120px;
border: 1px solid #dadce0;
}
.box li {
list-style: none;
width: 110px;
float: left;
line-height: 30px;
padding-left: 10px;
font-size: 14px;
}
</style>
</head>
<body>
<div class="box">
<ul>
<li>复制</li>
<li>粘贴</li>
<li>剪切</li>
</ul>
</div>
<script>
// 右键一般是默认事件,但是有些情况下不需要右键的默认事件,需要自定义,如游戏、办公系统等
document.addEventListener('contextmenu',function(e){
// 事件兼容处理
e = e || window.event;
// 阻止默认事件
e.preventDefault();
// 显示菜单:事件右侧
let box = document.querySelector('.box');
box.style.backgroundColor = '#ffffff';
box.style.left = e.pageX + 'px';
box.style.top = e.pageY + 'px';
box.style.display = 'block';
});
</script>
</body>
</html>