📄 spinner.js
字号:
/* Copyright (c) 2004-2006, The Dojo Foundation All Rights Reserved. Licensed under the Academic Free License version 2.1 or above OR the modified BSD license. For more information on Dojo licensing, see: http://dojotoolkit.org/community/licensing.shtml*/dojo.provide("dojo.widget.Spinner");dojo.require("dojo.io.*");dojo.require("dojo.lfx.*");dojo.require("dojo.html.*");dojo.require("dojo.html.layout");dojo.require("dojo.string");dojo.require("dojo.widget.*");dojo.require("dojo.widget.IntegerTextbox");dojo.require("dojo.widget.RealNumberTextbox");dojo.require("dojo.widget.DateTextbox");dojo.require("dojo.experimental");// summary: Mixin for validation widgets with a spinner// description: This class basically (conceptually) extends dojo.widget.ValidationTextbox.// It modifies the template to have up/down arrows, and provides related handling code.dojo.declare( "dojo.widget.Spinner", null, { _typamaticTimer: null, _typamaticFunction: null, _currentTimeout: this.defaultTimeout, _eventCount: 0, // Number // number of milliseconds before a held key or button becomes typematic defaultTimeout: 500, // Number // fraction of time used to change the typematic timer between events // 1.0 means that each typematic event fires at defaultTimeout intervals // < 1.0 means that each typematic event fires at an increasing faster rate timeoutChangeRate: 0.90, templatePath: dojo.uri.dojoUri("src/widget/templates/Spinner.html"), templateCssPath: dojo.uri.dojoUri("src/widget/templates/Spinner.css"), // String // up arrow graphic URL incrementSrc: dojo.uri.dojoUri("src/widget/templates/images/spinnerIncrement.gif"), // String // down arrow graphic URL decrementSrc: dojo.uri.dojoUri("src/widget/templates/images/spinnerDecrement.gif"), // does the keyboard related stuff _handleKeyEvents: function(/*Event*/ evt){ if(!evt.key){ return; } if(!evt.ctrlKey && !evt.altKey){ switch(evt.key){ case evt.KEY_DOWN_ARROW: dojo.event.browser.stopEvent(evt); this._downArrowPressed(evt); return; case evt.KEY_UP_ARROW: dojo.event.browser.stopEvent(evt); this._upArrowPressed(evt); return; } } this._eventCount++; }, _onSpinnerKeyUp: function(/*Event*/ evt){ this._arrowReleased(evt); this.onkeyup(evt); }, // reset button size; this function is called when the input area has changed size _resize: function(){ var inputSize = dojo.html.getBorderBox(this.textbox); this.buttonSize = { width: inputSize.height / 2, height: inputSize.height / 2 }; if(this.upArrowNode){ dojo.html.setMarginBox(this.upArrowNode, this.buttonSize); dojo.html.setMarginBox(this.downArrowNode, this.buttonSize); } }, _pressButton: function(/*DomNode*/ node){ node.style.borderWidth = "1px 0px 0px 1px"; node.style.borderStyle = "inset"; }, _releaseButton: function(/*DomNode*/ node){ node.style.borderWidth = "0px 1px 1px 0px"; node.style.borderStyle = "outset"; }, _arrowPressed: function(/*Event*/ evt, /*Number*/ direction){ var nodePressed = (direction == -1) ? this.downArrowNode : this.upArrowNode; var nodeReleased = (direction == +1) ? this.downArrowNode : this.upArrowNode; if(typeof evt != "number"){ if(this._typamaticTimer != null){ if(this._typamaticNode == nodePressed){ return; } dojo.lang.clearTimeout(this._typamaticTimer); } this._releaseButton(nodeReleased); this._eventCount++; this._typamaticTimer = null; this._currentTimeout = this.defaultTimeout; }else if (evt != this._eventCount){ this._releaseButton(nodePressed); return; } this._pressButton(nodePressed); this._setCursorX(this.adjustValue(direction,this._getCursorX())); this._typamaticNode = nodePressed; this._typamaticTimer = dojo.lang.setTimeout(this, "_arrowPressed", this._currentTimeout, this._eventCount, direction); this._currentTimeout = Math.round(this._currentTimeout * this.timeoutChangeRate); }, _downArrowPressed: function(/*Event*/ evt){ return this._arrowPressed(evt,-1); }, // IE sends these events when rapid clicking, mimic an extra single click _downArrowDoubleClicked: function(/*Event*/ evt){ var rc = this._downArrowPressed(evt); dojo.lang.setTimeout(this, "_arrowReleased", 50, null); return rc; }, _upArrowPressed: function(/*Event*/ evt){ return this._arrowPressed(evt,+1); }, // IE sends these events when rapid clicking, mimic an extra single click _upArrowDoubleClicked: function(/*Event*/ evt){ var rc = this._upArrowPressed(evt); dojo.lang.setTimeout(this, "_arrowReleased", 50, null); return rc; }, _arrowReleased: function(/*Event*/ evt){ this.textbox.focus(); if(evt != null && typeof evt == "object" && evt.keyCode && evt.keyCode != null){ var keyCode = evt.keyCode; var k = dojo.event.browser.keys; switch(keyCode){ case k.KEY_DOWN_ARROW: case k.KEY_UP_ARROW: dojo.event.browser.stopEvent(evt); break; } } this._releaseButton(this.upArrowNode); this._releaseButton(this.downArrowNode); this._eventCount++; if(this._typamaticTimer != null){ dojo.lang.clearTimeout(this._typamaticTimer); } this._typamaticTimer = null; this._currentTimeout = this.defaultTimeout; }, _mouseWheeled: function(/*Event*/ evt){ var scrollAmount = 0; if(typeof evt.wheelDelta == 'number'){ // IE scrollAmount = evt.wheelDelta; }else if (typeof evt.detail == 'number'){ // Mozilla+Firefox scrollAmount = -evt.detail; } if(scrollAmount > 0){ this._upArrowPressed(evt); this._arrowReleased(evt); }else if (scrollAmount < 0){ this._downArrowPressed(evt); this._arrowReleased(evt); } }, _discardEvent: function(/*Event*/ evt){ dojo.event.browser.stopEvent(evt); }, _getCursorX: function(){ var x = -1; try{ this.textbox.focus(); if (typeof this.textbox.selectionEnd == "number"){ x = this.textbox.selectionEnd; }else if (document.selection && document.selection.createRange){ var range = document.selection.createRange().duplicate(); if(range.parentElement() == this.textbox){ range.moveStart('textedit', -1); x = range.text.length; } } }catch(e){ /* squelch! */ } return x; }, _setCursorX: function(/*Number*/ x){ try{ this.textbox.focus(); if(!x){ x = 0; } if(typeof this.textbox.selectionEnd == "number"){ this.textbox.selectionEnd = x; }else if(this.textbox.createTextRange){ var range = this.textbox.createTextRange(); range.collapse(true); range.moveEnd('character', x); range.moveStart('character', x); range.select(); } }catch(e){ /* squelch! */ } }, _spinnerPostMixInProperties: function(/*Object*/ args, /*Object*/ frag){ // summary: the widget's postMixInProperties() method should call this method // set image size before instantiating template; // changing it aftwards doesn't work on FF var inputNode = this.getFragNodeRef(frag); var inputSize = dojo.html.getBorderBox(inputNode); this.buttonSize = { width: inputSize.height / 2 - 1, height: inputSize.height / 2 - 1}; }, _spinnerPostCreate: function(/*Object*/ args, /*Object*/ frag){ // summary: the widget's postCreate() method should call this method // extra listeners if(this.textbox.addEventListener){ // dojo.event.connect() doesn't seem to work with DOMMouseScroll this.textbox.addEventListener('DOMMouseScroll', dojo.lang.hitch(this, "_mouseWheeled"), false); // Mozilla + Firefox + Netscape }else{ dojo.event.connect(this.textbox, "onmousewheel", this, "_mouseWheeled"); // IE + Safari } //dojo.event.connect(window, "onchange", this, "_resize"); } });// summary// create spinable, single integer, input fielddojo.widget.defineWidget( "dojo.widget.IntegerSpinner", [dojo.widget.IntegerTextbox, dojo.widget.Spinner],{ // summary: an IntegerSpinner with +/- buttons // Number // increment amount delta: "1", postMixInProperties: function(/*Object*/ args, /*Object*/ frag){ dojo.widget.IntegerSpinner.superclass.postMixInProperties.apply(this, arguments); this._spinnerPostMixInProperties(args, frag); }, postCreate: function(/*Object*/ args, /*Object*/ frag){ dojo.widget.IntegerSpinner.superclass.postCreate.apply(this, arguments); this._spinnerPostCreate(args, frag); }, // sumary // spin the input field // direction < 0: spin down // direction > 0: spin up // direction = 0: revalidate existing value adjustValue: function(/*Number*/ direction, /*Number*/ x){ var val = this.getValue().replace(/[^\-+\d]/g, ""); if(val.length == 0){ return; } var num = Math.min(Math.max((parseInt(val)+(parseInt(this.delta) * direction)), (this.flags.min?this.flags.min:-Infinity)), (this.flags.max?this.flags.max:+Infinity)); val = num.toString(); if(num >= 0){ val = ((this.flags.signed == true)?'+':' ')+val; // make sure first char is a nondigit } if(this.flags.separator.length > 0){ for (var i=val.length-3; i > 1; i-=3){ val = val.substr(0,i)+this.flags.separator+val.substr(i); } } if(val.substr(0,1) == ' '){ val = val.substr(1); } // remove space this.setValue(val); return val.length; }});/* ****** RealNumberSpinner ****** A subclass of RealNumberTextbox. @attr places The exact number of decimal places. If omitted, it's unlimited and optional. @attr exponent Can be true or false. If omitted the exponential part is optional. @attr eSigned Is the exponent signed? Can be true or false, if omitted the sign is optional.*/dojo.widget.defineWidget( "dojo.widget.RealNumberSpinner", [dojo.widget.RealNumberTextbox, dojo.widget.Spinner], function(){ dojo.experimental("dojo.widget.RealNumberSpinner"); },{ // new subclass properties
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -