の形で呼ぶ。
//
// anchor_idはフレームを使う場合最低限各フレームごとに設定。お互い他のフレームを書換えたときにへんな干渉をさけるため。
// その他ページの種別毎などで変えてもよいが、あまり小分けにするとcookieが増える。
// 同じanchor_idで保存されるcookieは1セットのみ。でも単独ページ表示のサイトなら概ねこれで充分。
anchor_id = "anc_main";
noanchor = false; // bodyにanchorをしかけたときなど場合によって一時無効にするためのフラグ。
// アンカーの記憶。
function anchor_save(object_id, page_id) {
if(noanchor) { anchor_erase(); return; }
get_scroll();
setcookie(anchor_id+"_pid", page_id, 0);
setcookie(anchor_id+"_st", scroll_top, 0);
setcookie(anchor_id+"_sl", scroll_left, 0);
if(object_id) {
object_top = scroll_top + get_object_top(object_id);
object_left = scroll_left + get_object_left(object_id);
setcookie(anchor_id+"_oid", object_id, 0);
setcookie(anchor_id+"_ot", object_top, 0);
setcookie(anchor_id+"_ol", object_left, 0);
} else {
setcookie(anchor_id+"_oid", "", -1);
setcookie(anchor_id+"_ot", "", -1);
setcookie(anchor_id+"_ol", "", -1);
}
}
// アンカーの適用。
function anchor_apply(page_id) {
if((saved_page_id = getcookie(anchor_id+"_pid")) && page_id != saved_page_id) { return; }
get_scroll();
if((anchor_st = getcookie(anchor_id+"_st")) != "" && (anchor_sl = getcookie(anchor_id+"_sl")) != "") {
anchor_st = parseInt(anchor_st);
anchor_sl = parseInt(anchor_sl);
} else {
anchor_st = scroll_top;
anchor_sl = scroll_left;
}
if((object_id = getcookie(anchor_id+"_oid"))
&& (anchor_ot = getcookie(anchor_id+"_ot")) != ""
&& (anchor_ol = getcookie(anchor_id+"_ol")) != "") {
offset_top = (scroll_top + get_object_top(object_id)) - parseInt(anchor_ot);
offset_left = (scroll_left + get_object_left(object_id)) - parseInt(anchor_ol);
} else {
offset_top = offset_left = 0;
}
window.scrollTo(anchor_sl + offset_left, anchor_st + offset_top);
}
// アンカー消去。あえてとっておく必要がなければanchor_apply()後すぐ消去が望ましい。
function anchor_erase() {
setcookie(anchor_id+"_pid", "", -1);
setcookie(anchor_id+"_st", "", -1);
setcookie(anchor_id+"_sl", "", -1);
setcookie(anchor_id+"_oid", "", -1);
setcookie(anchor_id+"_ot", "", -1);
setcookie(anchor_id+"_ol", "", -1);
}
//-->
倉金家ホームページ
趣味の部屋/ホームページ余話
javascriptによるCookie取得関数のまちがい |
|
|
2011年9月28日 |
2011年11月28日 更新 |
その昔参考書にあるjavascriptのコードを使ってクッキーの値が正しく取得できなかったことがあり原因を調べてコードを修正したのですが、最近この間違ったコードがまだ使われる可能性に気がつきました。 javascriptでクッキーを取得する場合ご注意ください。 |
|
|
その昔(10年も前の話)、ホームページの作成を始めた当時javascriptを使う必要があってその勉強のために参考書を買いました。技術評論社の「JavaScript XXXX辞典」。 素人の私にはわかりやすく、ずいぶん参考にさせていただきました。 その中にクッキーの取得方法が書いてありクッキー名をcookienameとすると cookiedata = document.cookie + ";"; cookienameorder = cookiename + "="; startpos = cookiedata.indexOf(cookienameorder); ここでstartposの値から該当する名前のものがあるかを判定し、あればさらに endpos = cookiedata.indexOf(";", startpos); readdata = cookiedata.substring(startpos + cookienameorder.length, endpos); といった具合でクッキーの値が取得できるというもの。 |
|
しばらくこれを使っていましたが、あるときページの動作がおかしいので調べたらクッキーがおかしな値になっているのに気がつきました。 必死に原因を探った結果、別に似たような名前のクッキーがあり、その値を取得しているのを発見。
具体的には、もともとcountというクッキー名を使っていたところに、持続性を維持したかったのでcountはそのままでhogecountやfugacountとかいった名前のクッキーを追加したのが原因でした。 すなわち上記のjavascriptでは名前にcountを含む、たまたま最初にリストされた別のクッキーの値を拾ってしまっていたのでした。 (どうしてそうなるのかは考えてみてね。)
|
この方式を使うならば、 cookiedata = " " + document.cookie + ";"; …" "の中は半角スペース。 cookienameorder = " " + cookiename + "="; startpos = cookiedata.indexOf(cookienameorder); とするのが正解で、そのように修正してからはちゃんと値が取得できるようになりました。 |
|
上記を使って実際にcookieの書込、読出関数を書くならば一例として、 <script type="text/javascript"><!-- cookie_head = "SITE1_"; // 同一ドメインに複数サイトあるときのサイト識別用。 function setcookie(cookiename, cookievalue, timelimit) { cookienameorder = cookie_head + cookiename + "="; if(timelimit) { lifetime = parseInt(timelimit.toString().match(/^[\+\-]?[0-9]*/)); if(lifetime != 0) { cookielife = new Date(); lifeunit = timelimit.toString().match(/[A-Za-z]*$/).toString(); if(lifeunit.match(/^min/i)) { lifetime *= 60; } // minutes else if(lifeunit.match(/^h/i)) { lifetime *= 60*60; } // hours else if(lifeunit.match(/^d/i)) { lifetime *= 60*60*24; } // days else if(lifeunit.match(/^w/i)) { lifetime *= 60*60*24*7; } // weeks else if(lifeunit.match(/^m/i)) { lifetime *= 60*60*24*31; } // months else if(lifeunit.match(/^y/i)) { lifetime *= 60*60*24*365; } // years else { lifetime *= 60*60*24; } // default unit: days cookielife.setTime(cookielife.getTime() + lifetime*1000); expiredate = cookielife.toGMTString(); document.cookie = cookienameorder + cookievalue + ";expires=" + expiredate+";"; } else { document.cookie = cookienameorder + cookievalue + ";"; } } else { document.cookie = cookienameorder + cookievalue + ";"; } } function getcookie(cookiename) { cookiedata = " "+document.cookie+";"; cookienameorder = " "+cookie_head+cookiename+"="; startpos = cookiedata.indexOf(cookienameorder); if(startpos >= 0) { endpos = cookiedata.indexOf(";", startpos); readdata = cookiedata.substring(startpos + cookienameorder.length, endpos); } else return false; return(readdata); } //--></script> |
|
...とまあ、すいぶん昔の話なのでこれはこれでいいとして、先日別のことで検索して調べていたら偶然このまちがった方法を掲載しているサイトを見つけたので、もしやほかにもと思い調べてみると他にもいくつかありました。(例の本の影響が大きいようで。)
思い当たる方は確認するようお薦めします。
とはいうものの、自分のずっと昔のページにはまだこの間違ったコードがそのまま残っているかもしれない...。(全部見直す元気なし。たぶん名前がダブってはいないだろうから、ま、いいか。)
|
(追記 2011年11月28日) 先日東京へ出て暇があったので本屋を覗いてjavascript関係の本もちょっと見てみたら、この間違った方法を記載している本が今だにありました。 ご注意を!
|
|
|