2

DOM で検索し、結果をリストに表示する jQuery スクリプトがあります。

ここにスクリプトの簡易版があります: http://jsfiddle.net/FuJta/1/

通常、多数の結果があるため、スクリプトの実行には時間がかかる場合があります。(上記の例では、これはスクリプトを遅延させる関数でシミュレートされています)。そのため、検索ボックスへの入力が速すぎると、スクリプトによって入力が妨げられ、気分が悪くなります。

自由に入力できるようにスクリプトを変更するにはどうすればよいでしょうか。準備ができたら結果が表示されます。Facebook の検索のようなものが欲しいです。入力が速すぎると、結果が遅くなりますが、入力することはできます。

HTML

<p>Type in foo, bar or baz for searching. It works, but it is quite slow.</p><br/>
<input type="text" id="search"/>

<div id="container" style="display:none">
    <div class="element">foo</div>
    <div class="element">bar</div>
    <div class="element">baz</div>
</div>


<div id="results">
</div>​

Javascript

$(function() {
    function refreshResults() {
        var search = $('#search').val();
        var $filtered = $('#container .element').clone().filter(function() {
            var info = $(this).text();
            return info.toLowerCase().indexOf(search) >= 0;
        });
        $('#results').empty();
        $filtered.each(function() {
            $('#results').append($(this));
        });
    }

    // simulating script delay
    function pausecomp(millis) {
        var date = new Date();
        var curDate = null;
        do {
            curDate = new Date();
        }
        while (curDate - date < millis);
    }

    $('#search').keyup(function() {

        pausecomp(700);
        refreshResults();
    });
});​

1 つの解決策として、Enter キーを押したときにのみ結果を更新することができます。このように、結果を検索するための遅延は問題ありません。しかし、結果を遅らせて、ユーザーが自由に入力できるようにすることをお勧めします。

4

3 に答える 3

2

このような検索は、非同期手法を使用して実行する必要があります。Facebook がある種の AJAX を使用して検索結果を要求していることは間違いありません。これは、サーバーから結果を取得することを意味します。これにより、現在発生している UI の「フリーズ」を防ぐことができます。

以下は、試すことができる非常に簡単な例です (AJAX リクエストに JQuery を使用しています)。

var searchInProgress = false;//used to work out if a search is in progress
var searchInQueue = false;//used to flag if the input data has changed

function getSearchResults(searchText){
    if (searchInProgress ) {
        searchInQueue = true;
        return;
    }

    searchInProgress = true;
    searchInQueue = false;

   $.getJSON("URL",//URL to handle AJAX query
      { searchText: searchText},//URL parameters can go here
      function (data) {
         //handle your returned data here

         searchInProgress = false;

         if (searchInQueue){//text has changed, so search again
            getSearchResults();
         }
      });
}

$('#search').keyup(function() {
        getSearchResults($(this).val());
});

searchInProgressいくつかの注意事項: 必要に応じてフラグをリセットできるように、失敗した AJAX 要求を処理することをお勧めします。また、必要に応じて の後に遅延を追加することもできますがkeyup、これはすべて、どのように機能させたいかによって異なります。

于 2012-10-22T09:03:07.573 に答える
1

検索プロセスをステップに分割し、プロセス中にフローをブラウザーに戻して、UI が応答できるようにするソリューションを次に示します。

$(function() {

    function searchFunc($element,search) {
        var info = $element.text();
        return info.toLowerCase().indexOf(search) >= 0;
    }

    var searchProcessor = null;
    function restartSearch() {
        console.log('Restarting...');

        // Clear previous
        if (searchProcessor != null) {
            clearInterval(searchProcessor);
        }
        $('#results').empty();

        // Values for the processor
        var search = $('#search').val();
        var elements = $('#container .element').get();
        console.log('l:',elements,elements.length);

        // Start processing
        searchProcessor = setInterval(function() {
            if (elements.length == 0) {
                // Finished searching all elements
                clearInterval(searchProcessor);
                searchProcessor = null; 
                console.log('Finished.'); 

            } else { 
                console.log('Checking element...'); 
                var $checkElement = $(elements.shift());
                if (searchFunc($checkElement, search)) {
                    $('#results').append($checkElement.clone());
                }
            }
        }, 10);
    }

    $('#search').keyup(function() {
         restartSearch() 
    });
});

毎回 1 つの要素のみを処理します。毎回10~100回くらい処理できるように増やしていくべきなのかもしれませんが、重要な点は、作業がチャンクに分割されていることです。

clone()このソリューションは、すべてではなく、一致した要素のみを対象とするため、元のソリューションよりも高速になるはずです。

于 2012-10-22T09:41:54.870 に答える
1

ユーザーが入力しているときにKeyPress機能を遅らせる方法から、キーストロークごとにリクエストが発生しないようにしますか? :

var timeoutId = 0;
$('#search').keyup(function () { 
    clearTimeout(timeoutId); // doesn't matter if it's 0
    timeoutId = setTimeout(refreshResults, 100);
});

それは私が本当に望むことをします。

于 2012-10-22T09:05:28.147 に答える