1. ホーム
  2. javascript

[解決済み] ページロードの間に変数を持続させる

2022-10-14 07:13:22

質問

フォームの送信ボタンが押されたことをキャプチャしようとしていますが、フォームが送信された場合、ページがリフレッシュされ、いくつかの隠しフィールドが表示されます。フォームが以前送信されたかどうかをキャプチャし、再読み込み時に送信された場合、隠しフィールドを非表示にしたいと思います。これを達成するためにグローバル変数を使用しようとしましたが、正しく動作させることができませんでした。

私が試したことは以下の通りです。

  var clicked = false;

  $(document).ready(function() {

    $("input[type='submit'][value='Search']").attr("onclick", "form.act.value='detailSearch'; clicked = true;  return true;");

    if (clicked == true) {
      // show hidden fields
    } else {
      // don't show hidden fields
    }
  });

このコードの何が問題なのか、何か提案はありますか?

どのように解決するのですか?

HTTPはステートレスなので、ページを読み込むたびに、JavaScriptで設定したものの初期値が使用されます。JSでグローバル変数を設定し、ページを再び読み込んだ後もその値を維持させることはできません。

値を別の場所に保存して、JavaScriptを使用してロード時に初期化できるようにする方法が2つあります。


クエリ文字列

を使用してフォームを送信する場合 GET メソッドを使ってフォームを送信すると、URL はクエリ文字列 ( ?parameter=value&something=42 ). これを利用するには、フォームの入力フィールドに特定の値を設定します。これは最も単純な例でしょう。

<form method="GET">
    <input type="hidden" name="clicked" value="true" />
    <input type="submit" />
</form>

ページの初期読み込み時には、クエリー文字列は設定されません。このフォームを送信すると namevalue の組み合わせがクエリ文字列として渡されます。 clicked=true . そのため、このクエリ文字列でページを再度読み込むと、ボタンがクリックされたかどうかをチェックすることができます。

このデータを読み取るには、ページロード時に以下のスクリプトを使用します。

function getParameterByName(name) {
    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
        results = regex.exec(location.search);
    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
}

var clicked = getParameterByName('clicked');

( ソース )

これを使えるかどうかは、フォームが現在どのように動作しているかによります。もしすでにPOSTを使っているなら、これは問題になるかもしれません。

さらに、より大きなデータセットでは、これは最適とは言えません。文字列を渡すのは大したことではありませんが、データの配列やオブジェクトの場合は、おそらく Web Storage または Cookie を使用する必要があります。詳細はブラウザによって多少異なりますが、URI の長さの実用的な限界は、約 2000 文字


ウェブストレージ

HTML5 の導入に伴い、私たちは Web Storage も手に入れました。これは、ページの読み込み中にブラウザに情報を保存することができます。これには localStorage があり、(ユーザーが手動でクリアしない限り)より長い期間データを保存することができます。 sessionStorage は、現在のブラウジング・セッション中のみデータを保存します。後者は、ユーザーが後で戻ってきたときに "clicked" を true に設定しておきたくないので、ここで役に立ちます。

ここでは、ボタンのクリックイベントでストレージを設定しましたが、フォームの送信や他のものにバインドすることもできます。

$('input[type="submit"][value="Search"]').click(function() {
    sessionStorage.setItem('clicked', 'true');
});

そして、ページを読み込むと、これを使って設定されているかどうかを確認することができます。

var clicked = sessionStorage.getItem('clicked');

この値はこの閲覧セッションの間だけ保存されますが、もっと前にリセットしたい場合もあるかもしれません。そうするためには、以下を使用します。

sessionStorage.removeItem('clicked');

もしJSオブジェクトや配列を保存したい場合は、それを文字列に変換する必要があります。仕様によれば、他のデータ型の保存も可能なはずですが、まだブラウザ間で正しく実装されていません。

//set
localStorage.setItem('myObject', JSON.stringify(myObject));

//get
var myObject = JSON.parse(localStorage.getItem('myObject'));

ブラウザのサポートは かなり素晴らしい なので、よほど古い/不透明なブラウザをサポートする必要がない限り、安全に使用することができるはずです。ウェブ ストレージは未来です。


クッキー

Web Storageの代替手段として、Cookieにデータを保存する方法があります。クッキーは主にサーバーサイドのデータを読み取るために作られますが、純粋にクライアントサイドのデータにも使用することができます。

あなたはすでにjQueryを使用しているので、クッキーの設定は非常に簡単です。今回も click イベントを使用していますが、どこでも使用できます。

$('input[type="submit"][value="Search"]').click(function() {
    $.cookie('clicked', 'true', {expires: 1}); // expires in 1 day
});

そうすると、ページロード時にこのようにクッキーを読み取ることができます。

var clicked = $.cookie('clicked');

あなたの場合、クッキーはセッションを越えて持続するので、あなたがそれで行う必要があることは何でも、すぐにそれらを設定解除する必要があります。ユーザーが1日後に戻ってきて、まだ clicked を true に設定します。

if(clicked === "true") {
    //doYourStuff();
    $.cookie('clicked', null);
}

(jQuery以外でCookieを設定/読み込む方法は、以下の通りです。 を参照してください。 )

個人的には、クリックした状態を記憶するような単純なことにクッキーを使うことはしませんが、クエリ文字列がオプションではなく、sessionStorageをサポートしていない本当に古いブラウザをサポートする必要がある場合は、これが動作するでしょう。最初にsessionStorageをチェックするように実装し、それが失敗した場合のみCookieメソッドを使用するようにすべきです。


ウィンドウ名

これはおそらく localStorage/sessionStorage よりも前に作られたハックのように思えますが、情報を window.name プロパティに情報を保存することができます。

window.name = "my value"

文字列しか保存できないので、オブジェクトを保存したい場合は、上記のように文字列化する必要があります。 localStorage の例のように文字列化する必要があります。

window.name = JSON.stringify({ clicked: true });

大きな違いは、この情報はページの更新だけでなく、異なるドメイン間でも保持されることです。ただし、現在開いているタブに限定されます。

つまり、ページに何らかの情報を保存し、ユーザーがそのタブにいる限り、ユーザーが別の Web サイトを閲覧して戻ってきたとしても、同じ情報にアクセスできる可能性があるということです。一般に、1 つのブラウジング セッション中にクロスドメイン情報を実際に保存する必要がない限り、これを使用しないように助言します。