提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
事件流
事件流是描述的从页面接受事件的顺序,当几个都具有事件的元素层叠在一起的时候, 那么你点击其中一个元素,并不是只有当前被点击的元素会触发事件,而层叠在你点击范围的所有元素都会触发事件。事件流包括两种模式:冒泡和捕获。
事件冒泡
事件冒泡是从里往外逐个触发. 事件捕获, 是从外往里逐个触发. 现代的浏览器默认情况下都是事件冒泡的模式.
冒泡传递事件
document.onclick=function(){
console.log('我是 document');
};
document.documentElement.onclick=function() {
console.log('我是 html');
};
document.body.onclick= function(){
console.log('我是 body');
};
document.getElementById('box').onclick=function() {
console.log('我是 div');
};
document.getElementsByTagName('input')[0].onclick= function(){
console.log('我是 input');
};
但是一般我们只在指定的节点上添加事件, 而不想让其传递到下层节点触发事件, 这样我们就需要阻止事件冒泡;
阻止事件冒泡有两个方法:
( 在指定不想再继续传递事件的节点的事件执行函数中使用)
1, 取消冒泡, IE
e.cancelBubble = true;
2, 停止传播, 非IE
e.stopPropagation();
例如:
document.getElementsByTagName('input')[0].onclick= function(evt){
var e = evt || window.event;
//可以通过下述两个方法取消事件冒泡
if(e.stopPropagation){
e.stopPropagation();
}else{
e.cancelBubble = true
};
阻止浏览器默认行为
if (e.preventDefault) {
e.preventDefault(); //非IE
}
else {
e.returnValue = false; // IE
}
阻止右键菜单
在之前使用event对象的button属性时, 点击鼠标右键会弹出系统菜单, 如果我们想要创建自己的右键菜单, 则需要先阻止默认的右键菜单
document.oncontextmenu = function(){
console.log("右键被按下");
return false;
}
标签有属性href, 在用户点击超链接标签时, 实际上内部会调用onclick事件,那么如果我们需要在超链接跳转前做一些判断处理, 则可以将onclick指向我们自己的函数,并返回true或者false来决定是否允许超链接跳转;
例如:
var oA = document.getElementsByTagName("a")[0];
oA.onclick = function() {
if(confirm("你确定要跳转吗?")) {
return true;
}
else {
return false;
}
}
<a href=“http://www.baidu.com”>百度一下</a>
所谓拖拽: 就是按住元素后移动位置, 最后松开的过程
onmousedown : //鼠标按下
onmousemove : //鼠标移动
onmouseup : //鼠标松开
在鼠标按下的瞬间, 记录鼠标所在位置与目标元素左边界的距离disX, 以及与上边界的距离disY
公式: 目标元素的left = oEvent.clientX – disX + “px”;
目标元素的top = oEvent.clientY – disY + “px”;
注意:
onmousedown触发事件的对象: 目标元素(即要拖拽的元素);
onmousemove触发事件的对象: document
onmouseup触发事件的对象: document
onmousemove和onmouseup的触发事件对象都是document, 意味着鼠标在网页的任意位置移动鼠标或松开鼠标,都会触发对应的事件;
onmousemove和onmouseup 都要写在onmousedown事件中, 这样就可以保证鼠标按下后才可以移动目标元素(onmousemove)或停止移动(onmouseup)
onload = function() {
var box = document.getElementById("box");
//鼠标按下
box.onmousedown = function(evt) {
var e = evt || event;
//计算鼠标位置与div左边和上边的距离
var disX = e.clientX - box.offsetLeft;
var disY = e.clientY - box.offsetTop;
//鼠标移动
document.onmousemove = function(evt) {
var e = evt || event;
box.style.left = e.clientX - disX + "px";
box.style.top = e.clientY - disY + "px";
}
//鼠标松开
document.onmouseup = function() {
document.onmousemove = null;
document.onmouseup = null;
}
}
}
if (window.getComputedStyle) {
style = window.getComputedStyle(box, null); //支持IE9+及非IE浏览器
} else {
style = box.currentStyle; // IE8及以前
}
事件监听器, 是JS事件中的一种事件触发机制, 我们可以通过添加事件监听器的方式给元素添加事件及执行函数
box.addEventListener(“click”, func, false) : 给box元素添加点击事件(click), 以及事件执行函数func. 针对该函数的三个参数作说明:
第一个参数(“click”) : 事件名称(前面没有on)
第二个参数(func): 事件执行函数名称(没有双引号, 也没有())
第三个参数(false/true) : 是否使用捕捉(反向冒泡),默认false,为冒泡
box.removeEventListener(“click”, func) : 将box元素的点击事件(click), 以及对应的事件执行函数func移除
注: 这里只会删除使用box.addEventListener()方法添加的事件监听器
注: IE8及其以下不支持,火狐和谷歌支持。
box.attachEvent("onclick", fn); //添加事件
box.detachEvent("onclick", fn); //移除事件
//添加事件
function addEvent(obj, type, fn, useCapture){
if (obj.addEventListener) {
obj.addEventListener(type, fn, useCapture);
}
else {
obj.attachEvent("on"+type, fn);
}
}
//移除事件
function removeEvent(obj, type, fn, useCapture){
if (obj.removeEventListener) {
obj.removeEventListener(type, fn, useCapture);
}
else {
obj.detachEvent("on"+type, fn);
}
}
//调用
addEvent(aBtn[0], "click", fn, false);
function fn(){
alert("click 按钮1");
}
aBtn[1].onclick = function(){
removeEvent(aBtn[0], "click", fn, false);
}
<!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>Document</title>
</head>
<body>
<a href="http://www.baidu.com">a标签</a>
<!-- a标签默认会跳转页面 -->
<script>
document.getElementsByTagName('a')[0].onclick = function(e){
console.log("点击了");
// return false 阻止默认行为 遵从w3c但是ie9浏览器之前不支持(常用的)
return false
//ie浏览器 兼容 其他浏览器也可以使用
e.preventDefault()//阻止默认事件\
//针对低版本浏览器
e.returnValue = false
}
</script>
</body>
</html>
<!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>Document</title>
<style>
#bigBox{
width: 500px;
height: 500px;
background-color: aqua;
}
#box{
width: 200px;
height: 200px;
background-color: chartreuse;
}
</style>
</head>
<body>
<div id="bigBox">
<div id="box">
<button id="btn">点击</button>
</div>
</div>
<script>
var box = document.getElementById("box")
var btn = document.getElementById("btn")
var bigBox = document.getElementById("bigBox")
box.onclick = function(){
console.log("按钮盒子被点击了");
}
//在点击div里面的按钮时 会触发div的点击事件 事件冒上去了
//在触发事件的时候 会一层一层向上冒泡 (他同时会触发父类的事件)
//阻止事件冒泡 意思就是阻止事件的向上传递
btn.onclick = function(e){
//得到事件源对象
e = e || window.event
//阻止事件向上冒泡 stopPropagation 这个方法可以阻止事件冒泡 且遵从w3c规则 (兼容各大浏览器 ie9之前不兼容)
e.stopPropagation()
//ie浏览器的阻止事件冒泡 利用一个属性 cancelBubble 设置为true 他也兼容各大浏览器(不遵从w3c规范)
// e.cancelBubble = true //取消冒泡 不建议写
// 建议写法
if(e.stopPropagation){//如果浏览器可以使用
e.stopPropagation()//就使用这个
}else{
e.cacelBubble = true //如果不能使用就使用这个
}
console.log("点击了按钮");
}
bigBox.onclick = function(){
console.log("大盒子被点击了");
}
</script>
</body>
</html>
<!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>Document</title>
<style>
*{margin: 0;padding: 0;}
.bigBox{
width: 500px;
height: 500px;
background-color: pink;
position: absolute;
left: 100px;
top: 50px;
}
#box{
width: 100px;
height: 100px;
background: red;
position: absolute;
}
</style>
</head>
<body>
<div class="bigBox">
<div id="box">
</div>
</div>
<script>
//实现拖拽
//鼠标按下(onmousedown) 然后鼠标移动(onmousemove) 就会跟着动 鼠标松开(onmouseup)就不动了
// offset家族的内容 只读
var box = document.getElementById("box")
var bigBox = document.getElementsByClassName("bigBox")[0]
box.onmousedown = function(){
box.onmousemove = function(e){
e = e || window.event
//获取大盒子的偏移
var bigx = bigBox.offsetLeft
var bigy = bigBox.offsetTop
//获取鼠标的位置
var mouseX = e.pageX
var mouseY = e.pageY
//中心点要要减去的高宽
var w = box.offsetWidth/2
var h = box.offsetHeight/2
//定位设置left值和top值
var left = mouseX - w - bigx// 鼠标坐标-原本的宽度的一半-大盒子的偏移量
var top = mouseY - h - bigy
this.style.left = left+"px"
this.style.top = top+"px"
//里面盒子的偏移量
var x = box.offsetLeft
var y = box.offsetTop
//区间设置
if(x<0){
this.style.left = "0px"
}
if(y<0){
this.style.top = "0px"
}
// x y 的最大区间设置
if(x>bigBox.offsetWidth-w*2){
this.style.left = bigBox.offsetWidth-w*2 + "px"
}
if(y>bigBox.offsetHeight-h*2){
this.style.top = bigBox.offsetHeight-h*2 + "px"
}
}
}
//鼠标弹起事件
box.onmouseup = function(){
box.onmousemove = function(){
}
}
</script>
</body>
</html>
<!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>Document</title>
<style>
*{margin: 0;padding: 0;}
#box{
width: 500px;
height: 500px;
background-color: aqua;
display: flex;
justify-content: center;
align-items: center;
margin: 10px auto;
}
#box1{
width: 100px;
height: 100px;
font-size: 16px;
background-color: darkgoldenrod;
margin-right: 10px;
}
#box2{
width: 100px;
height: 100px;
font-size: 16px;
background-color: darkorange;
margin-left: 10px;
}
</style>
</head>
<body>
<div id="box">
<div id="box1">嗨害嗐</div>
<div id="box2">测试测试测试测试测试</div>
</div>
<script>
// 一个盒子里面有俩个小盒子
var box = document.getElementById("box")
var box1 = document.getElementById("box1")
var box2 = document.getElementById("box2")
// 右键点击第一个小盒子换颜色
box1.onmousedown = function(e){
e.stopPropagation?e.stopPropagation:e.cancelBubble = true
if(e.button == 2){
this.style.backgroundColor = "#ccc"
}
}
// 右键点击第二个小盒子 变内容
box2.onmousedown = function(e){
e.stopPropagation?e.stopPropagation:e.cancelBubble = true
if(e.button == 2){
this.innerText = "我是改变了的内容"
}
}
// 点击大盒子改字体颜色
box.onmousedown = function(){
this.style.color = "red"
// box.style.color = "red"
// e = e || window.event
// if( e.stopPropagation){
// e.stopPropagation()
// }else{
// e.cancelBubble = true
// }
e.stopPropagation?e.stopPropagation:e.cancelBubble = true
}
//事件 右键出现菜单 oncontextmenu 的事件
document.oncontextmenu = function(e){
// return false 后面的内容不会执行 return false一般放在最后一句
//如果第一个可以用就用第一个 不可以使用第二个
e.preventDefault?e.preventDefault():(e.returnValue=false)
}
</script>
</body>
</html>
<!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>Document</title>
<style>
.box{
width: 500px;
height: 500px;
background-color: aquamarine;
position: absolute;
margin: 10px;
}
.header{
width: 100%;
height: 50px;
background-color: blueviolet;
}
.content{
width: 100%;
height: 450PX;
background-color: coral;
}
</style>
</head>
<body>
<div class="box">
<div class="header"><span id="close">关闭</span></div>
<div class="content"></div>
</div>
<script>
//1.窗口拖动和关闭,只可以点击紫色区域才可以拖拽窗口,点击关闭按钮就关闭窗口
var box = document.getElementsByClassName("box")[0]//大盒子
var header = document.querySelector('.header')
//获取第一次的偏移量
var firstL = box.offsetLeft
var firstT = box.offsetTop
header.onmousedown = function(e){
//键盘按下的时候获取值
e = e || window.event
// var l = box.offsetLeft
// var t = box.offsetTop
//得到鼠标在里面的位置 鼠标的位置 - 大盒子的偏移量
var currentX = e.clientX - box.offsetLeft
var currentY = e.clientY - box.offsetTop
document.onmousemove = function(e){
//移动box
e = e || window.event
//得到鼠标的坐标
var x = e.clientX - firstL
var y = e.clientY - firstT
box.style.left = x-currentX + "px"
box.style.top = y-currentY + "px"
}
}
//弹起取消 移动
header.onmouseup = function(){
document.onmousemove = null
document.onmouseup = null
}
// 点击事件 处在键盘按下和弹起之后执行
document.getElementById("close").onmousedown = function(){
box.style.display = "none"
}
</script>
</body>
</html>
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了 阻止事件冒泡和默认行为,拖拽,事件监听器使用,上面是今天的代码