| イヌでもわかるJavaScript講座 | 
| Step.96 - クッキーを焼いて食べる | 
| クッキーを使って、訪問者の名前と訪問回数を表示してみます。 | 
| Step テーマ ● document.cookie | 
| 実行例 | 
| リスト
 
 | 
| サンプルだけの HTMLは こちらへ | 
| 説明クッキーを使って、訪問者の名前と訪問回数を表示してみましょう。 ●クッキーとは クッキーとは訪問者のパソコンにデータを書き込んだり、読み込んだりできる唯一?の方法で、その実体は小さなテキストファイルです。 今回やることは、訪問者の名前と訪問回数をクッキーを使って保存(【俗語:クッキーを焼く】) しておいて、次回からはクッキーを読み込んで(【俗語:クッキーを食べる】)ページ上に 「xxxさん、xx回目の訪問ありがとう!」といったメッセージを表示します。 プログラムの流れも言うには簡単です。 ・クッキーを食べる。 ・はじめての訪問なら名前を入力してもらう。名前を焼く。 ・名前と訪問回数を表示する。 ・訪問回数をカウントさせて焼きなおす。 実に簡単っぽいけど、クッキーを調理するのは奥が深くてめんどくさいのです。 クッキーを食べるには難しいことはありません。すでに document.cookie に入っています。 今回、訪問者名に USER_NAME、訪問回数に USER_COUNTER というクッキー名をつけました。その「=」に続く内容がその値で、セミコロン区切りで1行の文字列になっています。 その中から訪問者名を抜き出すためには切り取るしか方法がありません。つまり indexOf() や substring() とかを駆使して抜き取るわけです。今回はその2つを使っています。 indexOf() で先頭と最終位置を割り出して、substring() で切り取るわけです。 クッキー名の頭に「@」をわざとつけています。 myCookie = "@" + myCookie + "="; 例えば、クッキー名に USER_NAME と NAME という2つがその順番に焼かれていたとします。NAME のクッキーを食べようとして、indexOf ( ) で先頭位置を割り出そうとしたとき、最初にあった USER_NAME にヒットしてしまうという奥の深い可能性を考慮して、内部的にクッキー名の先頭に「@」をつけて、内部的に @NAME を検索するため、@USER_NAME には誤ヒットしないというスーパーアイデア(苦笑)です。 また、@USER_NAME と @USER_NAME1 という焼き方も考えられるので、クッキー名の最後には「=」も内部的につけて「@USER_NAME=」を indexOf ( ) で検索するというミラクル仕様(当たり前か)です。 注意:上記 document.cookie の内容で @USER_NAME と @USER_COUNTER 以外のクッキー名は今回のステップとは関係のない別ページのクッキーデータです。今回の仕様に沿っていません。 クッキーの最後に「;」をわざと追加しています。 myStr = document.cookie + ";" ; クッキーの項目はセミコロンで区切られています。このセミコロンを項目の最終位置にしています。クッキーの最後の項目にはセミコロンがついていないのでわざとつけて、indexOf() しやすくしています。 クッキーの焼き方ですが、項目をまとめて焼くこともできますが1つずつ焼くことも出来ます。1つずつ焼いたときは追加になります。既にその項目(クッキー名)があれば、新しい値に更新されます。 また、焼くときには有効期限(【俗語:賞味期間】)を追記します。人様のパソコンに一生クッキーを残すのは申し訳ないし腐って食中毒になったら大変なので期間を設けています。 クッキーを食べるたびにこんな調理をするのはめんどくさすぎるという方のために、汎用的関数mySetCookie() と myGetCookie() を作りました。 mySetCookie( ) は1つのクッキーを焼く関数で、パラメータは次の通りです。 【書式】 mySetCookie ( クッキー名 , 値 , 有効期限日数 ) 【例】 mySetCookie ( "USER_NAME" , "Tatsuya" , 365 ) ; myGetCookie( ) は1つのクッキーを食べる関数で、パラメータと戻り値は次の通りです。 【書式】 変数 = myGetCookie ( クッキー名 ) 【例】 myCount = myGetCookie ( "USER_COUNTER" ) ; 戻り値が null であれば、該当なしです。 また、値は文字として戻ってくるので、数値がほしければ、 myCount = eval ( myGetCookie ( "USER_COUNTER" ) ) ; と、eval() 関数を使って数値にします。 なお、1つずつクッキーを焼くため、クッキーをアクセスするたびに警告を出すように設定している人がページを訪れた場合、ウザいサイト ナンバー1 間違いなしです。 では、さらば! | 
| Q&A 1[Q] 名前を変更できるようにしたいのですが [A] 以下のスクリプトとボタンを設置してください <script type="text/javascript"><!--
function mySetName(){
  myU = prompt("名前を変更します",myUser);
  if (myU != null){ // 名前入力→キャンセルしなかった
    mySetCookie("USER_NAME",myU,365); // 名前を変更
    // 名前変更時はカウントしない苦肉の策
    myCount = myCount - 1;                   // カウンターを..
    mySetCookie("USER_COUNTER",myCount,365); // 戻して..
    location.reload();                       // 再表示   
  }
}
// --></script>
<form> お名前の変更はこちら→
<input type="button" value="変更" onclick="mySetName()">
</form> | 
| Q&A 2[Q] 1日1回だけカウントしたいのですが [A] 日付も焼いて確認します <script type="text/javascript"><!--
myD       = new Date();
myYear    = myD.getYear();
myYear4   = (myYear < 2000) ? myYear+1900 : myYear;
myMonth   = myD.getMonth() + 1;
myDate    = myD.getDate();
myYMD     = myYear4 + "/" + myMonth + "/" + myDate;
myUser = myGetCookie("USER_NAME");      // 名前読込
if (myUser == null){                    // 初めての訪問
   myUser = prompt("はじめまして! 名前を教えてください!","匿名");
   if (myUser == null){                 // 名前入力→キャンセルした
      myUser = "匿名";
   }
   mySetCookie("USER_NAME",myUser,365); // 名前保存
   mySetCookie("USER_DATE",myYMD,365);  // 訪問日保存
   myLast = myYMD;                      // 前回訪問日とする
   myCount = 1;                         // 訪問回数→初回
}else{                                          // 2度以上の訪問
   myCount = eval(myGetCookie("USER_COUNTER")); // カウンター読込
   myLast = myGetCookie("USER_DATE");           // 前回訪問日読込
}
if (myYMD != myLast){                       // 前回訪問日が今日じゃない
   myCount = myCount + 1;                   // カウンター加算
   mySetCookie("USER_COUNTER",myCount,365); // カウンター更新
   mySetCookie("USER_NAME",myUser,365);     // 名前の賞味期間を更新
   mySetCookie("USER_DATE",myYMD,365);      // 前回訪問日更新
}
document.write(myUser,"さん、",myCount,"度目の訪問ですね!");
// --></script>[Q] Q&Aその1 と組み合わせると、名前を変更すると、訪問回数が1下がってしまいます。 [A] 本題のサンプルは表示毎に訪問回数をカウントしています。Q&Aその1は、名前を変えたらリロードします。その時に、名前変更時は訪問回数をカウントしたくないので、コメントにもあるように、前もって訪問回数を1下げておき、本題サンプルが1上げて、プラスマイナス・ゼロという苦肉の策をとっています。よって、Q&Aその2と組み合わせるときは、Q&Aその1の訪問回数を1下げる部分を削除してください。     // 名前変更時はカウントしない苦肉の策
    myCount = myCount - 1;                   // カウンターを..
    mySetCookie("USER_COUNTER",myCount,365); // 戻して.. |