由于JavaScript在浏览器中以单线程模式运行,页面加载后,一旦页面上全部的JavaScript代码被执行完后,就只能依赖触发事件来执行JavaScript代码。javascript
浏览器在接收到用户的鼠标或键盘输入后,会自动在对应的DOM节点上触发相应的事件。若是该节点已经绑定了对应的JavaScript处理函数,该函数就会自动调用。php
因为不一样的浏览器绑定事件的代码都不太同样,因此用jQuery来写代码,就屏蔽了不一样浏览器的差别,咱们老是编写相同的代码。html
举个例子,假设要在用户点击了超连接时弹出提示框,咱们用jQuery这样绑定一个click
事件:java
/* HTML:
*
* <a id="test-link" href="#0">点我试试</a> * */ // 获取超连接的jQuery对象: var a = $('#test-link'); a.on('click', function () { alert('Hello!'); });
实测:点我试试浏览器
on
方法用来绑定一个事件,咱们须要传入事件名称和对应的处理函数。安全
另外一种更简化的写法是直接调用click()
方法:ruby
a.click(function () { alert('Hello!'); });
二者彻底等价。咱们一般用后面的写法。函数
jQuery可以绑定的事件主要包括:spa
鼠标事件
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:
取消绑定
一个已被绑定的事件能够解除绑定,经过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(),100毫秒后执行: setTimeout(popupTestWindow, 100); });
当用户点击button1
时,click
事件被触发,因为popupTestWindow()
在click
事件处理函数内执行,这是浏览器容许的,而button2
的click
事件并未马上执行popupTestWindow()
,延迟执行的popupTestWindow()
将被浏览器拦截。
效果实测: