Web前端Javascript笔记(5)事件
1. 什么是事件:事件是指发生并得到处理的操作
JavaScript中的事件是由访问web页面的用户引起的一系列操作,例如,用户的点击操作,JavaScript中有两种事件模型:内联模型,脚本模型。
内联模型:是一种传统简单的事件处理方法,在内联模型中,事件处理函数是HTML标签的一个属性,用于处理指定事件。特点:是和html代码混写在一起的。
脚本模型:将事件绑定与HTML代码分离开来:
事件的绑定方式:内联模式,脚本模式
在开发中,推荐使用外联(脚本)模式,这样可以将HTML于CSS完全分离
事件类型:
1. 鼠标事件
click: 单击
dblclick:双击
mouseover:鼠标移入,在经过元素子节点的时候也会触发
mouseout:鼠标移出
mousemove: 鼠标移动 (不停的触发)
mousedown:鼠标按下
mouseup:鼠标抬起
mouseenter: 鼠标移入 ,在经过元素子节点的时候不会触发
mouseleave: 鼠标移除
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function(){let btn = $("btn1");btn.ondblclick = function () {alert("double click");};btn.onmouseover = function () {this.style.background = "#996e27";};btn.onmouseout = function () {this.style.background = "white";};let cnt = 0;let box = $("box");box.onmousemove = function () {this.innerHTML = cnt++;}}</script><style>#box{width: 200px;height: 200px;background: red;}</style>
</head>
<body><button id="btn1">按钮</button><div id="box">0</div>
</body>
</html>
效果如下所示:
2.键盘事件(一般绑定在表单元素或者window)
keydown:键盘按下,如果不松开的话,会一直触发事件
keyup:键盘抬起
keypress:键盘按下,只支持字符键
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function(){let i = 0;window.onkeydown = function () {document.title = (i++).toString();};window.onkeyup = function () {document.title = "抬起"};window.onkeypress = function (key) {// 传入的参数:可以得到具体的按键值alert(key.code);}}</script>
</head>
<body></body>
</html>
3.HTML事件
a. window事件
load:当页面加载完毕后会触发的事件
unload:当页面解构的时候会触发的事件,例如刷新页面,或者关闭页面 ,只支持IE浏览器
scroll:页面滚动的时候触发事件
resize:窗口大小发生变化的时候触发的事件
b. 表单事件
blur : 失去焦点
focus :获得焦点
select:当在输入框内选中文本的时候会触发的事件
change: 当对输入框的文本进行修改且失去焦点的时候会触发事件
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function(){let input_tag = $("username");input_tag.onblur = function(){alert("失去焦点");};input_tag.onfocus = function () {alert("获得焦点");};input_tag.onchange = function () {alert("内容修改");};input_tag.onselect = function () {alert("内容选中");};}</script>
</head>
<body><input id="username" type="text" placeholder="请输入用户名">
</body>
</html>
【注】下面两个自能添加到form元素上
submit: 当点击submit上的按钮时才能出发
reset: 当点击reset上的按钮时才能出发
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function(){let form = $("userInfo");let input_box = form.firstElementChild;form.onsubmit = function () {if(!input_box.value){alert("用户名不能为空");}else{alert("注册成功");}};form.onreset = function () {input_box.value = "";alert("重置")};}</script>
</head>
<body><form id="userInfo"><input type="text" placeholder="请输入"><input type="submit"><input type="reset"></form>
</body>
</html>
事件对象:
在上述的事件绑定的过程中,当元素与标签之间的事件绑定一旦完成的时候,系统会自动生成一个事件对象,当事件触发的时候,系统会去调用相应的事件函数,此时,系统会将事件对象当作第一个参数传入。
例如:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>function show(){alert(arguments.length);alert(arguments[0]);}window.onload = function(){let button_tag = $("btn");button_tag.onclick = show;};</script>
</head>
<body><button id="btn">按钮</button>
</body>
</html>
例如,在触发按钮事件之后,系统会调事件函数show()(show函数只能由系统调用),可以在show()函数中输出函数参数,可以看到,系统给show()函数传入了一个参数:
可以看到传入的是一个MouseEvent事件对象。
可以在函数申明中定义一个形参,用来接收系统传入的参数,但是此方法只有在IE8以上的浏览器中才兼容,还有一种方法,可以在定义的函数中通过window.event拿到系统传入的参数,所以可以写一个兼容不同版本浏览器的函数:
<script>function show(ev){let e = ev || window.event;alert(e);}window.onload = function(){let button_tag = $("btn");button_tag.onclick = show;};
</script>
事件对象属性和方法:
a. 鼠标事件对象:
button: 表示按下的是鼠标的哪个键 0 1 2 = 【左,中,右】
获取当前鼠标位置:三种方法:(原点位置不一样)
clientX, clientY 原点位置为可视窗口的左上角,即使页面滚动了,参考原点依然是左上角的可视区域
pageX, pageY 原点位置为页面的左上角,页面滚动,相应的y坐标也会增加
screenX, screenY 原点位置为电脑屏幕的左上角,即使浏览器出了电脑屏幕,坐标的参考原点依然为屏幕左上角
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {document.onmousedown = function (ev) {// 鼠标按下的事件let e = ev || window.event; // 获取事件对象alert(e.button); // 获取鼠标的按键alert(e.clientX + "," + e.clientY);alert(e.pageX + "," + e.pageY);alert(e.screenX + "," +e.screenY);};}</script>
</head>
<body></body>
</html>
案例:
可以跟随鼠标移动的提示框
所以需要实现的是:
1. 鼠标移入,展现出提示框
2. 鼠标移动,提示框随着鼠标移动
3. 鼠标移出,提示框消失
步骤:
1. 先给a标签添加鼠标移入和移除事件,再添加鼠标移入事件。
2. 在获取到鼠标的当前坐标之后,需要给坐标添加一定量的偏置,在把偏置后的坐标作为div的位置,因为div的层级高于a标签,所以如果不偏置,鼠标在div上时,就相当于移出了a标签,这样就会反复触发mouseover和mouseout事件。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let tag_a = document.getElementsByTagName("a"); // 所有的a标签let content_box = $("msg");let content_arr = ["Go for html", "go for python", "go for C++"];for (let i=0; i<tag_a.length; i++){tag_a[i].index = i;tag_a[i].onmouseover = function () {content_box.style.display = "block";content_box.innerHTML = content_arr[i];};tag_a[i].onmouseout = function () {content_box.style.display = "none";};tag_a[i].onmousemove = function (position) {let pos = position || window.event; // 获取事件对象let cord_x = pos.clientX + 5; // 添加5像素的偏置量let cord_y = pos.clientY + 5;content_box.style.left = cord_x + "px";content_box.style.top = cord_y + "px";};}}</script><style>a{font-size: 25px;color: blue;display: block;border: none;/*width: 200px;*//*height: 100px;*/margin-left: 30px;margin-top: 100px;width: 50px;}#msg{width: 200px;height: 80px;border: 1px solid black;display: none;background: gray;position: absolute;}</style>
</head>
<body><a href="#">Html</a><a href="#">python</a><a href="#">c++</a><div id="msg"></div>
</body>
</html>
事件对象属性:
shiftkey : 按下shift键时为true, 否则为false
altkey:按下alt键为true,否则为false
ctrlkey:
metakey:windows下为windows键
键盘事件中的属性:
keyCode也需要兼容
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {window.onkeydown = function (ev) {let e = ev || window.event;alert(e);// 获取键码,需要考虑不同浏览器的兼容问题let which = e.which || e.keyCode;alert(which);}}</script>
</head>
<body></body>
</html>
对前面的内容发布的程序进行修改,添加快捷键,在输入框中输入内容,按下ctrl+enter键,也可以发布内容:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let input_tag = $("input_text");let bottom_section = $("bottom");$("add").onclick = function (){let input_content = input_tag.value;if(!input_content){alert("请输入内容");}else{// 开始创建节点let node = document.createElement("div");let text_node = document.createTextNode(input_content);let btn_node = document.createElement("button");let btn_text_node = document.createTextNode("x");btn_node.appendChild(btn_text_node);node.appendChild(text_node);node.appendChild(btn_node);node.style.background = randomColor();bottom_section.appendChild(node);input_tag.value = ""; // 清空输入框updateItemsButtons();}};$("delete").onclick = function () {let last_node = bottom_section.lastChild;bottom_section.removeChild(last_node);updateItemsButtons();};$("clone").onclick = function () {let last_node = bottom_section.lastChild;let clone_node = last_node.cloneNode(true); // 深拷贝bottom_section.appendChild(clone_node);updateItemsButtons();};function updateItemsButtons() {// 对每条记录上的删除按钮绑定函数let child_nodes = bottom_section.children; // 只获取div元素节点let btn_arr = [];for(let i=0; i<child_nodes.length; i++){btn_arr.push(child_nodes[i].firstElementChild);//console.log(child_nodes[i].children);}// 对标签绑定事件函数for (let i=0; i<btn_arr.length; i++){// console.log(btn_arr[i]);btn_arr[i].index = i;btn_arr[i].onclick = function () {bottom_section.removeChild(child_nodes[this.index]);}}}input_tag.onkeydown = function (ev){// 给输入框添加快捷键let e = ev || window.event;let key_code = e.keyCode || e.which; // 判断回车键if(e.ctrlKey && key_code===13){$("add").onclick();}}}</script><style>#container{width: 200px;border: 1px solid black;}#top{width: 100%;height: 30px;}#top input{height: 20px;line-height: 30px;margin: 0 auto;}#middle{width: 100%;height: 50px;border: none;display: flex;flex-direction: row;justify-content: space-around;background: #0f6674;}#middle button{/*width: 25%;*/height: 50%;align-self: center;/*margin-top: 10px;*/}#bottom{}#bottom div{height: 25px;position: relative;}#bottom div button{position: absolute;top: 1px;right: 2px;}</style>
</head>
<body><div id="container"><div id="top"><input type="text" id="input_text" placeholder="请输入内容"></div><div id="middle"><button id="add">添加</button><button id="delete">删除</button><button id="clone">克隆</button></div><div id="bottom"><!--<div>content<button>x</button></div>--></div></div>
</body>
</html>
效果如下所示:
事件冒泡和触发对象:
事件属性target表示触发对象,只有IE8以上的浏览器兼容,需要和window.event.srcElement方法兼容使用
触发对象表示的是这个事件是由谁而触发引起的:,例如下面的div标签:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {$("cox").onclick = function (ev) {alert(this.innerHTML); // 输出1233// 获取触发对象let e = ev || window.event; // 获取事件对象let target = e.target || window.event.srcElement; // 事件对象的target属性表示触发对象alert(target.innerHTML);}}</script>
</head>
<body><div id="cox">1233</div>
</body>
</html>
上述的两种方法输出的都是1233,但是,实际上this 和 targe实质上是不同的。this指向的是当前的标签,而target指向的是触发事件的标签,这个标签有可能是当前的标签,也可能是当前标签的子标签,例如:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {$("cox").onclick = function (ev) {alert(this.tagName); // 输出1233// 获取触发对象let e = ev || window.event; // 获取事件对象let target = e.target || window.event.srcElement; // 事件对象的target属性表示触发对象alert(target.innerHTML);}}</script>
</head>
<body><ul id="cox"><li>11111</li><li>22222</li></ul>
</body>
</html>
例如,this.tagName输出的是UL标签,因为UL是事件函数的主人,但是这里的target表示的具体点击的<li>标签,代表的是触发时间函数的那个对象。
事件冒泡:
存在于嵌套的标签中,当嵌套的标签内外都绑定了时间函数的时候,内部的事件函数被触发执行完毕后,外部的标签又会被触发。这就是事件冒泡。
例如,对于下面的三个<div>标签:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let tags = document.getElementsByTagName("div");for (let i=0; i<tags.length; i++){tags[i].onclick = function () {alert(this.id);}}}</script><style>div{padding: 30px;}#div1{background: red;width: 200px;height: 200px;}#div2{background: green;width: 60%;height: 60%;margin: 0 auto;}#div3{background: blue;width: 60%;height: 60%;margin: 0 auto;}</style>
</head>
<body><div id="div1"><div id="div2"><div id="div3"></div></div></div>
</body>
</html>
当点击div2的时候,会触发div2事件函数,之后又会触发div1事件函数。当点击div3的时候,触发div3事件函数,之后又触发div2事件函数,接着又会触发div1事件函数。
事件冒泡又称为事件流:事件由里向外,逐层触发。很多时候,并不想让浏览器发生事件冒泡,阻止事件冒泡的方法有两种:
cancelBubble = True和 stopPropagation(),这些都是事件对象的属性和方法,所以首先需要拿到事件对象:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let tags = document.getElementsByTagName("div");for (let i=0; i<tags.length; i++){tags[i].onclick = function (ev) {let e = ev || window.event;//e.cancelBubble = true; // 阻止事件冒泡// e.stopPropagation();// 跨浏览器兼容:stopBubble(e);alert(this.id);}}// 跨浏览器兼容function stopBubble(e) {if(e.stopPropagation){e.stopPropagation();}else{e.cancelBubble = true;}}}</script><style>div{padding: 30px;}#div1{background: red;width: 200px;height: 200px;}#div2{background: green;width: 60%;height: 60%;margin: 0 auto;}#div3{background: blue;width: 60%;height: 60%;margin: 0 auto;}</style>
</head>
<body><div id="div1"><div id="div2"><div id="div3"></div></div></div>
</body>
</html>
案例练习:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script rel="script" src="../JavaScript/tool.js"></script><script>window.onload = function () {let divs = document.getElementsByTagName("div");document.onmousemove = function (ev){let e = ev || window.event;for (let i=divs.length-1; i>0; i--){divs[i].style.left = divs[i-1].offsetLeft + "px";divs[i].style.top = divs[i-1].offsetTop + "px";}divs[0].style.left = e.clientX + "px";divs[0].style.top = e.clientY + "px";};}</script><style>*{margin: 0;padding: 0;}div{position: absolute;width: 10px;height: 10px;background: black;border-radius: 50%;}</style>
</head>
<body><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div>
</body>
</html>
Web前端Javascript笔记(5)事件相关推荐
- Web前端JavaScript笔记(4)节点
如何获取元素节点的属性: 在Web前端JavaScript笔记(3)对象中,介绍了访问行间属性的方法,除此之外,系统还提供了三个方法访问元素的属性: 1. setAttribute: 2. getAt ...
- Web前端Javascript笔记(6)正则表达式
在web前端中,假设用户需要提交表单,在表单提交到服务器进一步处理之前,Javascript程序会检查表单,以确认用户输入的信息是符合规范要求的.这些工作可以使用正则表达式完成,正则表达式是一个描述字 ...
- Web前端JavaScript笔记(5)事件-拖拽
阻止默认行为和超链接 在浏览器上运行网页后,右击会弹出菜单,这属于浏览器的默认行为.如何禁止这一默认行为: <script>window.onload = function () {doc ...
- Web前端Javascript笔记(8)Ajax前后端交互
认识Ajax 全名Asynchronous Javascript and XML(异步JavaScript和XML),节省用户操作时间,提高用户体验,减少数据请求,传输获取数据.Ajax相当于前后台数 ...
- Web前端 Javascript笔记(1)数组
结构 :html构建 样式:css控制 行为:JavaScript实现 什么是JavaScript? JavaScript是一种跨平台的脚本语言,平台,即运行环境,一般指操作系统. --------- ...
- Web前端JavaScript笔记(3)对象
在JavaScript中没有类这个概念,只有对象,在新ECMA6新版中增加了类的概念,和数组,字符串类似,对象的声明方法也有三种: 1. 通过new运算符进行传件对象 2. 省略new运算符创建对象 ...
- Web前端JavaScript笔记(7)ECMA6新增数组方法
新增数组方法: 1. Array.from(): 将伪数组转化为真数组 <script>window.onload = function () {let tag_li = documen ...
- Web前端JavaScript笔记(2)字符串
字符串: 字符串的声明方式: 1. 通过new运算符声明字符串 // 声明的是对象 2. 省略new运算符 3. 字符串常量赋值 <script>var str1 = n ...
- web前端学习笔记(最新)
web前端学习笔记 大家好,我是链表哥,新的学期,新的学习,我会为您展示我的学习进程. 一:什么是WEB前端? 所谓的Web前端指的是用户所能接触到的,并服务于用户的前沿端口,经我们程序员编辑修饰后展 ...
最新文章
- 如何将浮点数很好地格式化为String而没有不必要的十进制0?
- 【STM32】通用定时器(TIM2到TIM5)
- Python入门编程中的变量、字符串以及数据类型
- free text search - enterprise search
- 时钟php,php+js液晶时钟
- mysql t 保存_检查 (调试) - 离线消息保存到 MySQL - 《EMQ X Enterprise v4.1 中文文档》 - 书栈网 · BookStack...
- php的数组操作,PHP的数组操作
- 腾讯看点基于 Flink 的实时数仓及多维实时数据分析实践
- datagrid 表格数据填充方式
- 机器学习基础(二)——训练集和测试集的划分
- 论文投递,核心期刊目录(2017版)
- Python数据分析 | (31) 透视表和交叉表
- 药品大湾区分中心牵手易臣,OA系统助力机构高效办公
- 【VR】Unity3d VR学习笔记——Unity烘焙
- 试验设计——序贯设计
- java程序员工作中遇到的问题解决记录
- Intel x86_64 CPUID指令介绍
- 【“互联网+”大赛华为云赛道】EI命题攻略:华为云EI的能力超丰富,助你实现AI梦想
- Ubuntu18.04+GTX3090 编译安装pytorch-nightly环境
- 2022-2028年中国酿造醋产业竞争现状及发展趋势分析报告
热门文章
- 人工智能TensorFlow工作笔记009---认识TensorFlow中的会话
- 2017年7月9 号小计
- mysql数据库BigInt数据类型和实体对象中BigInteger,Long类型的冲突
- 交?叉?验?证?(?分?类?器?性?能?)
- boost学习之BOOST_PP_SEQ_FOR_EACH_R
- sizeof(class)分析
- linux下的C语言开发(ATT 汇编语言)
- 用汇编的眼光看C++(之模板类)
- android 蓝牙连接obd,Android蓝牙连接汽车OBD设备
- docker php安装gd扩展_给docker里的php安装gd扩展