2012-10-18 41 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);