事件

简介: 事件

因为JavaScript在浏览器中以单线程模式运行,页面加载后,一旦页面上所有的JavaScript代码被执行完后,就只能依赖触发事件来执行JavaScript代码。


浏览器在接收到用户的鼠标或键盘输入后,会自动在对应的DOM节点上触发相应的事件。如果该节点已经绑定了对应的JavaScript处理函数,该函数就会自动调用。


由于不同的浏览器绑定事件的代码都不太一样,所以用jQuery来写代码,就屏蔽了不同浏览器的差异,我们总是编写相同的代码。


举个例子,假设要在用户点击了超链接时弹出提示框,我们用jQuery这样绑定一个click事件:


/* HTML:

*

* <a id="test-link" href="#0">点我试试</a>

*

*/


// 获取超链接的jQuery对象:

var a = $('#test-link');

a.on('click', function () {

   alert('Hello!');

});


实测: 点我试试


on方法用来绑定一个事件,我们需要传入事件名称和对应的处理函数。


另一种更简化的写法是直接调用click()方法:


a.click(function () {

   alert('Hello!');

});


两者完全等价。我们通常用后面的写法。


jQuery能够绑定的事件主要包括:


鼠标事件


click: 鼠标单击时触发;

dblclick:鼠标双击时触发;

mouseenter:鼠标进入时触发;

mouseleave:鼠标移出时触发;

mousemove:鼠标在DOM内部移动时触发;

hover:鼠标进入和退出时触发两个函数,相当于mouseenter加上mouseleave。


键盘事件


键盘事件仅作用在当前焦点的DOM上,通常是<input>和<textarea>。

keydown:键盘按下时触发;

keyup:键盘松开时触发;

keypress:按一次键后触发。


其他事件


focus:当DOM获得焦点时触发;

blur:当DOM失去焦点时触发;

change:当<input>、<select>或<textarea>的内容改变时触发;

submit:当<form>提交时触发;

ready:当页面被载入并且DOM树完成初始化后触发。


其中,ready仅作用于document对象。由于ready事件在DOM完成初始化后触发,且只触发一次,所以非常适合用来写其他的初始化代码。假设我们想给一个<form>表单绑定submit事件,下面的代码没有预期的效果:


<html>

<head>

   <script>

       // 代码有误:

       $('#testForm').on('submit', function () {

           alert('submit!');

       });

   </script>

</head>

<body>

   <form id="testForm">

       ...

   </form>

</body>


因为JavaScript在此执行的时候,<form>尚未载入浏览器,所以$('#testForm)返回[],并没有绑定事件到任何DOM上。

所以我们自己的初始化代码必须放到document对象的ready事件中,保证DOM已完成初始化:


<html>

<head>

   <script>

       $(document).on('ready', function () {

           $('#testForm).on('submit', function () {

               alert('submit!');

           });

       });

   </script>

</head>

<body>

   <form id="testForm">

       ...

   </form>

</body>


这样写就没有问题了。因为相关代码会在DOM树初始化后再执行。


由于ready事件使用非常普遍,所以可以这样简化:


$(document).ready(function () {

   // on('submit', function)也可以简化:

   $('#testForm).submit(function () {

       alert('submit!');

   });

});


甚至还可以再简化为:


$(function () {

   // init...

});


上面的这种写法最为常见。如果你遇到$(function () {...})的形式,牢记这是document对象的ready事件处理函数。

完全可以反复绑定事件处理函数,它们会依次执行:

$(function () {

   console.log('init A...');

});

$(function () {

   console.log('init B...');

});

$(function () {

   console.log('init C...');

});


事件参数


有些事件,如mousemove和keypress,我们需要获取鼠标位置和按键的值,否则监听这些事件就没什么意义了。所有事件都会传入Event对象作为参数,可以从Event对象上获取到更多的信息:


$(function () {

   $('#testMouseMoveDiv').mousemove(function (e) {

       $('#testMouseMoveSpan').text('pageX = ' + e.pageX + ', pageY = ' + e.pageY);

   });

});


效果实测:


mousemove: pageX = 724, pageY = 3593


在此区域移动鼠标试试


取消绑定


一个已被绑定的事件可以解除绑定,通过off('click', function)实现:


function hello() {

   alert('hello!');

}


a.click(hello); // 绑定事件


// 10秒钟后解除绑定:

setTimeout(function () {

   a.off('click', hello);

}, 10000);


需要特别注意的是,下面这种写法是无效的:


// 绑定事件:

a.click(function () {

   alert('hello!');

});


// 解除绑定:

a.off('click', function () {

   alert('hello!');

});


这是因为两个匿名函数虽然长得一模一样,但是它们是两个不同的函数对象,off('click', function () {...})无法移除已绑定的第一个匿名函数。

为了实现移除效果,可以使用off('click')一次性移除已绑定的click事件的所有处理函数。


同理,无参数调用off()一次性移除已绑定的所有类型的事件处理函数。


事件触发条件


一个需要注意的问题是,事件的触发总是由用户操作引发的。例如,我们监控文本框的内容改动:


var input = $('#test-input');

input.change(function () {

   console.log('changed...');

});


当用户在文本框中输入时,就会触发change事件。但是,如果用JavaScript代码去改动文本框的值,将不会触发change事件:


var input = $('#test-input');

input.val('change it!'); // 无法触发change事件


有些时候,我们希望用代码触发change事件,可以直接调用无参数的change()方法来触发该事件:


var input = $('#test-input');

input.val('change it!');

input.change(); // 触发change事件


input.change()相当于input.trigger('change'),它是trigger()方法的简写。


为什么我们希望手动触发一个事件呢?如果不这么做,很多时候,我们就得写两份一模一样的代码。


浏览器安全限制


在浏览器中,有些JavaScript代码只有在用户触发下才能执行,例如,window.open()函数:


// 无法弹出新窗口,将被浏览器屏蔽:

$(function () {

   window.open('/');

});


这些“敏感代码”只能由用户操作来触发:


var button1 = $('#testPopupButton1');

var button2 = $('#testPopupButton2');


function popupTestWindow() {

   window.open('/');

}


button1.click(function () {

   popupTestWindow();

});


button2.click(function () {

   // 不立刻执行popupTestWindow(),3秒后执行:

   setTimeout(popupTestWindow, 3000);

});


当用户点击button1时,click事件被触发,由于popupTestWindow()在click事件处理函数内执行,这是浏览器允许的,而button2的click事件并未立刻执行popupTestWindow(),延迟执行的popupTestWindow()将被浏览器拦截。


相关文章
|
8天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
4天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2463 14
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
4天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1503 14
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
1月前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19274 29
|
1月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18822 20
|
1月前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17515 13
Apache Paimon V0.9最新进展
|
6天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
365 11
|
1月前
|
存储 人工智能 前端开发
AI 网关零代码解决 AI 幻觉问题
本文主要介绍了 AI Agent 的背景,概念,探讨了 AI Agent 网关插件的使用方法,效果以及实现原理。
18697 16
|
2天前
|
算法 Java
JAVA并发编程系列(8)CountDownLatch核心原理
面试中的编程题目“模拟拼团”,我们通过使用CountDownLatch来实现多线程条件下的拼团逻辑。此外,深入解析了CountDownLatch的核心原理及其内部实现机制,特别是`await()`方法的具体工作流程。通过详细分析源码与内部结构,帮助读者更好地理解并发编程的关键概念。
|
2天前
|
SQL 监控 druid
Druid连接池学习
Druid学习笔记,使用Druid进行密码加密。参考文档:https://github.com/alibaba/druid
195 82