1

ajax オートコンプリートを使用した検索テキスト入力を使用して、非常に基本的なページをコーディングしました。入力の onchange 属性を設定して、サーバーから一連の値を取得し、関連するデータリストにオプションを追加する ajax 関数を呼び出します。テキスト入力で何かを変更すると、JavaScript が実行されません。ただし、ウィンドウを最小化するか、新しいタブをクリックすると、それが実行されるため、構文やファイル インクルードの問題ではないと思います。また、キャッシュをクリアしようとしましたが、効果がありませんでした(とにかく閉じるたびに、Firefoxは完全にクリアされます)。これは何が原因でしょうか? ソースコードを貼り付けます:

私のAJAXクラス。それは機能します、私は仕事でそれをテストしました、そしてそれはうまくいきます。読む必要はありません。見たい場合に備えて貼り付けます。

/**
* @file ajax.js
* @version 1.0 - 2012-07-30
* @author *****
* @brief This file describes a class allowing to easily perform AJAX requests.
*/

/**
* @class Ajax
* @brief Used to performs AJAX requests.
* @details Usage example :
*
* var request1 = new Ajax()
*     .url('some_url')
*     .parameters('some_parameters')
*     .callback(function(xhr) { alert(xhr.responseText); })
*     .method('GET')
*     .execute();
*
* var request2 = new Ajax();
* request2.url('some_url');
* request2.parameters('some_parameters');
* request2.callback(function(xhr) { alert(xhr.responseXml); });
* request2.execute();
*
* Using setters is not necessary, properties can be set manually. Setters only allow to chain calls by returning this.
* The order in which properties are set does not matter as long as the mandatory ones are set before calling 'execute'.
* If the server returns a string it can be retrieved from xhr.responseText. If it returns an XML file, it will be in
* xhr.responseXml.
*/
function Ajax()
{
    /**
    * @brief (string) URL of the request (MANDATORY).
    * @details It main contain parameters, but if so, the property 'parameters' should be used instead.
    */
    var url;

    /**
    * @brief (string) Method to use for the request.
    * @details Can be either 'GET' or 'POST'.
    */
    var method = 'POST';

    /**
    * @brief Function to be called once the request has been performed.
    * @details This callback function will be given the XMLHttpRequest object as a parameter.
    */
    var callback;

    /**
    * @brief Parameters of the URL.
    * @details Must be in the following format : 'arg1=value1&arg2=value2'... and contain no question mark.
    */
    var parameters;

    /**
    * @brief Indicates if the request is syncrhonous.
    */
    var wait = false;

    /**
    * @brief Sets the 'url' property.
    * @details Returns the object to chain setter calls.
    * @param String.
    * @return Ajax.
    */
    this.url = function($url) { url = $url; return this; };

    /**
    * @brief Sets the 'method' property.
    * @details Returns the object to chain setter calls.
    * @param String.
    * @return Ajax.
    */
    this.method = function($method) { method = $method; return this; };

    /**
    * @brief Sets the 'callback' property.
    * @details Returns the object to chain setter calls.
    * @param Function.
    * @return Ajax.
    */
    this.callback = function($callback) { callback = $callback; return this; };

    /**
    * @brief Sets the 'parameters' property.
    * @details Returns the object to chain setter calls. WARNING : Using parameters will change the method to POST. If
    * parameters must be passed using GET, they must be included in the URL.
    * @param String.
    * @return Ajax.
    */
    this.parameters = function($parameters) { parameters = $parameters; method = 'POST'; return this; };

    this.wait = function($wait) { wait = $wait; return this; };

    // FIXME POST semble poser probleme lorsque l'on renvoie du json et que l'on l'éval.

    /**
    * @brief Performs the AJAX request.
    * @details The mandatory properties must be set before calling this method.
    */
    this.execute = function()
    {
        var xhr = null;

        try { xhr = new XMLHttpRequest();  }
        catch(e) { 
            try { xhr = new ActiveXObject("Msxml2.XMLHTTP"); } 
            catch(e2) { 
                try { xhr = new ActiveXObject("Microsoft.XMLHTTP"); } 
                catch(e) {}
            }
        }

        var self = this;

        xhr.onreadystatechange = function() {
            if(4 === xhr.readyState && 200 === xhr.status) {
                if(callback) return callback(xhr);
            }
        };

        xhr.open(method, url, !wait);

        if('POST' === method) xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
        xhr.send(parameters ? parameters : null);

        return this;
    };

    return this;
}

私のAJAXオートコンプリート機能:

function ajaxAutoComplete(inputId)
{
    var input = document.getElementById(inputId);
    if(null === input) alert('ajaxAutoComplete : invalid input ID.');

    if(!input.list) alert('ajaxAutoComplete : input has no associated data list');

    var list = document.getElementById(input.list.id);
    if(null === list) alert('ajaxAutoComplete : input has an invalid list ID.');

    var suggestions;

    new Ajax()
        .url('../Controller/index.php?exec=ajaxAutoComplete')
        .parameters('searchInput=' + input.value)
        .callback(function(xhr)
        {
            suggestions = eval('(' + xhr.responseText + ')');

            while(list.hasChildNode) list.removeChild(list.firstChild);

            for(var i = 0; i < suggestions.length; ++i)
            {
                var option = document.createElement('option');
                option.value = suggestions[i];
                list.appendChild(option);
            }
        })
        .wait(false)
        .execute();

} // ajaxAutoComplete()

そしてHTMLコード:

<!DOCTYPE html>
<html>
    <head>
        <title>Image Module</title>
        <meta charset="utf-8">
        <script type="text/javascript" src="../Js/main_dev.js"></script>
    </head>
    <body>
        <header>
            <h1>Image module</h1>
        </header>
        <nav>
            <form action="#" method="#">
                <fieldset>
                    <label for="searchInput">Search</label>
                    <input id="searchInput" list="searchSuggestions" name="searchInput" type="text" value="search" maxlength="255" onchange="ajaxAutoComplete(this.id)">
                    <datalist id="searchSuggestions">
                    </datalist>
                    <input type="submit" value="Search">
                </fieldset>
            </form>
        </nav>
        <div class="Content">
        </div>
        <footer>
            <span></span>
        </footer>
    </body>
</html>

サーバーは、[1611、1515187、415417、7815、587187] のようなランダムに生成された数値の JSON エンコード配列を返します。

Firefox 14 を使用しています。

何か案は ?読んでくれてありがとう !:)

4

3 に答える 3

2

change入力がフォーカスを失うまで、イベントは発生しません。keyupまたはkeydown代わりに耳を傾けたいと思うかもしれません。

于 2012-08-06T19:41:06.467 に答える
1

changeイベントは、入力がフォーカスを失ったときにのみ発生します。

変更イベントは、コントロールが入力フォーカスを失い、フォーカスを取得してからその値が変更された場合に発生します。このイベントは、INPUT、SELECT、およびTEXTAREAで有効です。エレメント。

別のイベントにバインドします。

また、既存のコード/ウィジェット/ライブラリ/etcの使用を検討してください。–私は、このすべての車輪の再発明が、失われた時間以外にあなたに何をもたらすと思われるのか、実際にはわかりません。

于 2012-08-06T19:41:13.523 に答える
0

押された文字ごとにAJAX呼び出しを行わないことをお勧めします。リクエストを少し遅らせて、ユーザーがまだ入力しているかどうかを確認します。そうしないと、前の文字のjsonが現在のものであるかのように解析される可能性があります。これを行うには、単純なキューを作成します。

<input id="searchInput" list="searchSuggestions" name="searchInput" type="text" value="search" maxlength="255" onkeydown="queueRequest(this.id)">

Javascriptは次のようになります

function queueRequest(id) {
    if (queuedRequest) clearTimeout(queuedRequest);
    window.queuedRequest = setTimeout(function(id) {
        ajaxAutoComplete(id);
    },100,id);
}

いくつかの注意点として、setTimeoutの3番目の引数がサポートされていないため、これはIE8以下では機能しません。

于 2012-08-06T19:48:50.130 に答える