📄 autocomplete.js
字号:
* @type String * @private */YAHOO.widget.AutoComplete.prototype._sLastTextboxValue = null;///////////////////////////////////////////////////////////////////////////////// Private methods////////////////////////////////////////////////////////////////////////////////** * Updates and validates latest public config properties. * * @method __initProps * @private */YAHOO.widget.AutoComplete.prototype._initProps = function() { // Correct any invalid values var minQueryLength = this.minQueryLength; if(!YAHOO.lang.isNumber(minQueryLength) || (minQueryLength < 1)) { minQueryLength = 1; } var maxResultsDisplayed = this.maxResultsDisplayed; if(!YAHOO.lang.isNumber(maxResultsDisplayed) || (maxResultsDisplayed < 1)) { maxResultsDisplayed = 10; } var queryDelay = this.queryDelay; if(!YAHOO.lang.isNumber(queryDelay) || (queryDelay < 0)) { queryDelay = 0.5; } var delimChar = this.delimChar; if(YAHOO.lang.isString(delimChar)) { delimChar = [delimChar]; } else if(!YAHOO.lang.isArray(delimChar)) { delimChar = null; } var animSpeed = this.animSpeed; if((this.animHoriz || this.animVert) && YAHOO.util.Anim) { if(!YAHOO.lang.isNumber(animSpeed) || (animSpeed < 0)) { animSpeed = 0.3; } if(!this._oAnim ) { oAnim = new YAHOO.util.Anim(this._oContainer._oContent, {}, animSpeed); this._oAnim = oAnim; } else { this._oAnim.duration = animSpeed; } } if(this.forceSelection && delimChar) { }};/** * Initializes the results container helpers if they are enabled and do * not exist * * @method _initContainerHelpers * @private */YAHOO.widget.AutoComplete.prototype._initContainerHelpers = function() { if(this.useShadow && !this._oContainer._oShadow) { var oShadow = document.createElement("div"); oShadow.className = "yui-ac-shadow"; this._oContainer._oShadow = this._oContainer.appendChild(oShadow); } if(this.useIFrame && !this._oContainer._oIFrame) { var oIFrame = document.createElement("iframe"); oIFrame.src = this._iFrameSrc; oIFrame.frameBorder = 0; oIFrame.scrolling = "no"; oIFrame.style.position = "absolute"; oIFrame.style.width = "100%"; oIFrame.style.height = "100%"; oIFrame.tabIndex = -1; this._oContainer._oIFrame = this._oContainer.appendChild(oIFrame); }};/** * Initializes the results container once at object creation * * @method _initContainer * @private */YAHOO.widget.AutoComplete.prototype._initContainer = function() { if(!this._oContainer._oContent) { // The oContent div helps size the iframe and shadow properly var oContent = document.createElement("div"); oContent.className = "yui-ac-content"; oContent.style.display = "none"; this._oContainer._oContent = this._oContainer.appendChild(oContent); var oHeader = document.createElement("div"); oHeader.className = "yui-ac-hd"; oHeader.style.display = "none"; this._oContainer._oContent._oHeader = this._oContainer._oContent.appendChild(oHeader); var oBody = document.createElement("div"); oBody.className = "yui-ac-bd"; this._oContainer._oContent._oBody = this._oContainer._oContent.appendChild(oBody); var oFooter = document.createElement("div"); oFooter.className = "yui-ac-ft"; oFooter.style.display = "none"; this._oContainer._oContent._oFooter = this._oContainer._oContent.appendChild(oFooter); } else { }};/** * Clears out contents of container body and creates up to * YAHOO.widget.AutoComplete#maxResultsDisplayed <li> elements in an * <ul> element. * * @method _initList * @private */YAHOO.widget.AutoComplete.prototype._initList = function() { this._aListItems = []; while(this._oContainer._oContent._oBody.hasChildNodes()) { var oldListItems = this.getListItems(); if(oldListItems) { for(var oldi = oldListItems.length-1; oldi >= 0; oldi--) { oldListItems[oldi] = null; } } this._oContainer._oContent._oBody.innerHTML = ""; } var oList = document.createElement("ul"); oList = this._oContainer._oContent._oBody.appendChild(oList); for(var i=0; i<this.maxResultsDisplayed; i++) { var oItem = document.createElement("li"); oItem = oList.appendChild(oItem); this._aListItems[i] = oItem; this._initListItem(oItem, i); } this._maxResultsDisplayed = this.maxResultsDisplayed;};/** * Initializes each <li> element in the container list. * * @method _initListItem * @param oItem {HTMLElement} The <li> DOM element. * @param nItemIndex {Number} The index of the element. * @private */YAHOO.widget.AutoComplete.prototype._initListItem = function(oItem, nItemIndex) { var oSelf = this; oItem.style.display = "none"; oItem._nItemIndex = nItemIndex; oItem.mouseover = oItem.mouseout = oItem.onclick = null; YAHOO.util.Event.addListener(oItem,"mouseover",oSelf._onItemMouseover,oSelf); YAHOO.util.Event.addListener(oItem,"mouseout",oSelf._onItemMouseout,oSelf); YAHOO.util.Event.addListener(oItem,"click",oSelf._onItemMouseclick,oSelf);};/** * Enables interval detection for Korean IME support. * * @method _onIMEDetected * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance. * @private */YAHOO.widget.AutoComplete.prototype._onIMEDetected = function(oSelf) { oSelf._enableIntervalDetection();};/** * Enables query triggers based on text input detection by intervals (rather * than by key events). * * @method _enableIntervalDetection * @private */YAHOO.widget.AutoComplete.prototype._enableIntervalDetection = function() { var currValue = this._oTextbox.value; var lastValue = this._sLastTextboxValue; if(currValue != lastValue) { this._sLastTextboxValue = currValue; this._sendQuery(currValue); }};/** * Cancels text input detection by intervals. * * @method _cancelIntervalDetection * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance. * @private */YAHOO.widget.AutoComplete.prototype._cancelIntervalDetection = function(oSelf) { if(oSelf._queryInterval) { clearInterval(oSelf._queryInterval); }};/** * Whether or not key is functional or should be ignored. Note that the right * arrow key is NOT an ignored key since it triggers queries for certain intl * charsets. * * @method _isIgnoreKey * @param nKeycode {Number} Code of key pressed. * @return {Boolean} True if key should be ignored, false otherwise. * @private */YAHOO.widget.AutoComplete.prototype._isIgnoreKey = function(nKeyCode) { if((nKeyCode == 9) || (nKeyCode == 13) || // tab, enter (nKeyCode == 16) || (nKeyCode == 17) || // shift, ctl (nKeyCode >= 18 && nKeyCode <= 20) || // alt,pause/break,caps lock (nKeyCode == 27) || // esc (nKeyCode >= 33 && nKeyCode <= 35) || // page up,page down,end (nKeyCode >= 36 && nKeyCode <= 38) || // home,left,up (nKeyCode == 40) || // down (nKeyCode >= 44 && nKeyCode <= 45)) { // print screen,insert return true; } return false;};/** * Makes query request to the DataSource. * * @method _sendQuery * @param sQuery {String} Query string. * @private */YAHOO.widget.AutoComplete.prototype._sendQuery = function(sQuery) { // Widget has been effectively turned off if(this.minQueryLength == -1) { this._toggleContainer(false); return; } // Delimiter has been enabled var aDelimChar = (this.delimChar) ? this.delimChar : null; if(aDelimChar) { // Loop through all possible delimiters and find the latest one // A " " may be a false positive if they are defined as delimiters AND // are used to separate delimited queries var nDelimIndex = -1; for(var i = aDelimChar.length-1; i >= 0; i--) { var nNewIndex = sQuery.lastIndexOf(aDelimChar[i]); if(nNewIndex > nDelimIndex) { nDelimIndex = nNewIndex; } } // If we think the last delimiter is a space (" "), make sure it is NOT // a false positive by also checking the char directly before it if(aDelimChar[i] == " ") { for (var j = aDelimChar.length-1; j >= 0; j--) { if(sQuery[nDelimIndex - 1] == aDelimChar[j]) { nDelimIndex--; break; } } } // A delimiter has been found so extract the latest query if(nDelimIndex > -1) { var nQueryStart = nDelimIndex + 1; // Trim any white space from the beginning... while(sQuery.charAt(nQueryStart) == " ") { nQueryStart += 1; } // ...and save the rest of the string for later this._sSavedQuery = sQuery.substring(0,nQueryStart); // Here is the query itself sQuery = sQuery.substr(nQueryStart); } else if(sQuery.indexOf(this._sSavedQuery) < 0){ this._sSavedQuery = null; } } // Don't search queries that are too short if(sQuery && (sQuery.length < this.minQueryLength) || (!sQuery && this.minQueryLength > 0)) { if(this._nDelayID != -1) { clearTimeout(this._nDelayID); } this._toggleContainer(false); return; } sQuery = encodeURIComponent(sQuery); this._nDelayID = -1; // Reset timeout ID because request has been made this.dataRequestEvent.fire(this, sQuery); this.dataSource.getResults(this._populateList, sQuery, this);};/** * Populates the array of <li> elements in the container with query * results. This method is passed to YAHOO.widget.DataSource#getResults as a * callback function so results from the DataSource instance are returned to the * AutoComplete instance. * * @method _populateList * @param sQuery {String} The query string. * @param aResults {Object[]} An array of query result objects from the DataSource. * @param oSelf {YAHOO.widget.AutoComplete} The AutoComplete instance. * @private */YAHOO.widget.AutoComplete.prototype._populateList = function(sQuery, aResults, oSelf) { if(aResults === null) { oSelf.dataErrorEvent.fire(oSelf, sQuery); } if(!oSelf._bFocused || !aResults) { return; } var isOpera = (navigator.userAgent.toLowerCase().indexOf("opera") != -1); var contentStyle = oSelf._oContainer._oContent.style; contentStyle.width = (!isOpera) ? null : ""; contentStyle.height = (!isOpera) ? null : ""; var sCurQuery = decodeURIComponent(sQuery); oSelf._sCurQuery = sCurQuery; oSelf._bItemSelected = false; if(oSelf._maxResultsDisplayed != oSelf.maxResultsDisplayed) { oSelf._initList(); } var nItems = Math.min(aResults.length,oSelf.maxResultsDisplayed); oSelf._nDisplayedItems = nItems; if(nItems > 0) { oSelf._initContainerHelpers(); var aItems = oSelf._aListItems; // Fill items with data for(var i = nItems-1; i >= 0; i--) { var oItemi = aItems[i]; var oResultItemi = aResults[i]; oItemi.innerHTML = oSelf.formatResult(oResultItemi, sCurQuery); oItemi.style.display = "list-item"; oItemi._sResultKey = oResultItemi[0]; oItemi._oResultData = oResultItemi; } // Empty out remaining items if any for(var j = aItems.length-1; j >= nItems ; j--) { var oItemj = aItems[j]; oItemj.innerHTML = null; oItemj.style.display = "none"; oItemj._sResultKey = null; oItemj._oResultData = null; } if(oSelf.autoHighlight) { // Go to the first item var oFirstItem = aItems[0]; oSelf._toggleHighlight(oFirstItem,"to"); oSelf.itemArrowToEvent.fire(oSelf, oFirstItem); oSelf._typeAhead(oFirstItem,sQuery); } else { oSelf._oCurItem = null; } // Expand the container var ok = oSelf.doBeforeExpandContainer(oSelf._oTextbox, oSelf._oContainer, sQuery, aResults); oSelf._toggleContainer(ok); } else { oSelf._toggleContainer(false); } oSelf.dataReturnEvent.fire(oSelf, sQuery, aResults);};/** * When forceSelection is true and the user attempts * leave the text input box without selecting an item from the query results, * the user selection is cleared. * * @method _clearSelection * @private */YAHOO.widget.AutoComplete.prototype._clearSelection = function() { var sValue = this._oTextbox.value; var sChar = (this.delimChar) ? this.delimChar[0] : null; var nIndex = (sChar) ? sValue.lastIndexOf(sChar, sValue.length-2) : -1; if(nIndex > -1) { this._oTextbox.value = sValue.substring(0,nIndex); } else { this._oTextbox.value = ""; } this._sSavedQuery = this._oTextbox.value; // Fire custom event this.selectionEnforceEvent.fire(this);};/** * Whether or not user-typed value in the text input box matches any of the * query results. * * @method _textMatchesOption * @return {Boolean} True if user-input text matches a result, false otherwise. * @private */YAHOO.widget.AutoComplete.prototype._textMatchesOption = function() { var foundMatch = false; for(var i = this._nDisplayedItems-1; i >= 0 ; i--) { var oItem = this._aListItems[i]; var sMatch = oItem._sResultKey.toLowerCase(); if(sMatch == this._sCurQuery.toLowerCase()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -