在对象的私有扩展对象上,专门增加了一个名为 events 的事件管理对象,在这个对象上每种事件分别对应一个同名的属性,这个属性的值是一个数组,针对这个事件的处理程序依次压入这个数组中,构成一个事件处理的列表。自定义的事件处理函数即被压入这个列表中。
在事件触发的时候,通过注册的匿名函数来执行 jQuery.event.handle ,由于使用了闭包,所以在这个函数中的 this 就是事件源对象,通过这个事件源对象找到对象的私有扩展数据,然后在 events 中找到对应的事件处理程序列表,最后,依次执行。
复制代码 代码如下:
/// <reference path="jQuery-core.js" />
// #2076
// 用于生成事件处理函数的 id
jQuery.guid = 1;
// jQuery 的事件对象
jQuery.event = { // # 1555
// 为对象增加事件
// elem 增加事件的元素, type 事件的名称, handler 事件处理程序, data 事件相关的数据
add: function (elem, type, handler, data) {
var handleObjIn, handleObj;
// 确认函数有一个唯一的 ID
if (!handler.guid) {
handler.guid = jQuery.guid++;
}
// 取得这个元素所对应的缓存数据对象
var elemData = jQuery.data(elem);
// 取得元素对应的缓存对象上的事件对象和所有事件共用的处理程序
var events = elemData.events = elemData.events || {};
var eventHandle = elemData.handle;
// 是否已经有事件处理函数 handle 只有一个,都是使用 jQuery.event.handle
// 通过使用闭包,使得这个函数引用当前的事件对象,参数。
if (!eventHandle) {
elemData.handle = eventHandle = function () {
return jQuery.event.handle.apply(eventHandle.elem, arguments);
};
}
// 使得闭包处理程序可以找到事件源对象
eventHandle.elem = elem;
//
handleObj = { handler: handler, data: data};
handleObj.namespace = "";
handleObj.type = type;
handleObj.guid = handler.guid;
// 每种事件可以有一系列的处理程序,数组形式
var handlers = events[type],
special = jQuery.event.special[type] || {};
// Init the event handler queue
if (!handlers) {
handlers = events[type] = [];
// Check for a special event handler
// Only use addEventListener/attachEvent if the special
// events handler returns false
// 完成实际的事件注册
// 实际的事件处理函数是 eventHandle
if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
// Bind the global event handler to the element
if (elem.addEventListener) {
elem.addEventListener(type, eventHandle, false);
} else if (elem.attachEvent) {
elem.attachEvent("on" + type, eventHandle);
}
}
}
// 自定义的处理函数在一个堆栈中,以后 jQuery.event.handle 到这里找到实际的处理程序
handlers.push(handleObj);
// Nullify elem to prevent memory leaks in IE
elem = null;
},
global: {},
// 真正的事件处理函数,
// 由于是通过 return jQuery.event.handle.apply(eventHandle.elem, arguments) 调用的
// 所以,此时的 this 就是事件源对象,event 是事件参数
handle: function (event) { // 1904
var all, handlers, namespaces, namespace, events;
event = window.event;
event.currentTarget = this;
// 在当前的事件对象上找到事件处理列表
var events = jQuery.data(this, "events"), handlers = events[event.type];
if (events && handlers) {
// Clone the handlers to prevent manipulation
handlers = handlers.slice(0);
for (var j = 0, l = handlers.length; j < l; j++) {
var handleObj = handlers[j];
// 取得注册事件时保存的参数
event.handler = handleObj.handler;
event.data = handleObj.data;
event.handleObj = handleObj;
var ret = handleObj.handler.apply(this, arguments);
}
}
return event.result;
},
// #2020
special: {}
}
// bind 函数定义
jQuery.fn.bind = function( type, fn)
{
var handler = fn;
// 调用 jQuery.event.add 添加事件
for (var i = 0, l = this.length; i < l; i++) {
jQuery.event.add(this[i], type, handler);
}
return this;
}
jQuery.fn.unbind = function (type, fn) {
// Handle object literals
if (typeof type === "object" && !type.preventDefault) {
for (var key in type) {
this.unbind(key, type[key]);
}
} else {
for (var i = 0, l = this.length; i < l; i++) {
jQuery.event.remove(this[i], type, fn);
}
}
return this;
}
// click 事件的注册方法
jQuery.fn.click = function (fn) {
this.bind("click", fn);
return this;
}
这样,对于页面上的 id 为 msg 的元素,就可以通过下面的代码注册一个 click 事件处理函数。
复制代码 代码如下:
// 事件操作
$("#msg").click(
function () {
alert(this.innerHTML);
}
);
在事件触发的时候,通过注册的匿名函数来执行 jQuery.event.handle ,由于使用了闭包,所以在这个函数中的 this 就是事件源对象,通过这个事件源对象找到对象的私有扩展数据,然后在 events 中找到对应的事件处理程序列表,最后,依次执行。
复制代码 代码如下:
/// <reference path="jQuery-core.js" />
// #2076
// 用于生成事件处理函数的 id
jQuery.guid = 1;
// jQuery 的事件对象
jQuery.event = { // # 1555
// 为对象增加事件
// elem 增加事件的元素, type 事件的名称, handler 事件处理程序, data 事件相关的数据
add: function (elem, type, handler, data) {
var handleObjIn, handleObj;
// 确认函数有一个唯一的 ID
if (!handler.guid) {
handler.guid = jQuery.guid++;
}
// 取得这个元素所对应的缓存数据对象
var elemData = jQuery.data(elem);
// 取得元素对应的缓存对象上的事件对象和所有事件共用的处理程序
var events = elemData.events = elemData.events || {};
var eventHandle = elemData.handle;
// 是否已经有事件处理函数 handle 只有一个,都是使用 jQuery.event.handle
// 通过使用闭包,使得这个函数引用当前的事件对象,参数。
if (!eventHandle) {
elemData.handle = eventHandle = function () {
return jQuery.event.handle.apply(eventHandle.elem, arguments);
};
}
// 使得闭包处理程序可以找到事件源对象
eventHandle.elem = elem;
//
handleObj = { handler: handler, data: data};
handleObj.namespace = "";
handleObj.type = type;
handleObj.guid = handler.guid;
// 每种事件可以有一系列的处理程序,数组形式
var handlers = events[type],
special = jQuery.event.special[type] || {};
// Init the event handler queue
if (!handlers) {
handlers = events[type] = [];
// Check for a special event handler
// Only use addEventListener/attachEvent if the special
// events handler returns false
// 完成实际的事件注册
// 实际的事件处理函数是 eventHandle
if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {
// Bind the global event handler to the element
if (elem.addEventListener) {
elem.addEventListener(type, eventHandle, false);
} else if (elem.attachEvent) {
elem.attachEvent("on" + type, eventHandle);
}
}
}
// 自定义的处理函数在一个堆栈中,以后 jQuery.event.handle 到这里找到实际的处理程序
handlers.push(handleObj);
// Nullify elem to prevent memory leaks in IE
elem = null;
},
global: {},
// 真正的事件处理函数,
// 由于是通过 return jQuery.event.handle.apply(eventHandle.elem, arguments) 调用的
// 所以,此时的 this 就是事件源对象,event 是事件参数
handle: function (event) { // 1904
var all, handlers, namespaces, namespace, events;
event = window.event;
event.currentTarget = this;
// 在当前的事件对象上找到事件处理列表
var events = jQuery.data(this, "events"), handlers = events[event.type];
if (events && handlers) {
// Clone the handlers to prevent manipulation
handlers = handlers.slice(0);
for (var j = 0, l = handlers.length; j < l; j++) {
var handleObj = handlers[j];
// 取得注册事件时保存的参数
event.handler = handleObj.handler;
event.data = handleObj.data;
event.handleObj = handleObj;
var ret = handleObj.handler.apply(this, arguments);
}
}
return event.result;
},
// #2020
special: {}
}
// bind 函数定义
jQuery.fn.bind = function( type, fn)
{
var handler = fn;
// 调用 jQuery.event.add 添加事件
for (var i = 0, l = this.length; i < l; i++) {
jQuery.event.add(this[i], type, handler);
}
return this;
}
jQuery.fn.unbind = function (type, fn) {
// Handle object literals
if (typeof type === "object" && !type.preventDefault) {
for (var key in type) {
this.unbind(key, type[key]);
}
} else {
for (var i = 0, l = this.length; i < l; i++) {
jQuery.event.remove(this[i], type, fn);
}
}
return this;
}
// click 事件的注册方法
jQuery.fn.click = function (fn) {
this.bind("click", fn);
return this;
}
这样,对于页面上的 id 为 msg 的元素,就可以通过下面的代码注册一个 click 事件处理函数。
复制代码 代码如下:
// 事件操作
$("#msg").click(
function () {
alert(this.innerHTML);
}
);
标签:
jQuery,事件处理,模拟代码
免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件!
如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
暂无“jQuery的实现原理的模拟代码 -3 事件处理”评论...
RTX 5090要首发 性能要翻倍!三星展示GDDR7显存
三星在GTC上展示了专为下一代游戏GPU设计的GDDR7内存。
首次推出的GDDR7内存模块密度为16GB,每个模块容量为2GB。其速度预设为32 Gbps(PAM3),但也可以降至28 Gbps,以提高产量和初始阶段的整体性能和成本效益。
据三星表示,GDDR7内存的能效将提高20%,同时工作电压仅为1.1V,低于标准的1.2V。通过采用更新的封装材料和优化的电路设计,使得在高速运行时的发热量降低,GDDR7的热阻比GDDR6降低了70%。
更新动态
2024年11月09日
2024年11月09日
- 雨林唱片《赏》新曲+精选集SACD版[ISO][2.3G]
- 罗大佑与OK男女合唱团.1995-再会吧!素兰【音乐工厂】【WAV+CUE】
- 草蜢.1993-宝贝对不起(国)【宝丽金】【WAV+CUE】
- 杨培安.2009-抒·情(EP)【擎天娱乐】【WAV+CUE】
- 周慧敏《EndlessDream》[WAV+CUE]
- 彭芳《纯色角3》2007[WAV+CUE]
- 江志丰2008-今生为你[豪记][WAV+CUE]
- 罗大佑1994《恋曲2000》音乐工厂[WAV+CUE][1G]
- 群星《一首歌一个故事》赵英俊某些作品重唱企划[FLAC分轨][1G]
- 群星《网易云英文歌曲播放量TOP100》[MP3][1G]
- 方大同.2024-梦想家TheDreamer【赋音乐】【FLAC分轨】
- 李慧珍.2007-爱死了【华谊兄弟】【WAV+CUE】
- 王大文.2019-国际太空站【环球】【FLAC分轨】
- 群星《2022超好听的十倍音质网络歌曲(163)》U盘音乐[WAV分轨][1.1G]
- 童丽《啼笑姻缘》头版限量编号24K金碟[低速原抓WAV+CUE][1.1G]