事件
- 注意点: 事件方法都是没有驼峰的
- ==移动端和 PC 端各自有特有的事件==
- css 的 pointerevents: none; 能使对应选择器选到的 dom 不响应不拦截事件 css 的 pointerevents: none; 能使对应选择器选到的 dom 不响应不拦截事件
移入, 移出, 移动 (移动端没有移入移出事件)
- .onmouseover .onmouseenter
- .onmouseout .onmouseleave
- .onmousemove
- 淦!居然没驼峰
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>13-JavaScript-移入移出事件</title>
<style>
*{
margin: 0;
padding: 0;
}
div{
width: 300px;
height: 300px;
background: red;
}
</style>
</head>
<body>
<div></div>
<script>
let oDiv = document.querySelector("div");
// 1.移入事件
// oDiv.onmouseover = function () {
// console.log("移入事件");
// }
// 注意点: 对于初学者来说, 为了避免未知的一些BUG, 建议使用onmouseenter
oDiv.onmouseenter = function () {
console.log("移入事件");
}
// 2.移出事件
// oDiv.onmouseout = function () {
// console.log("移出事件");
// }
// 注意点: 对于初学者来说, 为了避免未知的一些BUG, 建议使用onmouseleave
oDiv.onmouseleave = function () {
console.log("移出事件");
}
3.移动事件
oDiv.onmousemove = function () {
console.log("移动事件");
}
</script>
</body>
</html>
表单焦点事件
- .onfocus
- .onblur
- .onchange (只在失焦后才能拿到修改后的数据)
- .oninput (实时获取到修改后的数据)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>17-JavaScript-焦点事件</title>
</head>
<body>
<input type="text">
<script>
let oInput = document.querySelector("input");
// 1.监听input获取焦点
oInput.onfocus = function () {
console.log("获取到了焦点");
}
// 2.监听input失去焦点
oInput.onblur = function () {
console.log("失去了焦点");
}
// 3.监听input内容改变
// 注意点: onchange事件只有表单失去焦点的时候, 才能拿到修改之后的数据
oInput.onchange = function () {
console.log(this.value);
}
// oninput事件可以时时获取到用户修改之后的数据, 只要用户修改了数据就会调用(执行)
// 注意点: oninput事件只有在IE9以上的浏览器才能使用
// 在IE9以下, 如果想时时的获取到用户修改之后的数据, 可以通过onpropertychange事件来实现
oInput.oninput = function () {
console.log(this.value);
}
</script>
</body>
</html>
添加事件的三种方式
- element.onxxx
- element.attachEvent (上古, 了解即可)
- element.addEventListener (现代,可选事件冒泡 or 捕获)
方法一:onxxx
注意点:
- 由于是给属性赋值, 所以后赋值的会覆盖先赋值
- 缺点很明显: 不能通过一个事件触发多个方法, 不利于维持方法的细粒度
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>onclick</title>
</head>
<body>
<button id="btn">我是按钮</button>
<script>
// 这点击事件只会输出 777, 原理就是给对象属性重赋值会对原有的值进行覆盖
var oBtn = document.getElementById("btn");
oBtn.onclick = function () {
alert("666");
}
oBtn.onclick = function () {
alert("777");
}
</script>
</body>
</html>
方法二:attachEvent
注意点:
- 事件名称必须加上on
- 后添加的不会覆盖先添加的
- 只支持低版本的浏览器
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>attachEvent</title>
</head>
<body>
<button id="btn">我是按钮</button>
<script>
// 既输出 666 也输出 777,但现代浏览器已经摒弃了这个方法
var oBtn = document.getElementById("btn");
oBtn.attachEvent("onclick", function () {
alert("666");
});
oBtn.attachEvent("onclick", function () {
alert("777");
});
</script>
</body>
</html>
方法三:addEventListen
注意点:
- 事件名称不需要添加 on
- 后添加的不会覆盖先添加的
- 只支持现代浏览器(其实完全足够了)
- 这是三个里唯一可自定义事件是冒泡行为还是捕获行为的方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>addEventListener</title>
</head>
<body>
<button id="btn">我是按钮</button>
<script>
// 既输出 666 也输出 777,现代浏览器通用这个方法
var oBtn = document.getElementById("btn");
oBtn.addEventListener("click", function () {
alert("666");
});
oBtn.addEventListener("click", function () {
alert("777");
});
</script>
</body>
</html>
强行兼容
看似考虑周全,实则没有必要
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>加个判断</title>
</head>
<body>
<button id="btn">我是按钮</button>
<script>
var oBtn = document.getElementById("btn");
function addEvent(ele, name, fn) {
if(ele.attachEvent){
ele.attachEvent("on"+name, fn);
}else{
ele.addEventListener(name, fn);
}
}
</script>
</body>
</html>
事件对象
- 事件对象就是一个系统自动创建的一个对象
- 当注册的事件被触发的时候, 系统就会自动创建事件对象
- 事件对象的属性海了去了
注意点:
- 在高级版本的浏览器中, 会自动将事件对象传递给回到函数
- 在低级版本的浏览器中, 不会自动将事件对象传递给回调函数, 需要通过 window.event 来获取事件对象
关于阻止默认行为:
- event.preventDefault(); 只支持现代浏览器
- event.returnValue = false; 只支持上古浏览器(了解即可, 这年头谁还用 IE8 啊)
- return false; 通吃
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>事件对象</title>
</head>
<body>
<button id="btn">我是按钮</button>
<a href="http://www.baidu.com">百度首页</a>
<script>
var oBtn = document.getElementById("btn");
oBtn.onclick = function (event) {
// 兼容性的写法
event = event || window.event;
// alert("666");
console.log(event);
console.log(typeof event);
}
let oA = document.querySelector("a");
oA.onclick = function (event) {
// 兼容性的写法
event = event || window.event;
alert("666");
// 阻止默认行为
return false; // 企业开发推荐
// event.preventDefault(); // 高级浏览器
// event.returnValue = false; // IE9以下浏览器
}
</script>
</body>
</html>
事件执行的三个阶段
三个阶段
- 捕获阶段(从外向内的传递事件)
- 当前目标阶段
- 冒泡的阶段(从内向外的传递事件)
注意点:
- 三个阶段只有两个会被同时执行
- 要么捕获和当前, 要么当前和冒泡
冒泡还是捕获
如何设置事件到底是捕获还是冒泡?
通过addEventListener方法, 这个方法接收三个参数
- 第一个参数: 事件的名称
- 第二个参数: 回调函数
- 第三个参数: ==false 冒泡== / ==true 捕获==
注意点:
- onXxx的属性, 不接收任何参数, 所以默认就是冒泡
- attachEvent方法, 只能接收两个参数, 所以默认就是冒泡
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>41-JavaScript-事件执行的三个阶段</title>
<style>
*{
margin: 0;
padding: 0;
}
.father{
width: 300px;
height: 300px;
background: red;
}
.son{
width: 150px;
height: 150px;
background: blue;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
let oFDiv = document.querySelector(".father");
let oSDiv = document.querySelector(".son");
oFDiv.addEventListener("click", function () {
console.log("father");
}, false);
oSDiv.addEventListener("click", function () {
console.log("son");
}, false);
</script>
</body>
</html>
<!--
默认就是 false,也就是冒泡
设置为 true 的元素及其子元素链条都变为捕获,且仅影响自身及其子代,不影响其父元素
-->
关于冒泡的细节
IE6.0: div -> body -> html -> document
其他浏览器: div -> body -> html -> document -> window
注意: 不是所有的事件都能冒泡,有些事件不冒泡,如 blur、 focus、 load、 unload 等
阻止事件冒泡 (强行兼容)
首先要明确:阻止的前提是有事件,阻止事件冒泡的操作是写在实践方法的回调函数里的
- event.cancelBubble = true; (上古)
- event.stopProgagation(); (现代,知道这个才要紧)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>43-JavaScript-阻止事件冒泡</title>
<style>
*{
margin: 0;
padding: 0;
}
.father{
width: 300px;
height: 300px;
background: red;
}
.son{
width: 150px;
height: 150px;
background: blue;
}
</style>
</head>
<body>
<div class="father" id="father">
<div class="son" id="son"></div>
</div>
<script>
// 1.拿到需要操作的元素
var oFDiv = document.getElementById("father");
var oSDiv = document.getElementById("son");
// 2.注册事件监听
oFDiv.onclick = function () {
console.log("father");
}
oSDiv.onclick = function (event) {
event = event || window.event;
// event.stopPropagation(); // 高级浏览器
// event.cancelBubble = true; // 低级浏览器
if(event.cancelBubble){
event.cancelBubble = true;
}else{
event.stopPropagation();
}
console.log("son");
}
</script>
</body>
</html>
不同移入移出事件辨析
区别在于是否触发冒泡(或捕获)
- onmouseover 和 onmouseenter 的区别
- onmouseover 移入到子元素,父元素的移入事件也会被触发
- onmouseenter 移入到子元素,父元素的移入事件不会被触发
- onmouseout 和 onmouseleave 的区别
- onmouseout 移出到子元素,父元素的移入事件也会被触发
- onmouseleave 移出到子元素,父元素的移入事件不会被触发
- 简单来说, enter 和 leave 比较干净不拖泥带水
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>44-JavaScript-移入移出事件区别</title>
<style>
*{
margin: 0;
padding: 0;
}
.father{
width: 300px;
height: 300px;
background: red;
}
.son{
width: 150px;
height: 150px;
background: blue;
}
</style>
</head>
<body>
<div class="father">
<div class="son"></div>
</div>
<script>
let oFDiv = document.querySelector(".father");
let oSDiv = document.querySelector(".son");
/*
oFDiv.onmouseover = function () {
console.log("father");
}
oSDiv.onmouseover = function () {
console.log("son");
}
*/
/*
oFDiv.onmouseenter = function () {
console.log("father");
}
oSDiv.onmouseenter = function () {
console.log("son");
}
*/
oFDiv.onmouseleave = function () {
console.log("father");
}
oSDiv.onmouseleave = function () {
console.log("son");
}
</script>
</body>
</html>
通过事件获取元素位置
- offsetX/offsetY: 事件触发点相对于当前元素自身以左上为原点的位置
- clientX/clientY: 事件触发相对于浏览器可视区域的位置(上古浏览器不支持)
- 注意点:
- 显示器区域不包括滚动出去的部分(这个开发中用的少)
screenX/screenY: 事件触发相对于屏幕的位置- 整个网页包括滚动出去的部分 pageX/pageY: 事件触发相对于整个网页的位置(在页面不滚动时拿到的值和 clientX/clientY 是一样的)
细节们
-
调用事件方法时 return false 可以禁用默认事件, 或者用 event.preventDefault() 也行
-
如果想获取 query 到的 input 标签对象中输入的内容, 只能通过其 value 属性
html 可以给标签设置自定义标签属性, 可以给 JS 用,
甚至可以通过 JS 给指定 DOM 添加自定义属性标签
-
在 JS 中如果 HTML 标签的属性名称和取值名称一样的时候, JS 会返回 true/false 但如果是通过代码给 input 设置的数据, 那么不会触发 oninput 事件
-
对上古浏览器的兼容只需了解即可
移动端事件
移动端特有事件对象
- Touch事件对象
- 移动端的touch事件也是一个事件, 所以被触发的时候系统也会自动传递一个事件对象给我们
- 移动端touch事件对象中比较重要的三个子对象
- touches: 当前屏幕上所有手指的列表
- targetTouches: 保存了当前元素上所有的手指里列表 (这个用的多)
- changedTouches: 当前屏幕上刚刚接触的手指或者离开的手指
移动端点透问题
- 移动端点透问题
- 当一个元素放覆盖了另一个元素, 覆盖的元素监听 ==touch== 事件,而下面的元素监听 ==click== 事件
- 并且touch事件触发后覆盖的元素就消失了, 那么就会出现点透问题
- 移动端点透问题出现的原因
- 当手指触摸到屏幕的时候,系统生成两个事件,一个是touch 一个是click
- touch 事件先执行,执行完后从文档上消失
click 事件有 100~300ms 延迟, 所以后执行.(理由不对嗷, 我加了 content="scalable=no" 也还能点透)- 但 click 事件执行的时候触发的元素已经消失了, 对应的位置现在是下面的元素, 所以就触发了下面元素的 click 事件
- 移动端点透问题解决方案
在touch事件中添加
event.preverDefault()
; 阻止事件扩散
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>10-移动端点透问题</title>
<style>
* {
margin: 0;
padding: 0;
}
div {
text-align: center;
font-size: 40px;
}
.click {
width: 300px;
height: 300px;
background: red;
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 100px;
}
.tap {
width: 200px;
height: 200px;
background: blue;
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 150px;
}
</style>
</head>
<body>
<div class="click">click</div>
<div class="tap">tap</div>
<!-- 两元素在同级, 但展现时两个块块有重叠 -->
<script>
let oClick = document.querySelector(".click");
let oTap = document.querySelector(".tap");
oTap.ontouchstart = function (event) {
this.style.display = "none";
event.preventDefault(); // 阻止事件扩散
};
oClick.onclick = function () {
console.log("click");
};
</script>
</body>
</html>
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!