- 浏览: 323247 次
- 性别:
- 来自: 南昌
文章分类
最新评论
-
j_bird:
你好,想探讨下滑动窗口是怎么计算的,一条群发短信发出去,滑动窗 ...
协议研发 中移动CMPP2.0协议API -
andyliulin:
楼主,现在的magicode 生成器工具的 官网,http: ...
Mgicode 生成器正式发布 -
huazai_wow:
楼主 你只是分析了 在jquery 中 有使用到 jQu ...
jquery event trigger 分析 -
dengkanghua:
CMPP2.0中出现流量控制错误是什么引起的。有什么解决办法吗 ...
协议研发 中移动CMPP2.0协议API -
JohnHust:
[flash=200,200][/flash][url][/u ...
Jquery源码分析(一)
/* * author:prk * date:2008-08-17 * comment:analyse of jquery event * */ jQuery.event = { // add 事件到一个元素上。 add : function(elem, types, handler, data) { if (elem.nodeType == 3 || elem.nodeType == 8)// 空白节点或注释 return; // IE不能传入window,先复制一下。 if (jQuery.browser.msie && elem.setInterval) elem = window; // 为handler分配一个全局唯一的Id if (!handler.guid) handler.guid = this.guid++; // 把data附到handler.data中 if (data != undefined) { var fn = handler; handler = this.proxy(fn, function() {// 唯一Id,wrap原始handler Fn return fn.apply(this, arguments); }); handler.data = data; } // 初始化元素的events。如果没有取到events中值,就初始化data: {} var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}), // 如果没有取到handle中值,就初始化data: function() {....} handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function() { // 处理一个触发器的第二个事件和当page已经unload之后调用一个事件。 if (typeof jQuery != "undefined" && !jQuery.event.triggered) return jQuery.event.handle.apply(// arguments.callee.elem=handle.elem arguments.callee.elem, arguments); }); // 增加elem做为handle属性,防止IE由于没有本地Event而内存泄露。 handle.elem = elem; // 处理采用空格分隔多个事件名,如jQuery(...).bind("mouseover mouseout", fn); jQuery.each(types.split(/\s+/), function(index, type) { // 命名空间的事件,一般不会用到。 var parts = type.split("."); type = parts[0]; handler.type = parts[1]; // 捆绑到本元素type事件的所有处理函数 var handlers = events[type]; if (!handlers) {// 没有找到处理函数列表就初始化事件队列 handlers = events[type] = {}; // 如果type不是ready,或ready的setup执行返回false if (!jQuery.event.special[type] || jQuery.event.special[type].setup .call(elem, data) === false) { // 调用系统的事件函数来注册事件 if (elem.addEventListener)// FF elem.addEventListener(type, handle, false); else if (elem.attachEvent)// IE elem.attachEvent("on" + type, handle); } } // 把处理器的id和handler形式属性对的形式保存在handlers列表中, // 也存在events[type][handler.guid]中。 handlers[handler.guid] = handler; // 全局缓存这个事件的使用标识 jQuery.event.global[type] = true; }); // 防止IE内存泄露。 elem = null; }, guid : 1, global : {}, // 从元素中remove一个事件 remove : function(elem, types, handler) { if (elem.nodeType == 3 || elem.nodeType == 8) return; // 取出元素的events中Fn列表 var events = jQuery.data(elem, "events"), ret, index; if (events) { // remove所有的该元素的事件 .是命名空间的处理 if (types == undefined || (typeof types == "string" && types.charAt(0) == ".")) for (var type in events) this.remove(elem, type + (types || "")); else { // types, handler参数采用{type:xxx,handler:yyy}形式 if (types.type) { handler = types.handler; types = types.type; } // 处理采用空格分隔多个事件名 jQuery(...).unbind("mouseover mouseout", fn); jQuery .each(types.split(/\s+/), function(index, type) { // 命名空间的事件,一般不会用到。 var parts = type.split("."); type = parts[0]; if (events[type]) {// 事件名找到 if (handler)// handler传入,就remove事件名的这个处理函数 delete events[type][handler.guid];//guid的作用 else // remove这个事件的所有处理函数,带有命名空间的处理 for (handler in events[type]) if (!parts[1] || events[type][handler].type == parts[1]) delete events[type][handler]; // 如果没有该事件的处理函数存在,就remove事件名 for (ret in events[type])// 看看有没有? break; if (!ret) {// 没有 if (!jQuery.event.special[type]//不是ready || jQuery.event.special[type].teardown .call(elem) === false) {// type不等于ready if (elem.removeEventListener)// 在浏览器中remove事件名 elem.removeEventListener(type, jQuery.data(elem, "handle"), false); else if (elem.detachEvent) elem.detachEvent("on" + type, jQuery.data(elem, "handle")); } ret = null; delete events[type];// 在缓存中除去。 } } }); } // 不再使用,除去expando for (ret in events) break; if (!ret) { var handle = jQuery.data(elem, "handle"); if (handle) handle.elem = null; jQuery.removeData(elem, "events"); jQuery.removeData(elem, "handle"); } } }, trigger : function(type, data, elem, donative, extra) { data = jQuery.makeArray(data); if (type.indexOf("!") >= 0) {// 支持!的not的操作如!click,除click之后的所有 type = type.slice(0, -1);// 除最后一个字符? var exclusive = true; } if (!elem) {// 处理全局的fire事件 if (this.global[type]) jQuery.each(jQuery.cache, function() { // 从cache中找到所有注册该事件的元素,触发改事件的处理函数 if (this.events && this.events[type]) jQuery.event.trigger(type, data, this.handle.elem); }); } else {// 处理单个元素事件的fire事件 if (elem.nodeType == 3 || elem.nodeType == 8) return undefined; var val, ret, fn = jQuery.isFunction(elem[type] || null), // 我们是否要提交一个伪造的事件? event = !data[0] || !data[0].preventDefault; // 构建伪造的事件。 if (event) { data.unshift( {//存到数组中的第一个 type : type, target : elem, preventDefault : function() { }, stopPropagation : function() { }, timeStamp : now() }); data[0][expando] = true; // 不需要修正伪造事件 } //防止事件名出错 data[0].type = type; if (exclusive) data[0].exclusive = true; // 触发事件 var handle = jQuery.data(elem, "handle"); if (handle) val = handle.apply(elem, data); // Handle triggering native .onfoo handlers (and on links since we // don't call .click() for links) //处理触发.onfoo这样的本地处理方法,但是是对于links 's .click()不触发 if ((!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on" + type]&& elem["on" + type].apply(elem, data) === false) val = false; // Extra functions don't get the custom event object if (event) data.shift(); // 处理触发extra事件 if (extra && jQuery.isFunction(extra)) { //执行extra,同时把结果存到data中。 ret = extra.apply(elem, val == null ? data : data.concat(val)); // if anything is returned, give it precedence and have it // overwrite the previous value if (ret !== undefined) val = ret; } // 触发本地事件 if (fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click")) { this.triggered = true; try { elem[type](); //对于一些hidden的元素,IE会报错 } catch (e) { } } this.triggered = false; } return val; }, handle : function(event) { // 返回 undefined or false var val, ret, namespace, all, handlers; event = arguments[0] = jQuery.event.fix(event || window.event); // 命名空间处理 namespace = event.type.split("."); event.type = namespace[0]; namespace = namespace[1]; // all = true 表明任何 handler all = !namespace && !event.exclusive; // 找到元素的events中缓存的事件名的处理函数列表 handlers = (jQuery.data(this, "events") || {})[event.type]; for (var j in handlers) {// 每个处理函数执行 var handler = handlers[j]; // Filter the functions by class if (all || handler.type == namespace) { // 传入引用,为了之后删除它们 event.handler = handler; event.data = handler.data; ret = handler.apply(this, arguments);// 执行事件处理函数 if (val !== false) val = ret;// 只要有一个处理函数返回false,本函数就返回false. if (ret === false) {// 不执行浏览器默认的动作 event.preventDefault(); event.stopPropagation(); } } } return val; }, props : "altKey attrChange attrName bubbles button cancelable charCode clientX " + "clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode " + "metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX " + "screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which" .split(" "), //对事件进行包裹。 fix : function(event) { if (event[expando] == true)//表明事件已经包裹过 return event; //保存原始event,同时clone一个。 var originalEvent = event; event = { originalEvent : originalEvent }; for (var i = this.props.length, prop;i;) { prop = this.props[--i]; event[prop] = originalEvent[prop]; } event[expando] = true; //加上preventDefault and stopPropagation,在clone不会运行 event.preventDefault = function() { // 在原始事件上运行 if (originalEvent.preventDefault) originalEvent.preventDefault(); originalEvent.returnValue = false; }; event.stopPropagation = function() { // 在原始事件上运行 if (originalEvent.stopPropagation) originalEvent.stopPropagation(); originalEvent.cancelBubble = true; }; // 修正 timeStamp event.timeStamp = event.timeStamp || now(); // 修正target if (!event.target) event.target = event.srcElement || document; if (event.target.nodeType == 3)//文本节点是父节点。 event.target = event.target.parentNode; // relatedTarget if (!event.relatedTarget && event.fromElement) event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement; // Calculate pageX/Y if missing and clientX/Y available if (event.pageX == null && event.clientX != null) { var doc = document.documentElement, body = document.body; event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0); event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0); } // Add which for key events if (!event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode)) event.which = event.charCode || event.keyCode; // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs) if (!event.metaKey && event.ctrlKey) event.metaKey = event.ctrlKey; // Add which for click: 1 == left; 2 == middle; 3 == right // Note: button is not normalized, so don't use it if (!event.which && event.button) event.which = (event.button & 1 ? 1 : (event.button & 2 ? 3 : (event.button & 4 ? 2 : 0))); return event; }, proxy : function(fn, proxy) { // 作用就是分配全局guid. proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++; return proxy; }, special : { ready : { // Make sure the ready event is setup setup : bindReady, teardown : function() { } } } }; if (!jQuery.browser.msie) { // Checks if an event happened on an element within another element // Used in jQuery.event.special.mouseenter and mouseleave handlers var withinElement = function(event) { // Check if mouse(over|out) are still within the same parent element var parent = event.relatedTarget; // Traverse up the tree while (parent && parent != this) try { parent = parent.parentNode; } catch (e) { parent = this; } if (parent != this) { // set the correct event type event.type = event.data; // handle event if we actually just moused on to a non sub-element jQuery.event.handle.apply(this, arguments); } }; jQuery.each( { mouseover : 'mouseenter', mouseout : 'mouseleave' }, function(orig, fix) { jQuery.event.special[fix] = { setup : function() { jQuery.event.add(this, orig, withinElement, fix); }, teardown : function() { jQuery.event.remove(this, orig, withinElement); } }; }); } jQuery.fn.extend( { bind : function(type, data, fn) { return type == "unload" ? this.one(type, data, fn) : this .each(function() {// fn || data, fn && data实现了data参数可有可无 jQuery.event.add(this, type, fn || data, fn && data); }); }, // 为每一个匹配元素的特定事件(像click)绑定一个一次性的事件处理函数。 // 在每个对象上,这个事件处理函数只会被执行一次。其他规则与bind()函数相同。 // 这个事件处理函数会接收到一个事件对象,可以通过它来阻止(浏览器)默认的行为。 // 如果既想取消默认的行为,又想阻止事件起泡,这个事件处理函数必须返回false。 one : function(type, data, fn) { var one = jQuery.event.proxy(fn || data, function(event) { jQuery(this).unbind(event, one); return (fn || data).apply(this, arguments);// this-->当前的元素 }); return this.each(function() { jQuery.event.add(this, type, one, fn && data); }); }, // bind()的反向操作,从每一个匹配的元素中删除绑定的事件。 // 如果没有参数,则删除所有绑定的事件。 // 你可以将你用bind()注册的自定义事件取消绑定。 // I如果提供了事件类型作为参数,则只删除该类型的绑定事件。 // 如果把在绑定时传递的处理函数作为第二个参数,则只有这个特定的事件处理函数会被删除。 unbind : function(type, fn) { return this.each(function() { jQuery.event.remove(this, type, fn); }); }, trigger : function(type, data, fn) { return this.each(function() { jQuery.event.trigger(type, data, this, true, fn); }); }, //这个特别的方法将会触发指定的事件类型上所有绑定的处理函数。但不会执行浏览器默认动作. triggerHandler : function(type, data, fn) { return this[0] && jQuery.event.trigger(type, data, this[0], false, fn); }, //每次点击后依次调用函数。 toggle : function(fn) { var args = arguments, i = 1; while (i < args.length)//每个函数分配GUID jQuery.event.proxy(fn, args[i++]); return this.click(jQuery.event .proxy(fn, function(event) {//分配GUID this.lastToggle = (this.lastToggle || 0) % i;//上一个函数 event.preventDefault();//阻止缺省动作 //执行参数中的第几个函数,apply可以采用array-like的参数 //With apply, you can use an array literal, //for example, fun.apply(this, [name, value]), //or an Array object, for example, fun.apply(this, new Array(name, value)). return args[this.lastToggle++].apply(this, arguments) || false; })); }, //一个模仿悬停事件(鼠标移动到一个对象上面及移出这个对象)的方法。 //这是一个自定义的方法,它为频繁使用的任务提供了一种“保持在其中”的状态。 //当鼠标移动到一个匹配的元素上面时,会触发指定的第一个函数。当鼠标移出这个元素时, //会触发指定的第二个函数。而且,会伴随着对鼠标是否仍然处在特定元素中的检测(例如,处在div中的图像), //如果是,则会继续保持“悬停”状态,而不触发移出事件(修正了使用mouseout事件的一个常见错误)。 hover : function(fnOver, fnOut) { return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut); }, //dom ready时执行 fn ready : function(fn) { bindReady();//注册监听 if (jQuery.isReady)//ready就运行 fn.call(document, jQuery); else // 增加这个函数到queue中。可见支持无数的ready的调用。 jQuery.readyList.push(function() { return fn.call(this, jQuery); }); return this; } }); jQuery.extend( { isReady : false, readyList : [], // Handle when the DOM is ready ready : function() { if (!jQuery.isReady) { jQuery.isReady = true; if (jQuery.readyList) { jQuery.each(jQuery.readyList, function() { this.call(document); }); jQuery.readyList = null; } jQuery(document).triggerHandler("ready"); } } }); var readyBound = false; function bindReady() { if (readyBound) return; readyBound = true; // Mozilla, Opera, webkit nightlies 支持DOMContentLoaded事件 if (document.addEventListener && !jQuery.browser.opera) //当DOMContentLoaded事件触发时就运行jQuery.ready document.addEventListener("DOMContentLoaded", jQuery.ready, false); //IE或不是frame的window if (jQuery.browser.msie && window == top) (function() { if (jQuery.isReady) return; try { // 在ondocumentready之前,一直都会抛出异常 // http://javascript.nwbox.com/IEContentLoaded/ document.documentElement.doScroll("left"); } catch (error) { //一直运行bindReady()(=arguments.callee) setTimeout(arguments.callee, 0); return; } jQuery.ready();//documentready就运行jQuery.ready })(); if (jQuery.browser.opera) document.addEventListener("DOMContentLoaded", function() { if (jQuery.isReady) return; //只有styleSheets完全enable时,才是完全的load,其实还有pic for (var i = 0;i < document.styleSheets.length; i++) if (document.styleSheets[i].disabled) {//通过styleSheets来判断 setTimeout(arguments.callee, 0); return; } jQuery.ready(); }, false); if (jQuery.browser.safari) { var numStyles; (function() { if (jQuery.isReady) return; //首先得得到readyState=loaded或=complete if (document.readyState != "loaded" && document.readyState != "complete") { setTimeout(arguments.callee, 0); return; } //取得style的length,比较它们之间的长度,看看是不是完成loaded if (numStyles === undefined) numStyles = jQuery("style, link[rel=stylesheet]").length; if (document.styleSheets.length != numStyles) { setTimeout(arguments.callee, 0); return; } jQuery.ready(); })(); } //最后只能依赖于window.load. jQuery.event.add(window, "load", jQuery.ready); } //为jquery对象增加常用的事件方法 jQuery .each( ("blur,focus,load,resize,scroll,unload,click,dblclick," + "mousedown,mouseup,mousemove,mouseover,mouseout,change,select," + "submit,keydown,keypress,keyup,error") .split(","), function(i, name) { jQuery.fn[name] = function(fn) { return fn ? this.bind(name, fn) : this.trigger(name); }; }); // Prevent memory leaks in IE // And prevent errors on refresh with events like mouseover in other browsers // Window isn't included so as not to unbind existing unload events jQuery(window).bind('unload', function() { for (var id in jQuery.cache) // Skip the window if (id != 1 && jQuery.cache[id].handle) jQuery.event.remove(jQuery.cache[id].handle.elem); });
发表评论
-
[转载]jquery.validate.js的基本用法入门
2011-03-10 22:35 2884[转载]jquery.validate.js的基本用法入门 j ... -
使用javascript动态创建SVG对象的问题
2011-01-11 17:18 4745无沙备忘录系列 -平时的一些研究,有时也会颇费功夫,然 ... -
evaluate mxGraph
2010-06-10 16:09 1726To evaluate mxGraph: - Navigate ... -
js中的prototype与constructor
2010-06-09 10:53 2923并且每个函数都有一个默认的prototype属性。 如果这个函 ... -
Jquery1.2.6 源码分析
2008-08-29 00:13 14152jQuery是一个非常优秀的J ... -
jquery fx分析
2008-08-28 19:37 63178 FX分析 prk/彭仁夔 ... -
jqueyr fx源码(修改)
2008-08-28 19:33 2673/* * author:prk date:2008-08-0 ... -
jquery.ajax
2008-08-27 16:50 81157.2 jquery.ajax ... -
jquery event domready
2008-08-26 17:39 41416.3 domReady的处理 ... -
jquery event trigger 分析
2008-08-26 17:37 113786.2.2 trigger ... -
jquery event addEvent 分析
2008-08-26 17:36 111976.2 事件的处理 ... -
jquery event 封装的源源分析
2008-08-26 17:35 46046.Event分析 ... -
jquery position
2008-08-25 16:34 87825.2.3 position ... -
jquery wrap
2008-08-25 08:12 44805.3.5 wrap ... -
jquery element content
2008-08-25 08:11 43495.4dom元素的内容 ... -
jquery class
2008-08-22 23:18 53715.1.2 Class prk/彭仁夔 2008- ... -
jquery attr
2008-08-22 23:16 76165 DOM元素 prk/彭仁夔 ... -
jquery Selector (修改)
2008-08-21 17:10 3098/** * author:prk * date:2008- ... -
CSS selector (jquery的源码分析,修改)
2008-08-21 17:09 44183.3、采用CSS方式查找Dom节点 ... -
如何找到Dom元素
2008-08-20 22:10 28323、如何找到Dom元素 ...
相关推荐
2. **DOM 操作(DOM Manipulation)**:jQuery 提供了一系列方法用于创建、修改和操作DOM元素,如 `append()` 在元素末尾添加内容,`prepend()` 在元素开头添加内容,`html()` 和 `text()` 用于设置或获取元素的HTML...
对于事件的操作无非是addEvent,fireEvent,removeEvent这三个事 件方法。... Jquery提供了一个 event的包裹,这个相对于其它的lib提供的有点简单,但是足够使用。 代码如下: //对事件进行包裹。 fix : function(e
2. **事件处理(Event Handling)**:jQuery提供了方便的方式来绑定和触发DOM事件。例如,`$("button").click(function() {...})`用于当按钮被点击时执行特定函数。 3. **DOM操作(DOM Manipulation)**:jQuery...
3. **DOM操作(DOM Manipulation)**:jQuery提供了一系列方便的DOM操作方法,如`append()`用于在元素内部追加内容,`remove()`用于删除元素,`clone()`用于复制元素等。 4. **事件处理(Events)**:jQuery简化了...
首先,jQuery的核心理念是“Write Less, Do More”,它通过封装了一系列简洁的API,使得开发者可以更高效地进行页面操作。在jQuery 3.3.1版本中,我们可以看到这一理念的体现。 1. **选择器(Selectors)**:jQuery...
jQuery源码分析系列涉及了对jQuery库内部实现的详细解读,jQuery作为前端开发中最常用的JavaScript库之一,它简化了DOM操作、事件处理、动画效果和AJAX交互等操作。通过深入分析jQuery的源码,开发者可以学习到先进...
4. **事件处理(Event Handling)**: jQuery简化了事件绑定和解绑,如`click()`、`hover()`和`live()`,并且提供了一致的跨浏览器事件处理。 5. **动画(Animation)**: jQuery的`fadeIn()`, `slideUp()`, `animate...
这本书籍的源码提供了丰富的实例和练习,使读者能够通过实际操作来加深对jQuery的理解。以下将详细介绍jQuery库的核心概念、功能及其在实际开发中的应用。 jQuery是一个广泛使用的JavaScript库,它的主要目标是简化...
3. **事件处理**:JQuery提供了一套简洁的API来绑定和解绑事件,如`$(selector).on('event', handler)`和`$(selector).off('event')`。此外,还有事件冒泡处理和事件委托的概念。 4. **链式调用**:JQuery对象的...
3. **事件处理(Event Handling)**:jQuery简化了事件绑定和解绑的过程,`on()`和`off()`方法使得事件处理更加灵活。通过源码,我们可以理解事件委托机制以及事件冒泡的处理方式。 4. **动画效果(Animation)**:...
1. **jQuery选择器**:jQuery提供了一系列高效的选择器,如ID选择器(`#id`)、类选择器(`.class`)、元素选择器(`element`)等,以及组合选择器( `,` 和 `:` ),例如`$("#myID .myClass")`用于选取ID为`myID`内...
3. **事件处理**:jQuery的事件处理非常灵活,如`click()`、`mouseover()`、`mouseout()`等,源码中会展示如何绑定和解绑事件,以及使用`event.preventDefault()`和`event.stopPropagation()`控制事件行为。...
jQuery的核心理念是“Write Less, Do More”,它通过封装了一系列高效的操作DOM、处理事件、创建动画的函数,使得开发者可以用更少的代码实现更多的功能。这主要体现在以下几个方面: 1. **选择器(Selectors)**:...
### jQuery源码分析关键知识点详解 #### 一、前言 在深入了解jQuery源码之前,有必要先简要介绍一下jQuery的基本情况及其对JavaScript编程领域的重要意义。jQuery作为一个轻量级、功能丰富的JavaScript库,在Web...
《jQuery第二版源码解析》 jQuery,作为一款广受欢迎的JavaScript库,为开发者提供了简单易用的API,使得DOM操作、事件处理、动画效果以及AJAX交互等任务变得轻而易举。当我们深入到jQuery的源码,不仅可以理解其...
8. **源码结构**:了解jQuery的模块化设计,如`data()`, `queue()`, `event()`, `css()`等模块,以及它们之间的关系。 通过阅读《锋利的jQuery源码》,开发者不仅可以掌握jQuery的基本用法,还能深入理解其内部机制...
3. **事件处理(Event Handling)**:jQuery提供了简洁的事件绑定方式,如`$(selector).click(function(){...})`用于绑定点击事件,`$(document).ready(function(){...})`确保在DOM加载完成后执行代码。 4. **动画...
这本书的源码提供了丰富的实践示例,下面我们将深入探讨jQuery的核心知识点。 1. **选择器**:jQuery的选择器是其强大之处之一,它基于CSS选择器,允许开发者快速准确地选取页面上的元素。例如,`$("#id")`选择ID为...
本资源提供了多个版本的jQuery未压缩源码下载,包括jQuery 1.7.2、jQuery 1.8.3、jQuery 2.0.3、jQuery 1.4.2、jQuery 1.10.2和jQuery 1.9.1。这些版本涵盖了jQuery发展中的不同时期,适合开发者根据项目需求选择...