jquery.ui.autocomplete 扩展:无限下拉
程序员文章站
2022-07-13 22:52:54
...
扩展自 jQuery.ui.autocomplete, 实现无限下拉功能。
使用场景:下拉列表数量巨大,并且可以分多次加载完成。
使用限制:source 需是 Function, 其他情况请使用jQuery.ui.autocomplete。
实现原理:在autocomplete中添加scroll事件,判断列表中最后一个项目是否被显示。
当最后一个项目被显示时,调用 search(最终调用 source) 加载后续数据。
Depends:
jquery.ui.autocomplete.js
使用场景:下拉列表数量巨大,并且可以分多次加载完成。
使用限制:source 需是 Function, 其他情况请使用jQuery.ui.autocomplete。
实现原理:在autocomplete中添加scroll事件,判断列表中最后一个项目是否被显示。
当最后一个项目被显示时,调用 search(最终调用 source) 加载后续数据。
Depends:
jquery.ui.autocomplete.js
/*! * * 扩展自 jQuery.ui.autocomplete, 实现无限下拉功能。 * * 使用场景:下拉列表数量巨大,并且可以分多次加载完成。 * * 使用限制:source 需是 Function, 其他情况请使用jQuery.ui.autocomplete。 * * 实现原理:在autocomplete中添加scroll事件,判断列表中最后一个项目是否被显示。 * 当最后一个项目被显示时,调用 search(最终调用 source) 加载后续数据。 * * * Depends: * jquery.ui.autocomplete.js */ (function( $, undefined ) { //输入的值是否发生了变化。 //_searchTimeout中设置为true,//this._on( "scroll") 中设置为 false。 //在__response和_suggest 中被使用。 var termChanged = true; //用于防止多次调用 search 方法。 var lastEleAppeared = false; $.widget( "ui.autocompleteEx", jQuery.ui.autocomplete, { version: "1.10.3", _create: function() { this._super( ); this._on( this.menu.element, { scroll : function(){ var menuElement = this.menu.element; var lastEle = menuElement.children(":last"); var eleTop = lastEle.offset().top; var maxTop = menuElement.offset().top + menuElement.height(); var minTop = maxTop - lastEle.height(); if( eleTop > minTop && eleTop < maxTop ){ if( lastEleAppeared !== true){//如最后一个元素被显示,则需加载后续数据。 lastEleAppeared = true; termChanged = false; var tmp = this.term; this.search( this.term ); this.term = tmp; } }else{ lastEleAppeared = false; } } }); }, _searchTimeout: function( event ) { clearTimeout( this.searching ); this.searching = this._delay(function() { // only search if the value has changed if ( this.term !== this._value() ) { this.selectedItem = null; termChanged = true;//***** this.search( null, event ); } }, this.options.delay ); }, _response: function() { var that = this; return function( content ) { that.__response( content ); that.pending--; if ( !that.pending ) { that.element.removeClass( "ui-autocomplete-loading" ); } }; }, __response: function( content ) { if ( content ) { content = this._normalize( content ); } this._trigger( "response", null, { content: content } ); if ( !this.options.disabled && content && content.length && !this.cancelSearch ) { this._suggest( content ); this._trigger( "open" ); } else { // use ._close() instead of .close() so we don't cancel future searches if( termChanged ){//***** this._close(); }//***** } }, _suggest: function( items ) { //***** var ul = this.menu.element; if( termChanged ){ ul.empty(); } //***** this._renderMenu( ul, items ); this.isNewMenu = true; this.menu.refresh(); // size and position menu ul.show(); this._resizeMenu(); ul.position( $.extend({ of: this.element }, this.options.position )); if ( this.options.autoFocus ) { this.menu.next(); } }, _move: function( direction, event ) { if ( !this.menu.element.is( ":visible" ) ) { this.search( null, event ); return; } if ( this.menu.isFirstItem() && /^previous/.test( direction ) || this.menu.isLastItem() && /^next/.test( direction ) ) { //this._value( this.term ); //this.menu.blur(); return; } this.menu[ direction ]( event ); } }); $.extend( $.ui.autocompleteEx, { escapeRegex: function( value ) { return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&"); }, filter: function(array, term) { var matcher = new RegExp( $.ui.autocompleteEx.escapeRegex(term), "i" ); return $.grep( array, function(value) { return matcher.test( value.label || value.value || value ); }); } }); }( jQuery ));