2012-10-18 36 views
0

我测试了JQuery的自动完成UI控件,发现有大量数据的时候自动完成在IE浏览器的性能极差。我的客户使用Internet Explorer 7JQuery的自动完成追加到开放列表

我找到了一个解决方案以缓解性能问题。我只返回前40场比赛,而不是返回自动填充搜索的所有比赛。下面的代码

source: function (request, response) { 
       var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term), "i"); 
       var select_el = select.get(0); // get dom element 
       var rep = new Array(); // response array 
       var maxRepSize = 40; // maximum response size 
       // simple loop for the options 
       var looper = 0; 
       for (var i = 0; i < select_el.length; i++) { 
        var text = select_el.options[i].text; 
        if (!request || request == '') { 
         // add element to result array 
         rep[looper++] = { 
          label: text, 
          value: text, 
          option: select_el.options[i] 
         }; 
        } 
        else if (select_el.options[i].value && matcher.test(text) ) { 
         // add element to result array 
         rep[looper++] = { 
          label: text, 
          value: text, 
          option: select_el.options[i] 
         }; 
        } 
        if (rep.length > maxRepSize) { 
         needMoreItems = true; 
         break; 
        } 
       } 
       // send response 
       response(rep); 
      }, 

客户端要求我将“更多结果”项添加到自动完成列表中。如果有超过40个项目匹配“更多结果”的项目将在列表的底部出现的搜索。如果用户在“更多结果”项点击,自动完成下拉将扩大到包括在未来的40场比赛。我尝试用jQuery的自动完成,我能够填充自动提示列表中的下一个40个项目,但是当用户在动态添加的项目之一点击,我不能click事件绑定到自动完成UI控件的选择事件。下面的代码:

open: function(event, ui) { 

       if (needMoreItems) { 

        needMoreItems = false; 
        $('<li class="ui-menu-item" role="menuitem" id="yoADDMORE" ><a class="ui-corner-all" tabindex="-1">... more available<br/><br/></a></li>') 
        .bind({ 
         click: function(e) { 
          var appendHtml = ''; 
          var select_el = select.get(0); 
          var maxRepSize = 40; // maximum response size 
          // simple loop for the options 
          var looper = 0; 
          for (var i = 41; i < select_el.length; i++) { 
           appendHtml += '<li class="ui-menu-item" role="menuitem"><a class="ui-corner-all" tabindex="-1">' + select_el.options[i].text + '</a></li>'; 

           if (looper ++ > maxRepSize) { 
            needMoreItems = true; 
            break; 
           } 
          } 
          if (needMoreItems) 
          appendHtml += '<li class="ui-menu-item" role="menuitem" id="yoADDMORE" ><a class="ui-corner-all" tabindex="-1">... more available<br/><br/></a></li>'; 
          $('#yoADDMORE').remove(); 
          $('ul.ui-autocomplete').html($('ul.ui-autocomplete').html() + appendHtml); 

          $('ul.ui-autocomplete > li') 
          .bind({ 
           mouseenter: function(e) { 
            // Hover event handler 
            $("> a",this).attr('class','ui-corner-all ui-state-hover'); 
           }, 
           mouseleave: function(e) { 
            // Hover event handler 
            $("> a",this).attr('class','ui-corner-all'); 
           } 
          }); 

         }, 
         mouseenter: function(e) { 
          // Hover event handler 
          $("> a",this).attr('class','ui-corner-all ui-state-hover'); 
         }, 
         mouseleave: function(e) { 
          // Hover event handler 
          $("> a",this).attr('class','ui-corner-all'); 
         } 



        }) 
        .appendTo('ul.ui-autocomplete'); 

       }      

      }, 

链接的jsfiddle http://jsfiddle.net/eyecode/sX4Ba/ 任何帮助,将不胜感激。

由于提前

+0

你检查错误日志?你正在得到一个'无法调用'数据'空'的错误。 – Mathletics

+0

基本上我追加项目自动完成列表中手动我收到一个错误,在“ui.data.item”为空“选择:函数(事件,UI)”事件 – Victor

+0

你是否解决了这个了吗?今天晚些时候我会有一段时间来看看它。 – Mathletics

回答

1

为了列出前20名的选项有“更多。”在第一次20个项目的底部。一旦用户按下“更多..”链接。所有项目将显示在下拉菜单中。

(function ($) { 
    $.widget("ui.typeaheadtextbox", { 
     _create: function() { 
      var self = this, 
      select = this.element.hide(), 
      theWidth = select.width(), 
      selected = select.children(":selected"), 
      value = selected.val() ? selected.text() : ""; 
     var _searchItem = ''; 
     var _more = false; 
     var _lastIndex = 0; 
     var _maxSize = 20; 
     var _rep = null; 
      var input = this.input = $("<input id='" + select[0].id + "_jq' style=\"width: " + theWidth + "px\">") 
      .insertAfter(select) 
      .val(value) 
      .autocomplete({ 
       delay: 10, 
       minLength: 0, 
       source: function (request, response) { 
        var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(request.term), "i"); 
        var j = 0; 
      _rep = response; 
      _searchItem = request.term; 
      var select_el = select.get(0); // get dom element 
      var rep = new Array(); // response array 
      for (var i = 0; i < select_el.length; i++) { 
      var text = select_el.options[i].text; 
      if (select_el.options[i].value && (!request.term || matcher.test(text))) { 
       j++; 
       if (j > _maxSize) { 
           _more = true; 
           _lastIndex = i; 
           break; 
          } 
       // add element to result array 
       rep[(j - 1)] = { 
           label: text.replace(new RegExp("^(?![^&;]+;)(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(_searchItem) + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>"), value: text, option: select_el.options[i] 
          }; 
      } 
      } 
      return response(rep); 
       }, 
       autoFocus:true, 
       open: function(event, ui) { 
        if (_more) { 
         _more = false; 
         $('<li class="ui-menu-item_more" role="menuitem" id="' + select.get(0).id + '_ADDMORE_' + _lastIndex + '" ><a class="ui-corner-all" tabindex="-1"><img width="16" src="Content/themes/base/images/icon-search-small.png"/> <strong>View All</strong></a></li>') 
         .bind({ 
          click: function(e) { 
           var response = _rep; 
           var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(_searchItem), "i"); 
           var select_el = select.get(0); // get dom element 
           var rep = new Array(); // response array 
           var j = 0; 
           for (var i = 0; i < select_el.length; i++) { 
            var text = select_el.options[i].text; 
            if (select_el.options[i].value && (!_searchItem || matcher.test(text))) { 
             // add element to result array 
             rep[j++] = { 
              label: text.replace(new RegExp("^(?![^&;]+;)(?!<[^<>]*)(" + $.ui.autocomplete.escapeRegex(_searchItem) + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>"), value: text, option: select_el.options[i] 
             }; 
            } 
           } 
           $(this).remove(); 
           return _rep(rep); 
          }, 
          mouseenter: function(e) { $("> a",this).attr('class','ui-corner-all ui-state-hover'); }, 
          mouseleave: function(e) { $("> a",this).attr('class','ui-corner-all');} 
         }) 
         .appendTo('ul.ui-autocomplete'); 
         _lastIndex = 0; 
         return true; 
        } 
       }, 
       select: function (event, ui) { 
        ui.item.option.selected = true; 
        self._trigger("selected", event, { 
         item: ui.item.option 
        }); 
       }, 
       change: function (event, ui) { 
        if (!ui.item) { 
         var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"), 
          valid = false; 
         select.children("option").each(function() { 
          if ($(this).text().match(matcher)) { 
           this.selected = valid = true; 
           return false; 
          } 
         }); 
         if (!valid) { 
          // remove invalid value, as it didn't match anything 
          $(this).val(""); 
          select.val(""); 
          input.data("autocomplete").term = ""; 
          return false; 
         } 
        } 
       } 
      }) 
      .addClass("ui-widget ui-widget-content ui-corner-all"); 
      input.data("autocomplete")._renderMenu = function(ul, items) { 
      var self = this; var htm = ''; var beginHtm = '<li><a>'; var endHtm = '</a></li>'; 
      for(var i=0;i<items.length;i++) { 
       htm += beginHtm + items[i].label + endHtm; 
      } 
      ul[0].innerHTML = htm; 
      var liTags = ul[0].getElementsByTagName('li'); 
      for(var i=0;i<liTags.length;i++) { 
      $(liTags[i]).data("item.autocomplete", items[i]); 
      } 
      return true; 
     }; 
     }, 
     destroy: function() { 
      this.input.remove(); 
      this.element.show(); 
      $.Widget.prototype.destroy.call(this); 
     }, 
     clear: function() { 
      this.element.val(""); 
      this.input.val(""); 
     } 
    }); 
})(jQuery);