- 浏览: 323194 次
- 性别:
- 来自: 南昌
文章分类
最新评论
-
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-07-31 * comment: */ if (!window.Event) var Event = { }; // 为Event注册一些键名 Object.extend(Event, { KEY_BACKSPACE: 8, KEY_TAB: 9, KEY_RETURN: 13, KEY_ESC: 27, KEY_LEFT: 37, KEY_UP: 38, KEY_RIGHT: 39, KEY_DOWN: 40, KEY_DELETE: 46, KEY_HOME: 36, KEY_END: 35, KEY_PAGEUP: 33, KEY_PAGEDOWN: 34, KEY_INSERT: 45, // 缓存 cache: { }, // 事件相关连的元素,只对mouseover,mouseout有效。 relatedTarget: function(event) { var element; // event.type,事件名 switch(event.type) { case 'mouseover': element = event.fromElement; break; case 'mouseout': element = event.toElement; break; default: return null; } // 通过Extend 包装原配的emement为Prototype的Element // 在YUI则进行了resolveTextNode的处理。觉得有必要。 return Element.extend(element); } }); Event.Methods = (function() { // 判断是按了鼠标的什么键,右,左,中间啊, // 解决Brower的兼容性 var isButton; if (Prototype.Browser.IE) { var buttonMap = { 0: 1, 1: 4, 2: 2 }; isButton = function(event, code) { return event.button == buttonMap[code]; }; } else if (Prototype.Browser.WebKit) { isButton = function(event, code) { switch (code) { case 0: return event.which == 1 && !event.metaKey; case 1: return event.which == 1 && event.metaKey; default: return false; } }; } else { isButton = function(event, code) { return event.which ? (event.which === code + 1) : (event.button === code); }; } // Ext 通过下面三行解决兼容问题。 // var btnMap = Ext.isIE ? {1:0,4:1,2:2} : // (Ext.isSafari ? {1:0,2:1,3:2} : {0:0,1:1,2:2}); // this.button = e.button ? btnMap[e.button] : (e.which ? e.which-1 : -1); return { isLeftClick: function(event) { return isButton(event, 0) }, isMiddleClick: function(event) { return isButton(event, 1) }, isRightClick: function(event) { return isButton(event, 2) }, // 定位event 's element element: function(event) { // 包装Event event = Event.extend(event); var node = event.target, currentTarget = event.currentTarget, type = event.type; // target:Returns a reference to the target to which the event was // originally dispatched // currentTarget:Returns a reference to the currently registered target // for the event. // 解决FF的兼容 if (currentTarget && currentTarget.tagName) { // Firefox screws up the "click" event when moving between radio buttons // via arrow keys. It also screws up the "load" and "error" events on // images, reporting the document as the target instead of the original // image. if (['load', 'error'].include(type) || (currentTarget.tagName.toUpperCase() === "INPUT" && currentTarget.type === "radio" && type === "click")) node = currentTarget; } // node.nodeType == Node.TEXT_NODE ? node.parentNode // 是YUI Event中resolveTextNode return Element.extend(node && node.nodeType == Node.TEXT_NODE ? node.parentNode : node); }, // 查找到event的原始节点的祖先节点。expression只能是标签名 如a findElement: function(event, expression) { var element = Event.element(event); if (!expression) return element; var elements = [element].concat(element.ancestors()); return Selector.findElement(elements, expression, 0); }, // 事件的元素的x,y坐标,相对于页面的。 pointer: function(event) { /* * pageX/Y:coordinate of the event relative to the page layerX/Y: coordinate * of the event relative to the current layer screenX/Y: position of the * event on the screen Browser区域 clientX /Y: position of the event * 页面在Browser中区域。 */ var docElement = document.documentElement, body = document.body || { scrollLeft: 0, scrollTop: 0 }; return { x: event.pageX || (event.clientX + (docElement.scrollLeft || body.scrollLeft) - (docElement.clientLeft || 0)), y: event.pageY || (event.clientY + (docElement.scrollTop || body.scrollTop) - (docElement.clientTop || 0)) }; }, pointerX: function(event) { return Event.pointer(event).x }, pointerY: function(event) { return Event.pointer(event).y }, // 中断事件 stop: function(event) { Event.extend(event); event.preventDefault(); event.stopPropagation(); event.stopped = true; } }; })(); // 实现Event的确extend Event.extend = (function() { // 作用就是把函数的调用对象变成函数是第一个参数。条理化。 var methods = Object.keys(Event.Methods).inject({ }, function(m, name) { m[name] = Event.Methods[name].methodize(); return m; }); if (Prototype.Browser.IE) { Object.extend(methods, { stopPropagation: function() { this.cancelBubble = true }, preventDefault: function() { this.returnValue = false }, inspect: function() { return "[object Event]" } }); return function(event) { if (!event) return false; if (event._extendedByPrototype) return event; var pointer = Event.pointer(event); // 为事件注册属性 Object.extend(event, { _extendedByPrototype: Prototype.emptyFunction, target: Element.extend(event.srcElement), relatedTarget: Event.relatedTarget(event), pageX: pointer.x, pageY: pointer.y }); // 推迟到每次调用时,才把methods考到event return Object.extend(event, methods); }; } else { // 把条理化的方法注册到Event.prototype Event.prototype = Event.prototype || document.createEvent("HTMLEvents")['__proto__']; Object.extend(Event.prototype, methods); return Prototype.K; } })(); Object.extend(Event, (function() { var cache = Event.cache; function getEventID(element) { // Event ID is stored as the 0th index in a one-item array so that it // won't get copied to a new node when cloneNode is called. // 这种处理递增的Id很妙,arguments.callee.id=getEventID.id,同时也设定getEventID.id if (element === window) return 1; if (element._prototypeEventID) return element._prototypeEventID[0]; return (element._prototypeEventID = [arguments.callee.id++])[0]; } getEventID.id = 2; function getDOMEventName(eventName) { if (eventName && eventName.include(':')) return "dataavailable"; return eventName; } // 根据Id从cache中取得或生成一个元素的缓存。 function getCacheForID(id) { return cache[id] = cache[id] || { }; } // 根据Id,eventName从cache中取得或生成一个元素的的事件名数组 function getWrappersForEventName(id, eventName) { var c = getCacheForID(id); return c[eventName] = c[eventName] || []; } // 包装handler,主要作用取Id,缓存。 function createWrapper(element, eventName, handler) { // create id,and create cache for id. var id = getEventID(element), c = getCacheForID(id); // Attach the element itself onto its cache entry so we can retrieve it for // cleanup on page unload. {3:{element:element}} if (!c.element) c.element = element; // {3:{element:element,eventName:[]}} var w = getWrappersForEventName(id, eventName); // 有的话,不加入了 if (w.pluck("handler").include(handler)) return false; // wrapper FN var wrapper = function(event) { if (!Event || !Event.extend || (event.eventName && event.eventName != eventName)) return false; handler.call(element, Event.extend(event)); }; // add static method:handler=original handler // {3:{element:element,eventName:[{handler:handler,wrapper:wrapper}]}} wrapper.handler = handler; // store in cache. w.push(wrapper); return wrapper; } // 根据id, eventName, handler找已经cache的Wrapper function findWrapper(id, eventName, handler) { // {3:{element:element,eventName:[wrapper1,wrapper1]}} // w=[wrapper1,wrapper1] var w = getWrappersForEventName(id, eventName); // 函数在数组中找到符合条件的数组元素,很方便 return w.find(function(wrapper) { return wrapper.handler == handler }); } // 从eventName对应的数组中去掉符合条件的。 function destroyWrapper(id, eventName, handler) { var c = getCacheForID(id); if (!c[eventName]) return false; c[eventName] = c[eventName].without(findWrapper(id, eventName, handler)); } // Loop through all elements and remove all handlers on page unload. IE // needs this in order to prevent memory leaks. function purgeListeners() { var element, entry; for (var i in Event.cache) { // cache={3:{element:element,eventName:[wrapper1,wrapper1]}} entry = Event.cache[i]; // unscribe the element 's listen. Event.stopObserving(entry.element); entry.element = null; } } function onStop() { document.detachEvent("onstop", onStop); purgeListeners(); } function onBeforeUnload() { if (document.readyState === "interactive") { document.attachEvent("onstop", onStop); (function() { document.detachEvent("onstop", onStop); }).defer(); } } // 防止IE内存泄露 if (window.attachEvent && !window.addEventListener) { // Internet Explorer needs to remove event handlers on page unload // in order to avoid memory leaks. window.attachEvent("onunload", purgeListeners); // IE also doesn't fire the unload event if the page is navigated away // from before it's done loading. Workaround adapted from // http://blog.moxiecode.com/2008/04/08/unload-event-never-fires-in-ie/. window.attachEvent("onbeforeunload", onBeforeUnload); } // Safari has a dummy event handler on page unload so that it won't // use its bfcache. Safari <= 3.1 has an issue with restoring the "document" // object when page is returned to via the back button using its bfcache. else if (Prototype.Browser.WebKit) { window.addEventListener("unload", Prototype.emptyFunction, false); } return { // 为element的某个事件注册处理函数。 observe: function(element, eventName, handler) { element = $(element); var name = getDOMEventName(eventName); // cache={id:{element:element,eventName:[wrapper1{handler:handler},wrapper2{handler:handler}]}} var wrapper = createWrapper(element, eventName, handler); if (!wrapper) return element; // IE和FF的兼容,addEventListener if (element.addEventListener) { element.addEventListener(name, wrapper, false); } else { element.attachEvent("on" + name, wrapper); } return element; }, //unscribe the Listener stopObserving: function(element, eventName, handler) { element = $(element); eventName = Object.isString(eventName) ? eventName : null; // cache={id:{element:element,eventName:[wrapper1{handler:handler},wrapper2{handler:handler}]}} var id = getEventID(element), c = cache[id]; if (!c) { return element; } // handler不存在,eventName存在,就unscribe all the Listener of this eventName else if (!handler && eventName) { getWrappersForEventName(id, eventName).each(function(wrapper) { Event.stopObserving(element, eventName, wrapper.handler); }); return element; } // eventName不存在,unscribe all the Listener of this element。 else if (!eventName) { Object.keys(c).without("element").each(function(eventName) { Event.stopObserving(element, eventName); }); return element; } var wrapper = findWrapper(id, eventName, handler); if (!wrapper) return element; // unregist element Listener. var name = getDOMEventName(eventName); // 从Dom element removeEventListener if (element.removeEventListener) {//FF element.removeEventListener(name, wrapper, false); } else {//IE element.detachEvent("on" + name, wrapper); } // 清除相当的handler destroyWrapper(id, eventName, handler); return element; }, // 手工触发DOM元素监听。 fire: function(element, eventName, memo) { // http://www.nabble.com/firefox-DOM-does-not-have-the-fireEvent-function-t2188792.html // 在FF中实现IE fireEvent方法 element = $(element); //不知道为了兼容那一个FF系列的游览器。 if (element == document && document.createEvent && !element.dispatchEvent) element = document.documentElement; /* * initEvent 该方法将初始化 Document.createEvent() 方法创建的合成 Event 对象的 type * 属性、bubbles 属性和 cancelable 属性。 只有在新创建的 Event 对象被 Document 对象或 Element * 对象的 dispatchEvent() 方法分派之前,才能调用 Event.initEvent() 方法。 */ var event; if (document.createEvent) { // FF中人工fire,先create event,second: initEvent,then dispatchEvent event = document.createEvent("HTMLEvents"); // event.initEvent(eventType,canBubble,cancelable) event.initEvent("dataavailable", true, true); } else {// IE event = document.createEventObject(); event.eventType = "ondataavailable"; } event.eventName = eventName; event.memo = memo || { }; if (document.createEvent) {// FF element.dispatchEvent(event); } else {// IE element.fireEvent(event.eventType, event); } return Event.extend(event); } }; })()); // Event的静态方法 Object.extend(Event, Event.Methods); // Element的静态方法 Element.addMethods({ fire: Event.fire, observe: Event.observe, stopObserving: Event.stopObserving }); // document方法,但条理化。也就是 // fire: function(element, eventName, memo)不要传入element //它现在已经默认为document Object.extend(document, { fire: Element.Methods.fire.methodize(), observe: Element.Methods.observe.methodize(), stopObserving: Element.Methods.stopObserving.methodize(), loaded: false }); (function() { /* * Support for the DOMContentLoaded event is based on work by Dan Webb, * Matthias Miller, Dean Edwards, John Resig and Diego Perini. */ var timer; function fireContentLoadedEvent() { if (document.loaded) return; if (timer) window.clearInterval(timer); document.loaded = true; // mothodize,document.fire("dom:loaded")==Element.Methods.fire(document,"dom:loaded") document.fire("dom:loaded"); } function isCssLoaded() { return true; } // FF系列 if (document.addEventListener) { // Opera\WebKit isCssLoaded if (Prototype.Browser.Opera) { isCssLoaded = function() { var sheets = document.styleSheets, length = sheets.length; while (length--) if (sheets[length].disabled) return false; return true; }; // Force check to end when window loads Event.observe(window, "load", function() { isCssLoaded = function() { return true } }); } else if (Prototype.Browser.WebKit) { isCssLoaded = function() { var length = document.getElementsByTagName('style').length, links = document.getElementsByTagName('link'); for (var i=0, link; link = links[i]; i++) if(link.getAttribute('rel') == "stylesheet") length++; return document.styleSheets.length >= length; }; } document.addEventListener("DOMContentLoaded", function() { // Ensure all stylesheets are loaded, solves Opera/Safari issue // arguments.callee // /Reference to the currently executing function. if (!isCssLoaded()) return arguments.callee.defer(); fireContentLoadedEvent(); }, false); } else {// IE document.attachEvent("onreadystatechange", function() { if (document.readyState == "complete") { document.detachEvent("onreadystatechange", arguments.callee); fireContentLoadedEvent(); } }); if (window == top) { timer = setInterval(function() { try { document.documentElement.doScroll("left"); } catch(e) { return } fireContentLoadedEvent(); }, 10); } } // Safari <3.1 doesn't support DOMContentLoaded if (Prototype.Browser.WebKit && (navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1] < 525)) { timer = setInterval(function() { if (/loaded|complete/.test(document.readyState) && isCssLoaded()) fireContentLoadedEvent(); }, 10); } // Worst case fallback... Event.observe(window, "load", fireContentLoadedEvent); })();
相关推荐
3. **事件处理**:Prototype.js通过`Event.observe`和`Event.stopObserving`方法,简化了事件监听和解绑。此外,它还提供了一个统一的事件模型,解决了浏览器间事件处理的兼容性问题。 4. **函数扩展**:Prototype....
《prototype.js源码及PDF文档》是一份宝贵的资源,它包含了一个重要的JavaScript库——Prototype的源代码和相关的PDF文档。Prototype是Web开发中一个广泛使用的开源JavaScript框架,它旨在简化DOM操作,提供强大的...
Prototype 1.4版本是该库的一个重要里程碑,本文将深入解析其源码,帮助初学者理解其内部机制,并通过实例进一步阐述其使用方法。 首先,Prototype的核心设计理念是通过增加类和对象的概念,使JavaScript这种基于...
PrototypeJS 是一个广泛使用的JavaScript库,它为JavaScript编程提供了许多便利的功能和方法,尤其...同时,对于想要深入了解JavaScript机制或开发自己的JavaScript库的人来说,研究PrototypeJS源码是一条很好的途径。
此外,Prototype 源码中还有很多其他有用的功能,如 `Function.prototype.bind`(绑定函数上下文),`Array.prototype.each`(数组迭代),以及 `Element` 和 `Event` 的扩展等,这些都是为了增强 JavaScript 的基本...
4. **事件处理**:Prototype改进了JavaScript的事件处理机制,引入了`Event.observe`和`Event.stopObserving`方法,可以方便地绑定和解绑事件监听器,同时提供了阻止事件冒泡的功能。 5. **CSS选择器**:Prototype...
3. **事件处理**:Prototype 的事件系统使得绑定和解绑事件更简单,如 `Event.observe()` 和 `Event.stopObserving()`,并且支持事件委托。 4. **Ajax**:Prototype 提供了 `Ajax` 对象,封装了异步通信,包括 `...
通过以上对 Prototype 1.3 源码的分析可以看出,Prototype 旨在通过简洁高效的 API 来简化前端开发工作,尤其是针对 DOM 操作、事件处理以及类型操作等方面。这些核心功能的实现不仅提高了开发效率,还增强了代码的...
2. **事件处理**:Prototype 改进了JavaScript的事件处理机制,提供了一致的跨浏览器事件绑定和解绑,如 `Event.observe` 和 `Event.stopObserving`。 3. **Ajax交互**:`Ajax` 类包含了一系列用于创建异步HTTP请求...
通过阅读和分析 Prototype 1.5 版本的源码,开发者不仅可以学习到 JavaScript 的高级技巧,还能领略到优秀的代码设计和工程实践。同时,了解 Prototype 的源码也有助于理解其他 JavaScript 库和框架,如 jQuery 和 ...
4. **事件处理**:Prototype提供了`Event.observe()`和`Event.stopObserving()`方法来绑定和解绑事件处理程序,以及`Event.stop()`来阻止事件的默认行为。此外,它还引入了模拟DOM事件冒泡的概念,使得跨浏览器的...
JS文件很可能是Prototype库的源码或者示例代码,通过阅读和分析源码,开发者可以深入理解Prototype的工作原理,对于调试和定制Prototype功能大有裨益。 在学习Prototype的过程中,不仅要掌握上述知识点,还要通过...
5. **事件处理**:Prototype 提供了统一的事件处理模型,如`Event.observe()`用于绑定事件监听器,`Event.stop()`阻止事件冒泡,使得跨浏览器的事件处理更加一致。 6. **Selectors API**:Prototype 包含了一个类似...
2. Delegation(委托):Prototype的`Event.observe()`方法可以实现事件委托,监听父元素上的事件,处理子元素的行为,减少事件监听器的数量,提高性能。 五、Function增强 1. Function.prototype.bind:这个方法...
Prototype提供了事件处理的统一接口,可以使用`Event.observe()`和`Event.stopObserving()`来监听和移除事件。此外,还有`Event.stop()`、`Event.preventDefault()`等方法用于控制事件流。 6. **`prototype.js`...
- **Prototype源码分析**:通过阅读源码,可以学习到JavaScript设计模式、模块化开发以及如何优化JavaScript性能等方面的知识。 - **Prototype API**:API文档是学习如何使用Prototype的关键资源,它会详细介绍每个...
《Prototype参考手册》是关于JavaScript库Prototype的一份详尽指南,该库主要为JavaScript编程提供了一种更加面向对象的语法和实用工具。Prototype是Web开发中的一个重要组件,它通过扩展JavaScript的基本类型和对象...
6. **Event Handling**:Prototype改进了事件处理,提供了一种更符合面向对象编程习惯的方式来绑定和处理事件,如`observe`和`stopObserving`。 7. **Ajax部件(Ajax Components)**:如`Ajax.InPlaceEditor`和`...
5. **事件处理**:Prototype库提供了`Event.observe()`和`Event.stopObserving()`方法,用于事件监听和解绑,增强了事件处理的灵活性。 6. **特效与动画**:Prototype 1.4包含了一些基础的动画效果,如`Element....