JavaScript入门系列目录

01、事件基础

1.1、事件简介

事件Event)是JavaScript的心脏,触发各种交互,让网页动起来。事件是浏览器网页可以监测到的行为,如页面加载、鼠标点击、键盘按键等。在这些事件中可以自定义事件处理程序,用于实现各种业务需求。

事件对象的继承关系:

常见的事件类型、事件如下:

鼠标事件(event)
click(event) 点击触发,通常是鼠标左键在一个元素上被按下并放开时
dblclick 双击触发事件
contextmenu 鼠标右键点击触发
mousedownmouseup 鼠标按下、弹起时触发
mousemove 鼠标在元素上移动时触发
onmouseovermouseout 鼠标移入、移出元素区域时触发
mouseenter、mouseleave 鼠标移入、移出元素区域时触发,与上面不同的是不会冒泡
dragstart、dragend 拖放事件(drag/dræɡ/拖)
键盘事件(event)
keydown、keyup 键盘按键按下、松开时触发
表单事件(event)
blur(event)、focusout() 元素失去焦点,blur不会冒泡 (blue /blɜːr/ 模糊 /不乐/)
focus、focusin 元素获取焦点时触发,focus不会冒泡
from.submit 提交表单form时触发,可用于表单校验
change 值发生变化时触发,文本框是在值变化且失去焦点是才触发
input 输入值改变时触发,event.preventDefault()无法阻止,因为已经改变了
Document 事件(event) 文档生命周期:DOMContentLoaded ️ load ️ beforeunload ️ unload
doc.DOMContentLoaded 已加载 HTML并构建好DOM树,外部资源(image、css)可能尚未加载完成
- 如果遇到<script>标签,会执行(包括外部的资源)然后才继续后面的DOM加载,要注意!async、defer标记的除外(只支持外部js资源)
window.load 文档完全加载完成,包括图片、样式都准备好了。可用于window、element
window.beforeunload 当用户正在离开页面时,不可取消,好像也不能干什么。
window.unload 用户几乎已经离开了,同上
doc.readystatechange 文档状态变化时触发,可跟踪文档加载状态readyState
onerror 加载出现错误,用于元素
scroll 滑动条滚动事件,具有滚动的视图元素。用于window、element
ClipboardEvent事件 事件参数对象clipboardData由于安全限制,方法无法使用
cut,copy,paste 剪切、拷贝、粘贴时触发
 e.clipboardData 保存了一个DataTransfer对象,用于存放数据,该对象也用于拖放
CSS事件(event)
transitionend 一个元素 CSS 动画完成时ele.addEventListener("transitionend", func)

1.2、事件的绑定

① HTML事件:HTML中绑定(调用)事件处理程序,<button onclick="func(event);func2()">button</button>注意加括号()

② JS绑定事件(DOM-0级事件)button.onclick = function() {},和HTML绑定一样,只能绑定一个事件处理程序。不能用setAttribute设置事件,因为设置的是字符串值。

③ 注册事件DOM-2级事件):

  • ele.addEventListener(event,func[, options]) :注册事件,推荐的常用方式,可添加多个事件处理程序,但同一个事件类型不可添加同一个handler对象。参数options为配置信息,如是否冒泡。
  • ele.removeEventListener(event,func[, options]) :必须是与添加时相同(恒等)的参数,不可移除匿名函数事件。

④ 事件处理对象handleEvent

除了注册事件方法,还可用将一个包含handleEvent方法的对象注册到事件处理程序,触发事件时调用对象的handleEvent方法。so,只要对象中包含handleEvent方法即可,任何对象、类的实例都可以。

<div id="ediv">
<span id="espan" onclick="console.log('html bind')">span</span>
<button id="btn" onclick="console.log('html bind')">button</button>
</div>
<script>
function func1(event) {
console.log(event.currentTarget, event.target); //div span
console.log("event.cancleable:" + event.cancelable) //event.cancleable:true
console.log(event.clientX, event.clientY); //31 363
//取消冒泡
event.cancelBubble = true;
event.stopPropagation();
event.stopImmediatePropagation(); //取消冒泡,以及元素同类型的其他事件
//取消默认事件,如checkbox,a元素的默认行为
event.preventDefault();//对自定义事件没用,
}
ediv.addEventListener('click', func1);
ediv.addEventListener('click', e=>console.log(e.currentTarget.localName)); //div,前面取消了则不会执行
ediv.addEventListener('click', ()=>console.log('click me')); //事件处理对象,调用对象的handelEvent方法执行事件
let eventObj = {
handleEvent(event) {
console.log("handleEvent", this.objName, event);
},
objName: "eventObj",
}
btn.addEventListener("click", eventObj);
</script>

1.3、事件对象event

每一个事件处理程序都有一个event对象,内置了事件的详细信息。最基础的Event如下,还有很多继承事件对象。

Event属性
type 事件的类型
target 指向事件触发的目标元素,可能为子元素,冒泡中不会改变。originalTarget为非标准(Mozilla)
currentTarget = this 指向事件绑定的元素,当前正在处理事假的元素,同 this
isTrusted 触发方式,true=用户,false=脚本触发,(Trusted/ˈtrʌstɪd/ 可信的)
bubbles 判断事件是否冒泡,bool。( Bubble/ˈbʌb(ə)l/ 冒泡)
cancelBubble 是否取消冒泡,可设置true阻止冒泡,stopPropagation()的别名
composed 表示事件是否可以穿过 Shadow DOM 和常规 DOM 之间的隔阂进行冒泡,bool
event.clientX / clientY 鼠标事件触发的x、y坐标
Event 方法
stopPropagation() 停止向上冒泡(propagation /ˌprɒpəˈɡeɪʃn/ 传播),不影响当前元素的其他注册事件
stopImmediatePropagation() 取消后面的同类型事件的执行,包括冒泡,(Immediate /ɪˈmiːdiət/ 立刻)
preventDefault() 取消默认事件行为,如checkbox、<a>,不影响冒泡。defaultPrevented 判断是否取消了

使用event.preventDefault() 可以移除浏览器的默认事件行为,也可以用return false

<p>
<input type="checkbox" onclick="return false">
<!--取消默认事件行为:点击无效了-->
<a href="http://www.qq.com" id="qq1" onclick="return false">QQ-1</a>
<a href="http://www.qq.com" id="qq2">QQ-2</a>
<a href="http://www.qq.com" id="qq3">QQ-3</a>
</p>
<script>
//return false 对a标签好像没有作用
qq1.addEventListener("click", () => false);
qq2.addEventListener("click", (event) => event.preventDefault()); //取消默认事件行为
qq3.addEventListener("click", (event) => {
if (!confirm("你确定已满18周岁,要前往[ " + event.target.getAttribute("href") + " ] 吗?")) {
event.preventDefault(); //取消默认事件行为 prevent /prɪˈvent/ 阻止
}
});
</script>

1.4、事件流:冒泡和捕获

事件的触发大都是某一个HTML元素,但这一个元素触发事件时,该事件会在该元素与根节点之间进行顺序传播,路过的元素都会接收到该事件,这个过程称为“事件流”,简单来说就是接收事件的顺序,如下三个阶段。

① 捕获阶段(Capturing phase):(phase /feɪz/ 阶段)

事件(从 Window)逐级向下传播,直到具体的目标元素。捕获阶段实际上很少使用,默认情况下也不会触发,addEventListener 注册事件时通过参数对象options.capture = true设置在捕获阶段触发事件。ediv.addEventListener("click", fevent2, true /* { capture: true } */);

② 目标阶段(Target phase):事件到达目标元素。

目标元素 event.target:直接触发事件的、最近的那个元素,也是嵌套最深的那个元素。

③ 冒泡阶段(Bubbling phase):一般常用的是冒泡阶段,这更符合逻辑。

事件从目标元素上开始冒泡,逐级向上春波,直到根节点。几乎所有事件都会冒泡,除了个别的,如blurfocus没有冒泡。

<div id="ediv">
<button id="ebutton">button</button>
</div>
<script>
const eles = document.querySelectorAll("#ediv,#ebutton");
for (let ele of eles) {
ele.addEventListener("click", e => console.log("capturing:" + e.currentTarget.localName), true); //捕获
ele.addEventListener("click", e => console.log("bubbling:" + e.currentTarget.tagName)); //冒泡
}
/*
capturing:div
capturing:button
bubbling:BUTTON
bubbling:DIV */
</script>

事件流的两种传播方式其实是IE和Netscape两个公司的不同处理机制导致的。

停止冒泡stopPropagation()stopImmediatePropagation()

  • 注意的区别stopPropagation()只是停止向上冒泡;stopImmediatePropagation()会额外取消当前元素同类型的后续事件。
  • 非必要不主动关闭冒泡,谨慎使用,可能会影响其他功能。

1.5、事件委托

事件委托只是事件的一种使用方式而已,基于事件冒泡在,上级节点统一处理从而简化事件的绑定。比如有一堆导航按钮,不需要每个都添加事件,把点击事件委托给其父级元素统一处理。

  • 优点:简化代码逻辑,便于修改维护。
  • 缺点:事件必须冒泡,如果被阻止了,就嗝屁了;可以忽略的冒泡性能损失。

表格排序示例(委托给表格统一处理):codePen地址

//需求:点击表格标题,对数据进行排序
const table = document.querySelector("#grid");
table.onclick = function (e) {
//点击标题单元格,并且有自定义排序属性
if (e.target.tagName != "TH" || !e.target.hasAttribute("data-sort")) return;
let th = e.target;
sortTable(th.cellIndex, th.dataset.sort);
};
function sortTable(colIndex, type) {
let trs = Array.from(document.querySelectorAll("#grid tbody tr"));
let tbody = table.tBodies[0];
let sortFunc = function (r1, r2) {
switch (type) {
case "number":
return r1.cells[colIndex].innerText - r2.cells[colIndex].innerText;
break;
case "number":
default:
return r1.cells[colIndex].innerText > r2.cells[colIndex].innerText? 1: -1;
break;
}
};
trs = trs.sort(sortFunc);
tbody.append(...trs); //追加已存在的元素,自动进行移动
}

全局提示示例:点击查看【codepen】

1.6、自定义事件

① 创建事件对象let event = new Event(type[, options]) ,使用Event构造函数,或者CustomEvent自定义事件(参数中有一个detail字段可存放自定义数据,在事件处理程序中通过event.detail使用),或其他事件对象MouseEvent、KeyboardEvent。

  • type:事件类型,可以是像 "click" 这样的字符串或任意。
  • options:具有两个可选属性的对象,是否冒泡bubbles(true=冒泡、false),是否取消默认行为ancelable: (true=阻止、false),默认值都是false。

②触发事件elem.dispatchEvent(event)

在你需要的地方调用elem.dispatchEvent(event)触发自定义事件,事件的处理程序和普通事件一样通过addEventListener添加,不支持on***

<p>
<input type="text" id="input">
</p>
<script>
//1、定义事件:当按下F4按钮时触发
let keyF4Click = new CustomEvent("keyF4Click", { detail: { key: "F4" } })
input.addEventListener("keyup", (event => {
if (event.key == "F4")
//2、触发事件
input.dispatchEvent(keyF4Click);
}))
//只能通过addEventListener添加自定义的事件处理程序
input.addEventListener("keyF4Click", (e) => {
input.value += e.detail.key;
})
</script>

02、UI事件

2.2、鼠标事件MouseEvent

鼠标事件(event)
click(event) 点击触发,通常是鼠标左键在一个元素上被按下并放开时
dblclick 双击触发事件
contextmenu 鼠标右键点击触发
mousedownmouseup 鼠标按下、弹起时触发
mousemove 鼠标在元素上移动时触发
onmouseovermouseout 鼠标移入、移出元素区域时触发
mouseenter、mouseleave 鼠标移入、移出元素区域时触发,与上面不同的是不会冒泡
dragstart、dragend 拖放事件(drag/dræɡ/拖)

鼠标事件响应顺序mouseenter mousemove mousedown mouseup click mouseleave

<button id="btn" >button</button>
<script>
btn.addEventListener("mouseenter", (e)=>console.log(1,e.type)); //1 'mouseenter'
btn.addEventListener("mousemove", (e)=>console.log(2,e.type)); //2 'mousemove'
btn.addEventListener("mousedown", (e)=>console.log(3,e.type)); //3 'mousedown'
btn.addEventListener("mouseup", (e)=>console.log(4,e.type)); //4 'mouseup'
btn.addEventListener("click", (e)=>console.log(5,e.type)); //5 'click'
btn.addEventListener("mouseleave", (e)=>console.log(6,e.type)); //6 'mouseleave'
</script>
MouseEvent属性
button 鼠标按下的按钮:0=主按键/左键,1=滚轮中按键,2=次按键/右键
clientX / clientY 鼠标指针在窗口的 X 坐标、Y 坐标
pageX/pageY 鼠标指针在文档的 X 坐标、Y 坐标
ctrlKey、altKey、shiftKey 是否按下了CtrlAltShift按键,bool值
metaKey Mac中的 Cmd,同window的Ctrl
relatedTarget 次要(关联)目标,鼠标移入/出中使用,表示上一个target

鼠标点击位置动画示例:codepen

<style>
.mpoint {
position: absolute;
padding: 0; margin: 0;
width: 200px; height: 200px;
background-color: #dda427;
border-radius: 50%;
animation: click 1s;
}
@keyframes click {
0% { transform: scale(0, 0); opacity: 0; }
30% { transform: scale(1, 1); opacity: 1; }
100% { transform: scale(0, 0); background-color: #7c20e4; opacity: 0; }
}
</style>
<script>
let cdiv = document.createElement('div');
//动画执行完后移除自身
cdiv.addEventListener('animationend', () => cdiv.remove());
window.addEventListener('click', (e) => {
document.body.append(cdiv);
cdiv.className = 'mpoint';
//定位圆圈的位置,为鼠标点坐标
cdiv.style.left = (e.clientX - cdiv.clientWidth / 2) + 'px';
cdiv.style.top = (e.clientY - cdiv.clientHeight / 2) + 'px';
});
</script>

点击查看【codepen】

2.3、键盘事件KeyboardEvent

键盘事件(event)
keydown、keyup 键盘按键按下、松开时触发
过时的keypress
KeyboardEvent属性
code 按键编码(KeyA、KeyA、F1、0、Shift),物理按键的准确编码,比较稳定
key 按键值(A、a、F1、Digit0、ShiftLeft),正常看到的值,可能会随系统语言、输入环境变化
repeat 按键是否被一直按住,bool。按住时会一直触发keydown
ctrlKey、altKey、shiftKey 是否按下了CtrlAltShift按键,bool值
metaKey Mac中的 Cmd,同window的Ctrl

03、表单事件

3.1、表单查找/取值

获取表单<form><form name="formName"> 除了元素查找还有如下方式

  • 属性访问document.formName
  • forms属性document.forms为文档中所有表单集合。
<form name="loginForm"><input type="text"></form>
<script>
document.loginForm;
document.forms.loginForm;
document.forms['loginForm'];
document.forms[0];
</script>

获取表单元素

  • form.name
  • form.elements集合,不用管元素的层级
    • form.elements.name,单个元素
    • form.elements['name'],元素名为name的集合,组合元素使用。
  • 子表单fieldset.elements

表单和表单元素的双向引用:

表单元素取值input.value<input>表单元素大部分都是value取值/赋值,注意下面的:

  • input.checked,单选radio、多选checkbox通过checked取值/赋值,多个需要遍历取值。
  • textarea.value,️注意多行文本<textarea>是通过value取值,而不是innerHTML
  • 下拉框select:select.options =<option> 的子元素的集合
    • 单选select.valueselect.selectedIndex
    • 多选:遍历options取值,Array.from(select.options).filter(op=>op.select).map(op=>op.value);

提交表单

  • document.loginForm.submit():表单的submit()方法提交,完全自主控制,推荐食用。
  • submit按钮+事件onclick=return 校验函数():校验函数校验表单数据,返回true提交表单,否则不提交

<button type="submit" onclick="return canSubmit()">

  • submit按钮+form的事件onsubmit=return 校验函数():功能和用法基本同上。
<form name="fuser" id="fuser" action="" method="post">
姓名:<input name="userName" type="text" title="请输入用户名" /><br />
密码:<input name="userPwd" type="password" title="请输入密码" /><br />
生日:<input name="userBirthday" type="date" value="2021-10-11" /><br />
性别:<input name="sex" id="usex1" type="radio" value="男" checked=true /><label for="usex1">男</label>
<input name="sex" id="usex2" type="radio" value="女" /><label for="usex2">女</label>
<input name="sex" id="usex3" type="radio" value="其他" /><label for="usex3">其他</label><br />
爱好:<input id="uint1" name="interest" type="checkbox" value="运动" /><label for="uint1">运动</label>
<input id="uint2" name="interest" type="checkbox" value="学习" /><label for="uint2">学习</label>
<input id="uint3" name="interest" type="checkbox" value="看书" /><label for="uint3">看书</label>
<input id="uint4" name="interest" type="checkbox" value="躺着" /><label for="uint4">躺着</label><br />
学历:<select id="education" name="education">
<option value="大专">大专</option>
<option value="本科">本科</option>
<option value="研究生">研究生</option>
</select><br />
<button type="button" onclick="getData()">获取数据</button>
</form>

<script>
var form = document.fuser;
function getData() {
var form = document.fuser;
var userData = {};
userData.userName = form.userName.value;
userData.userPwd = form.userPwd.value;
userData.userBirthday = form.userBirthday.value;
//单选、多选,注意设置name、value值,遍历取值
userData.sex = Array.from(document.getElementsByName('sex'))
.filter(n => n.checked)[0]?.value
userData.interest = Array.from(document.getElementsByName('interest'))
.filter(n => n.checked).map(n=>n.value).join();
//下拉框取值
userData.education = form.education.value;
userData.education = form.education.options[form.education.selectedIndex].value;
console.log(JSON.stringify(userData));
};
getData();
</script>

3.2、表单事件

表单事件(event)
blur(event)、focusout() 元素失去焦点,blur不会冒泡 (blue /blɜːr/ 模糊 /不乐/)
focus、focusin 元素获取焦点时触发,focus不会冒泡
from.submit 提交表单form时触发,可用于表单校验
change 值发生变化时触发,文本框是在值变化且失去焦点是才触发
input 输入值改变时触发。event.preventDefault()无法阻止,因为已经改变了
方法-聚焦
elem.focus() 设置元素获得焦点
elem.blur() 设置元素失去焦点

可编辑单元格的表格示例:codepen


️版权申明:版权所有@安木夕,本文内容仅供学习,欢迎指正、交流,转载请注明出处!原文编辑地址-语雀

JavaScript入门⑧-事件总结大全的更多相关文章

  1. JavaScript onkeydown事件入门实例(键盘某个按键被按下)

    JavaScript onkeydown 事件 用户按下一个键盘按键时会触发 onkeydown 事件.与 onkeypress事件不同的是,onkeydown 事件是响应任意键按下的处理(包括功能键 ...

  2. JavaScript入门篇 编程练习

    编程挑战 一.定义"改变颜色"的函数 提示: obj.style.color obj.style.backgroundColor 二.定义"改变宽高"的函数 提 ...

  3. 慕课网JavaScript入门篇课程笔记

    1.js注释很重要 单行注释,在注释内容前加符号 “//”. <script type="text/javascript"> document.write(" ...

  4. JavaScript入门基础

    JavaScript基本语法 1.运算符 运算符就是完成操作的一系列符号,它有七类: 赋值运算符(=,+=,-=,*=,/=,%=,<<=,>>=,|=,&=).算术运 ...

  5. Google Map JavaScript API V3 实例大全

    Google Map JavaScript API V3 实例大全 基础知识 简单的例子 地理位置 语言 位置 坐标 简单的投影 事件 简单事件 关闭事件 多次添加事件 事件属性 控制 php禁用ui ...

  6. javascript入门视频第一天 小案例制作 零基础开始学习javascript

    JavaScript 是我们网页设计师必备的技能之一.我们主要用javascript来写的是网页特效.我们从零基础开始学习javascript入门. 但是,好的同学刚开始不知道怎么学习,接触js,因此 ...

  7. JavaScript入门篇

    记录一下在慕课网学习JavaScript的过程. 以下内容均来自慕课网. 传送:https://www.imooc.com/code/401 为什么学习JavaScript 1. 所有主流浏览器都支持 ...

  8. JavaScript入门--慕课网学习笔记

     JAVASCRIPT—(慕课网)入门篇 我们来看看如何写入JS代码?你只需一步操作,使用<script>标签在HTML网页中插入JavaScript代码.注意, <script&g ...

  9. JavaScript入门几个概念

    JavaScript入门几个概念 刚刚入门JavaScript的时候,搞懂DOM.BOM以及它们的对象document和window很有必要. DOM是为了操作文档出现的API,document是它的 ...

  10. javascript入门笔记3-dom

    1.通过ID获取元素 document.getElementById("id") <!DOCTYPE HTML> <html> <head> & ...

随机推荐

  1. Portainer安装,配置自定义镜像仓库拉取镜像

    Portainer介绍 Portainer是Docker的图形化管理工具,提供状态显示面板.应用模板快速部署.容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作).事件日志显示.容器控制台 ...

  2. echarts 饼图中间添加图片

    饼图添加图片只需要配置两部分 option = { graphic: { // 这个属性可以在饼图内部填充图片,文字等 elements: [{ type: 'image',//需要填充图片,配置im ...

  3. PHP实践项目【1】:注册登录页面

    在我们这个项目里面,一共用到了5个php文件,他们分别是: login.php 登录页面 logincheck.php 登录检测php文件 register.php 新用户注册页面 regcheck. ...

  4. 二叉树及其三种遍历方式的实现(基于Java)

    二叉树概念: 二叉树是每个节点的度均不超过2的有序树,因此二叉树中每个节点的孩子只能是0,1或者2个,并且每个孩子都有左右之分. 位于左边的孩子称为左孩子,位于右边的孩子成为右孩子:以左孩子为根节点的 ...

  5. 记一次 .NET 某工控视觉软件 非托管泄漏分析

    一:背景 1.讲故事 最近分享了好几篇关于 非托管内存泄漏 的文章,有时候就是这么神奇,来求助的都是这类型的dump,一饮一啄,莫非前定.让我被迫加深对 NT堆, 页堆 的理解,这一篇就给大家再带来一 ...

  6. DevOps|高效能敏捷交付组织:特性团队(FeatureTeam)+Scrum

    这是<研发效能组织能力建设>的第三篇.特性团队和Scrum,这两个定义我们在之前的文章中都详细介绍了.这两个组织模式或者说管理实践,我都用过所以有些时候特别有感触.书本上纯粹的模式很容易理 ...

  7. 2022年最新最详细IDEA关联数据库方式、在IDEA中进行数据库的可视化操作(包含图解过程)

    文章目录 1.使用IDEA关联Mysql数据库的详细操作步骤 1.1 打开侧边栏的Database 2.2. 选择要连接的数据库(Mysql) 2.3 .输入要连接的数据库.用户名.密码 2.4 .点 ...

  8. python如何引入外部其他py文件

    新手常常会遇到这种问题 解决方法如下: 比如我在C:\Users\123\Desktop有一个mmm.py文件,内容为: def abc(): print('hello,world') 当我写程序想引 ...

  9. LcdToos如何在线调屏PORCH参数

    在点屏过程中,我们会经常碰到画面对不齐现象,在这种情况下需要多次尝试修调屏的PORCH参数来使画面显示正常:通常的做法是修改完PORCH参数下载到PG,点亮看效果,这种方法无疑效率很低,对于现象的表现 ...

  10. C# String.IsNullOrEmpty()方法的使用

    IsNullOrEmpty(string)是String类的一个有参的方法,方法需要类的调用,所以String.IsNullOrEmpty(string) IsNullOrEmpty是判断字符串的Nu ...