📄 controls.js
字号:
// Copyright (c) 2005 Thomas Fuchs (http://script.aculo.us, http://mir.aculo.us)// (c) 2005 Ivan Krstic (http://blogs.law.harvard.edu/ivan)// // Permission is hereby granted, free of charge, to any person obtaining// a copy of this software and associated documentation files (the// "Software"), to deal in the Software without restriction, including// without limitation the rights to use, copy, modify, merge, publish,// distribute, sublicense, and/or sell copies of the Software, and to// permit persons to whom the Software is furnished to do so, subject to// the following conditions:// // The above copyright notice and this permission notice shall be// included in all copies or substantial portions of the Software.// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.Element.collectTextNodesIgnoreClass = function(element, ignoreclass) { var children = $(element).childNodes; var text = ""; var classtest = new RegExp("^([^ ]+ )*" + ignoreclass+ "( [^ ]+)*$","i"); for (var i = 0; i < children.length; i++) { if(children[i].nodeType==3) { text+=children[i].nodeValue; } else { if((!children[i].className.match(classtest)) && children[i].hasChildNodes()) text += Element.collectTextNodesIgnoreClass(children[i], ignoreclass); } } return text;}// Autocompleter.Base handles all the autocompletion functionality // that's independent of the data source for autocompletion. This// includes drawing the autocompletion menu, observing keyboard// and mouse events, and similar.//// Specific autocompleters need to provide, at the very least, // a getUpdatedChoices function that will be invoked every time// the text inside the monitored textbox changes. This method // should get the text for which to provide autocompletion by// invoking this.getEntry(), NOT by directly accessing// this.element.value. This is to allow incremental tokenized// autocompletion. Specific auto-completion logic (AJAX, etc)// belongs in getUpdatedChoices.//// Tokenized incremental autocompletion is enabled automatically// when an autocompleter is instantiated with the 'tokens' option// in the options parameter, e.g.:// new Ajax.Autocompleter('id','upd', '/url/', { tokens: ',' });// will incrementally autocomplete with a comma as the token.// Additionally, ',' in the above example can be replaced with// a token array, e.g. { tokens: new Array (',', '\n') } which// enables autocompletion on multiple tokens. This is most // useful when one of the tokens is \n (a newline), as it // allows smart autocompletion after linebreaks.var Autocompleter = {}Autocompleter.Base = function() {};Autocompleter.Base.prototype = { base_initialize: function(element, update, options) { this.element = $(element); this.update = $(update); this.has_focus = false; this.changed = false; this.active = false; this.index = 0; this.entry_count = 0; if (this.setOptions) this.setOptions(options); else this.options = options || {}; this.options.tokens = this.options.tokens || new Array(); this.options.frequency = this.options.frequency || 0.4; this.options.min_chars = this.options.min_chars || 1; this.options.onShow = this.options.onShow || function(element, update){ if(!update.style.position || update.style.position=='absolute') { update.style.position = 'absolute'; var offsets = Position.cumulativeOffset(element); update.style.left = offsets[0] + 'px'; update.style.top = (offsets[1] + element.offsetHeight) + 'px'; update.style.width = element.offsetWidth + 'px'; } new Effect.Appear(update,{duration:0.15}); }; this.options.onHide = this.options.onHide || function(element, update){ new Effect.Fade(update,{duration:0.15}) }; if(this.options.indicator) this.indicator = $(this.options.indicator); if (typeof(this.options.tokens) == 'string') this.options.tokens = new Array(this.options.tokens); this.observer = null; Element.hide(this.update); Event.observe(this.element, "blur", this.onBlur.bindAsEventListener(this)); Event.observe(this.element, "keypress", this.onKeyPress.bindAsEventListener(this)); }, show: function() { if(this.update.style.display=='none') this.options.onShow(this.element, this.update); if(!this.iefix && (navigator.appVersion.indexOf('MSIE')>0) && this.update.style.position=='absolute') { new Insertion.After(this.update, '<iframe id="' + this.update.id + '_iefix" '+ 'style="display:none;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' + 'src="javascript:false;" frameborder="0" scrolling="no"></iframe>'); this.iefix = $(this.update.id+'_iefix'); } if(this.iefix) { Position.clone(this.update, this.iefix); this.iefix.style.zIndex = 1; this.update.style.zIndex = 2; Element.show(this.iefix); } }, hide: function() { if(this.update.style.display=='') this.options.onHide(this.element, this.update); if(this.iefix) Element.hide(this.iefix); }, startIndicator: function() { if(this.indicator) Element.show(this.indicator); }, stopIndicator: function() { if(this.indicator) Element.hide(this.indicator); }, onKeyPress: function(event) { if(this.active) switch(event.keyCode) { case Event.KEY_TAB: case Event.KEY_RETURN: this.select_entry(); Event.stop(event); case Event.KEY_ESC: this.hide(); this.active = false; return; case Event.KEY_LEFT: case Event.KEY_RIGHT: return; case Event.KEY_UP: this.mark_previous(); this.render(); if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); return; case Event.KEY_DOWN: this.mark_next(); this.render(); if(navigator.appVersion.indexOf('AppleWebKit')>0) Event.stop(event); return; } else if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN) return; this.changed = true; this.has_focus = true; if(this.observer) clearTimeout(this.observer); this.observer = setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000); }, onHover: function(event) { var element = Event.findElement(event, 'LI'); if(this.index != element.autocompleteIndex) { this.index = element.autocompleteIndex; this.render(); } Event.stop(event); }, onClick: function(event) { var element = Event.findElement(event, 'LI'); this.index = element.autocompleteIndex; this.select_entry(); Event.stop(event); }, onBlur: function(event) { // needed to make click events working setTimeout(this.hide.bind(this), 250); this.has_focus = false; this.active = false; }, render: function() { if(this.entry_count > 0) { for (var i = 0; i < this.entry_count; i++) this.index==i ? Element.addClassName(this.get_entry(i),"selected") : Element.removeClassName(this.get_entry(i),"selected"); if(this.has_focus) { if(this.get_current_entry().scrollIntoView) this.get_current_entry().scrollIntoView(false); this.show(); this.active = true; } } else this.hide(); }, mark_previous: function() { if(this.index > 0) this.index-- else this.index = this.entry_count-1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -