用Dojo实现tab页的过程中,没有引用“on.js”,但是firebug调试时一直提示如下错误:
on.js源码如下:
define(["./has!dom-addeventlistener?:./aspect", "./_base/kernel", "./sniff"], function(aspect, dojo, has){ "use strict"; if(has("dom")){ // check to make sure we are in a browser, this module should work anywhere var major = window.ScriptEngineMajorVersion; has.add("jscript", major && (major() + ScriptEngineMinorVersion() / 10)); has.add("event-orientationchange", has("touch") && !has("android")); // TODO: how do we detect this? has.add("event-stopimmediatepropagation", window.Event && !!window.Event.prototype && !!window.Event.prototype.stopImmediatePropagation); has.add("event-focusin", function(global, doc, element){ return 'onfocusin' in element || (element.addEventListener && (function () { var hasFocusInEvent = false; function testFocus() { hasFocusInEvent = true; } try { var element = doc.createElement('input'), activeElement = doc.activeElement; element.style.position = 'fixed'; element.addEventListener('focusin', testFocus, false); doc.body.appendChild(element); element.focus(); doc.body.removeChild(element); element.removeEventListener('focusin', testFocus, false); activeElement.focus(); } catch (e) {} return hasFocusInEvent; })()); }); } var on = function(target, type, listener, dontFix){ // summary: // A function that provides core event listening functionality. With this function // you can provide a target, event type, and listener to be notified of // future matching events that are fired. // target: Element|Object // This is the target object or DOM element that to receive events from // type: String|Function // This is the name of the event to listen for or an extension event type. // listener: Function // This is the function that should be called when the event fires. // returns: Object // An object with a remove() method that can be used to stop listening for this // event. // description: // To listen for "click" events on a button node, we can do: // | define(["dojo/on"], function(listen){ // | on(button, "click", clickHandler); // | ... // Evented JavaScript objects can also have their own events. // | var obj = new Evented; // | on(obj, "foo", fooHandler); // And then we could publish a "foo" event: // | on.emit(obj, "foo", {key: "value"}); // We can use extension events as well. For example, you could listen for a tap gesture: // | define(["dojo/on", "dojo/gesture/tap", function(listen, tap){ // | on(button, tap, tapHandler); // | ... // which would trigger fooHandler. Note that for a simple object this is equivalent to calling: // | obj.onfoo({key:"value"}); // If you use on.emit on a DOM node, it will use native event dispatching when possible. if(typeof target.on == "function" && typeof type != "function" && !target.nodeType){ // delegate to the target's on() method, so it can handle it's own listening if it wants (unless it // is DOM node and we may be dealing with jQuery or Prototype's incompatible addition to the // Element prototype return target.on(type, listener); } // delegate to main listener code return on.parse(target, type, listener, addListener, dontFix, this); }; on.pausable = function(target, type, listener, dontFix){ // summary: // This function acts the same as on(), but with pausable functionality. The // returned signal object has pause() and resume() functions. Calling the // pause() method will cause the listener to not be called for future events. Calling the // resume() method will cause the listener to again be called for future events. var paused; var signal = on(target, type, function(){ if(!paused){ return listener.apply(this, arguments); } }, dontFix); signal.pause = function(){ paused = true; }; signal.resume = function(){ paused = false; }; return signal; }; on.once = function(target, type, listener, dontFix){ // summary: // This function acts the same as on(), but will only call the listener once. The // listener will be called for the first // event that takes place and then listener will automatically be removed. var signal = on(target, type, function(){ // remove this listener signal.remove(); // proceed to call the listener return listener.apply(this, arguments); }); return signal; }; on.parse = function(target, type, listener, addListener, dontFix, matchesTarget){ if(type.call){ // event handler function // on(node, touch.press, touchListener); return type.call(matchesTarget, target, listener); } if(type.indexOf(",") > -1){ // we allow comma delimited event names, so you can register for multiple events at once var events = type.split(/s*,s*/); var handles = []; var i = 0; var eventName; while(eventName = events[i++]){ handles.push(addListener(target, eventName, listener, dontFix, matchesTarget)); } handles.remove = function(){ for(var i = 0; i < handles.length; i++){ handles[i].remove(); } }; return handles; } return addListener(target, type, listener, dontFix, matchesTarget); }; var touchEvents = /^touch/; function addListener(target, type, listener, dontFix, matchesTarget){ // event delegation: var selector = type.match(/(.*):(.*)/); // if we have a selector:event, the last one is interpreted as an event, and we use event delegation if(selector){ type = selector[2]; selector = selector[1]; // create the extension event for selectors and directly call it return on.selector(selector, type).call(matchesTarget, target, listener); } // test to see if it a touch event right now, so we don't have to do it every time it fires if(has("touch")){ if(touchEvents.test(type)){ // touch event, fix it listener = fixTouchListener(listener); } if(!has("event-orientationchange") && (type == "orientationchange")){ //"orientationchange" not supported <= Android 2.1, //but works through "resize" on window type = "resize"; target = window; listener = fixTouchListener(listener); } } if(addStopImmediate){ // add stopImmediatePropagation if it doesn't exist listener = addStopImmediate(listener); } // normal path, the target is |this| if(target.addEventListener){ // the target has addEventListener, which should be used if available (might or might not be a node, non-nodes can implement this method as well) // check for capture conversions var capture = type in captures, adjustedType = capture ? captures[type] : type; target.addEventListener(adjustedType, listener, capture); // create and return the signal return { remove: function(){ target.removeEventListener(adjustedType, listener, capture); } }; } type = "on" + type; if(fixAttach && target.attachEvent){ return fixAttach(target, type, listener); } throw new Error("Target must be an event emitter"); } on.selector = function(selector, eventType, children){ // summary: // Creates a new extension event with event delegation. This is based on // the provided event type (can be extension event) that // only calls the listener when the CSS selector matches the target of the event. // // The application must require() an appropriate level of dojo/query to handle the selector. // selector: // The CSS selector to use for filter events and determine the |this| of the event listener. // eventType: // The event to listen for // children: // Indicates if children elements of the selector should be allowed. This defaults to // true // example: // | require(["dojo/on", "dojo/mouse", "dojo/query!css2"], function(listen, mouse){ // | on(node, on.selector(".my-class", mouse.enter), handlerForMyHover); return function(target, listener){ // if the selector is function, use it to select the node, otherwise use the matches method var matchesTarget = typeof selector == "function" ? {matches: selector} : this, bubble = eventType.bubble; function select(eventTarget){ // see if we have a valid matchesTarget or default to dojo/query matchesTarget = matchesTarget && matchesTarget.matches ? matchesTarget : dojo.query; // there is a selector, so make sure it matches while(!matchesTarget.matches(eventTarget, selector, target)){ if(eventTarget == target || children === false || !(eventTarget = eventTarget.parentNode) || eventTarget.nodeType != 1){ // intentional assignment return; } } return eventTarget; } if(bubble){ // the event type doesn't naturally bubble, but has a bubbling form, use that, and give it the selector so it can perform the select itself return on(target, bubble(select), listener); } // standard event delegation return on(target, eventType, function(event){ // call select to see if we match var eventTarget = select(event.target); // if it matches we call the listener return eventTarget && listener.call(eventTarget, event); }); }; }; function syntheticPreventDefault(){ this.cancelable = false; this.defaultPrevented = true; } function syntheticStopPropagation(){ this.bubbles = false; } var slice = [].slice, syntheticDispatch = on.emit = function(target, type, event){ // summary: // Fires an event on the target object. // target: // The target object to fire the event on. This can be a DOM element or a plain // JS object. If the target is a DOM element, native event emitting mechanisms // are used when possible. // type: // The event type name. You can emulate standard native events like "click" and // "mouseover" or create custom events like "open" or "finish". // event: // An object that provides the properties for the event. See https://developer.mozilla.org/en/DOM/event.initEvent // for some of the properties. These properties are copied to the event object. // Of particular importance are the cancelable and bubbles properties. The // cancelable property indicates whether or not the event has a default action // that can be cancelled. The event is cancelled by calling preventDefault() on // the event object. The bubbles property indicates whether or not the // event will bubble up the DOM tree. If bubbles is true, the event will be called // on the target and then each parent successively until the top of the tree // is reached or stopPropagation() is called. Both bubbles and cancelable // default to false. // returns: // If the event is cancelable and the event is not cancelled, // emit will return true. If the event is cancelable and the event is cancelled, // emit will return false. // details: // Note that this is designed to emit events for listeners registered through // dojo/on. It should actually work with any event listener except those // added through IE's attachEvent (IE8 and below's non-W3C event emitting // doesn't support custom event types). It should work with all events registered // through dojo/on. Also note that the emit method does do any default // action, it only returns a value to indicate if the default action should take // place. For example, emitting a keypress event would not cause a character // to appear in a textbox. // example: // To fire our own click event // | require(["dojo/on", "dojo/dom" // | ], function(on, dom){ // | on.emit(dom.byId("button"), "click", { // | cancelable: true, // | bubbles: true, // | screenX: 33, // | screenY: 44 // | }); // We can also fire our own custom events: // | on.emit(dom.byId("slider"), "slide", { // | cancelable: true, // | bubbles: true, // | direction: "left-to-right" // | }); // | }); var args = slice.call(arguments, 2); var method = "on" + type; if("parentNode" in target){ // node (or node-like), create event controller methods var newEvent = args[0] = {}; for(var i in event){ newEvent[i] = event[i]; } newEvent.preventDefault = syntheticPreventDefault; newEvent.stopPropagation = syntheticStopPropagation; newEvent.target = target; newEvent.type = type; event = newEvent; } do{ // call any node which has a handler (note that ideally we would try/catch to simulate normal event propagation but that causes too much pain for debugging) target[method] && target[method].apply(target, args); // and then continue up the parent node chain if it is still bubbling (if started as bubbles and stopPropagation hasn't been called) }while(event && event.bubbles && (target = target.parentNode)); return event && event.cancelable && event; // if it is still true (was cancelable and was cancelled), return the event to indicate default action should happen }; var captures = has("event-focusin") ? {} : {focusin: "focus", focusout: "blur"}; if(!has("event-stopimmediatepropagation")){ var stopImmediatePropagation =function(){ this.immediatelyStopped = true; this.modified = true; // mark it as modified so the event will be cached in IE }; var addStopImmediate = function(listener){ return function(event){ if(!event.immediatelyStopped){// check to make sure it hasn't been stopped immediately event.stopImmediatePropagation = stopImmediatePropagation; return listener.apply(this, arguments); } }; } } if(has("dom-addeventlistener")){ // emitter that works with native event handling on.emit = function(target, type, event){ if(target.dispatchEvent && document.createEvent){ // use the native event emitting mechanism if it is available on the target object // create a generic event // we could create branch into the different types of event constructors, but // that would be a lot of extra code, with little benefit that I can see, seems // best to use the generic constructor and copy properties over, making it // easy to have events look like the ones created with specific initializers var nativeEvent = target.ownerDocument.createEvent("HTMLEvents"); nativeEvent.initEvent(type, !!event.bubbles, !!event.cancelable);
不知道是什么原因