0

JQuery オートコンプリート UI ウィジェットをテストしたところ、IE で大量のデータを処理する場合、オートコンプリートのパフォーマンスが非常に低いことがわかりました。クライアントは Internet Explorer 7 を使用しています。

パフォーマンスの問題を軽減する解決策を見つけました。オートコンプリート検索のすべての一致を返す代わりに、最初の 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 項目を入力できましたが、ユーザーが動的に追加された項目の 1 つをクリックしたときに、クリック イベントをオートコンプリート 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/ 助けていただければ幸いです。

前もって感謝します

4

1 に答える 1

1

最初の 20 項目の下部に「More ..」を付けて、上位 20 のオプションをリストするため。ユーザーが「More ..」リンクを押すと。すべての項目がドロップダウンに表示されます。

(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);
于 2013-02-14T22:21:27.187 に答える