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)事件相关推荐

  1. Web前端JavaScript笔记(4)节点

    如何获取元素节点的属性: 在Web前端JavaScript笔记(3)对象中,介绍了访问行间属性的方法,除此之外,系统还提供了三个方法访问元素的属性: 1. setAttribute: 2. getAt ...

  2. Web前端Javascript笔记(6)正则表达式

    在web前端中,假设用户需要提交表单,在表单提交到服务器进一步处理之前,Javascript程序会检查表单,以确认用户输入的信息是符合规范要求的.这些工作可以使用正则表达式完成,正则表达式是一个描述字 ...

  3. Web前端JavaScript笔记(5)事件-拖拽

    阻止默认行为和超链接 在浏览器上运行网页后,右击会弹出菜单,这属于浏览器的默认行为.如何禁止这一默认行为: <script>window.onload = function () {doc ...

  4. Web前端Javascript笔记(8)Ajax前后端交互

    认识Ajax 全名Asynchronous Javascript and XML(异步JavaScript和XML),节省用户操作时间,提高用户体验,减少数据请求,传输获取数据.Ajax相当于前后台数 ...

  5. Web前端 Javascript笔记(1)数组

    结构 :html构建 样式:css控制 行为:JavaScript实现 什么是JavaScript? JavaScript是一种跨平台的脚本语言,平台,即运行环境,一般指操作系统. --------- ...

  6. Web前端JavaScript笔记(3)对象

    在JavaScript中没有类这个概念,只有对象,在新ECMA6新版中增加了类的概念,和数组,字符串类似,对象的声明方法也有三种: 1. 通过new运算符进行传件对象 2. 省略new运算符创建对象 ...

  7. Web前端JavaScript笔记(7)ECMA6新增数组方法

    新增数组方法: 1. Array.from():  将伪数组转化为真数组 <script>window.onload = function () {let tag_li = documen ...

  8. Web前端JavaScript笔记(2)字符串

    字符串: 字符串的声明方式: 1.  通过new运算符声明字符串         // 声明的是对象 2. 省略new运算符 3. 字符串常量赋值 <script>var str1 = n ...

  9. web前端学习笔记(最新)

    web前端学习笔记 大家好,我是链表哥,新的学期,新的学习,我会为您展示我的学习进程. 一:什么是WEB前端? 所谓的Web前端指的是用户所能接触到的,并服务于用户的前沿端口,经我们程序员编辑修饰后展 ...

最新文章

  1. 如何将浮点数很好地格式化为String而没有不必要的十进制0?
  2. 【STM32】通用定时器(TIM2到TIM5)
  3. Python入门编程中的变量、字符串以及数据类型
  4. free text search - enterprise search
  5. 时钟php,php+js液晶时钟
  6. mysql t 保存_检查 (调试) - 离线消息保存到 MySQL - 《EMQ X Enterprise v4.1 中文文档》 - 书栈网 · BookStack...
  7. php的数组操作,PHP的数组操作
  8. 腾讯看点基于 Flink 的实时数仓及多维实时数据分析实践
  9. datagrid 表格数据填充方式
  10. 机器学习基础(二)——训练集和测试集的划分
  11. 论文投递,核心期刊目录(2017版)
  12. Python数据分析 | (31) 透视表和交叉表
  13. 药品大湾区分中心牵手易臣,OA系统助力机构高效办公
  14. 【VR】Unity3d VR学习笔记——Unity烘焙
  15. 试验设计——序贯设计
  16. java程序员工作中遇到的问题解决记录
  17. Intel x86_64 CPUID指令介绍
  18. 【“互联网+”大赛华为云赛道】EI命题攻略:华为云EI的能力超丰富,助你实现AI梦想
  19. Ubuntu18.04+GTX3090 编译安装pytorch-nightly环境
  20. 2022-2028年中国酿造醋产业竞争现状及发展趋势分析报告

热门文章

  1. 人工智能TensorFlow工作笔记009---认识TensorFlow中的会话
  2. 2017年7月9 号小计
  3. mysql数据库BigInt数据类型和实体对象中BigInteger,Long类型的冲突
  4. 交?叉?验?证?(?分?类?器?性?能?)
  5. boost学习之BOOST_PP_SEQ_FOR_EACH_R
  6. sizeof(class)分析
  7. linux下的C语言开发(ATT 汇编语言)
  8. 用汇编的眼光看C++(之模板类)
  9. android 蓝牙连接obd,Android蓝牙连接汽车OBD设备
  10. docker php安装gd扩展_给docker里的php安装gd扩展