-2

newsCheck簡単に言えば、ユーザーがホームページにいない場合に呼び出される関数の間隔をクリアする必要があります。簡単そうで、私もそう思いました。これは私に大きな問題を引き起こしています。ページのリロードや変更時に間隔がクリアされない理由は、履歴 API を使用することです。

重要でないスクリプトを省略したものを次に示します。

//only run if on home page
if (url == 'Home' || url == ''  || url == 'home' || url == 'home.html' || url == 'Home.html'){

    //set up interval handler for cancellation when not on home 
    var handle=self.setInterval(function(){newsCheck()},1000);

    // ...

}//close if Home clause 
else
{
    handle = self.clearInterval(handle);
} 

さて、newsCheckAjaxクエリ(ポーリング)を介してデータベースから新しい情報をチェックする機能です。これは、家にいないときはキャンセルする必要がないため、キャンセルする必要があります。

history api に関する追加情報

履歴 API スクリプトを使用して新しいページを読み込むため、間隔をキャンセルする必要があるため、ホームページにアクセスしていなくても関数は実行され続けます。

loadContentこれに対抗するために、履歴 APIの関数にこれを入れました。

$.ajax({
         type: "GET",
         url: "AJAX/request_feed.js",
         dataType: "script"
        });

newsCheckご覧のとおり、関数をキャンセルできるように、どのページでも実行されます。これが、上記のスクリプトで URL チェックを行う理由です。

関数を含むスクリプトでは、URL が新しい URL に変更されたときに URL が取得されるように、前のページの URL を取得しないようにnewsCheckurl 変数を前に置きました。(document).ready次に、URL を確認し、オンHomeの場合はスクリプトを実行し、そうでない場合は間隔をクリアします。

4

1 に答える 1

1

これがあなたが望むものだと思います:

//only run if on home page
if (url == 'Home' || url == ''  || url == 'home' || url == 'home.html' || url == 'Home.html'){

    //set up interval handler for cancellation when not on home 
    var handle= setInterval(function(){newsCheck()},1000);

    // ...

}

編集: HTML5 history API を使用してコードを変更していることを考えると、必要なものは次のとおりです。

// Set up the handle globally, because you won't have a history event triggered right away
var handle = setInterval(function(){newsCheck()},1000);
// Cancel it right away if you're not on the home page
if (url != 'Home' && url != ''  && url != 'home' && url != 'home.html' && url != 'Home.html') {
    clearinterval(handle);
}

// Listen for history API events
window.addEventListener('popstate', function(event) {
    // Check the new url
    if (url == 'Home' || url == ''  || url == 'home' || url == 'home.html' || url == 'Home.html') {
        // On the home page now, so set up the interval
        // And we're inside an anonymous function now, so scope the handle to the window
        window.handle = setInterval(function(){newsCheck()},1000);
    } else {
        // Not on the home page now, so clear the interval
        // No guarantee that the interval exists at this point
        if(window.handle)
            clearinterval(window.handle);
    }
});

そして、'pushstate' イベント リスナーに対しても同様のことを行う必要があると思いますが、私はこのことについて少し曖昧なので、試してみてください。

元の応答

いくつかのポインター。

  1. setInterval現在、ほとんどのブラウザの JavaScript 実装のネイティブ コードです。どこにもスコープを設定する必要はありません。MDNのドキュメントと例を参照してください。
  2. ホームページ以外のページでは間隔を空ける必要はありません。ホームページ以外のページはそのまま設定してください。
  3. 1 秒に 1 回ニュースを Ajax するのは、かなりクレイジーです。コードを解決したら、より長い間隔に移行することを強くお勧めします。あなたのサーバーとあなたのユーザーは、コンピューターが遅い、待ち時間が長い、またはインターネットサービスが貧弱であることに感謝します.
  4. あなたがどこurlから来ているかによって、それは完全に偽物かもしれません. 正しい値が含まれていることを確認しましたか? 比較しているすべての値がすべての可能性であると確信していますか?

また、MDN は、間隔から呼び出される長時間実行操作について次のように述べています。

危険な使用

ロジックの実行に間隔時間よりも長くかかる可能性がある場合は、window.setTimeout を使用して名前付き関数を再帰的に呼び出すことをお勧めします。たとえば、setInterval を使用して 5 秒ごとにリモート サーバーをポーリングする場合、ネットワーク遅延、応答しないサーバー、およびその他の多くの問題により、割り当てられた時間内に要求が完了しない可能性があります。そのため、必ずしも順番に返されるとは限らない XHR リクエストがキューに入れられていることに気付くかもしれません。

このような場合、再帰的な setTimeout パターンが推奨されます。

(function loop(){
    setTimeout(function(){

       // logic here

       // recurse
       loop();

    }, 1000);
})();

上記のスニペットでは、名前付き関数ループが宣言され、すぐに実行されます。loop は、ロジックの実行が完了した後、setTimeout 内で再帰的に呼び出されます。このパターンは固定間隔での実行を保証しませんが、再帰する前に前の間隔が完了していることを保証します。

AJAX 完了コールバックからの次の newsCheck() 呼び出しのタイムアウトを設定することをお勧めします。そうすれば、まだ非同期であり、一度に複数のリクエストを開始する可能性はありません。

于 2012-12-12T23:44:59.073 に答える