質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

jQueryプラグイン

jQueryの拡張機能。 様々な種類があり、その数は膨大です。公開済みのプラグインの他にも、自作することもできます。 jQueryで利用できるようにしておくだけで、導入およびカスタマイズが比較的容易に行なえます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

2431閲覧

jQueryのCookie保存において、以前のデータが上書きされてしまう問題について

christmas-tree

総合スコア12

Cookie

HTTPにおけるCookieとは、クライアントのウェブブラウザ上に保存された一時的なデータを指します。クライアント側のJavaScriptでも、サーバー側のHTTPヘッダーでもクッキーの読み書き・修正・削除が可能です。

jQueryプラグイン

jQueryの拡張機能。 様々な種類があり、その数は膨大です。公開済みのプラグインの他にも、自作することもできます。 jQueryで利用できるようにしておくだけで、導入およびカスタマイズが比較的容易に行なえます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/01/05 05:44

編集2019/01/05 06:21

お世話になっております。
以前の質問が解決し、新たに別問題が生じたために質問させて頂きます。
宜しくお願い致します。

###実現したいこと

こちらのCodePenのサンプルでは、画像(.Target)クリックでCookieに内容が保存されるようになっています。
https://codepen.io/anon/pen/maXwmx

しかし、2つの画像の片方をクリックすると、もう片方のCookieが上書きされてしまうというのが今回の問題です。

たとえば、1回目に「ケリーのバッグ」をクリックしても、2回目に「エレンのシューズ」をクリックすると、2つとも「エレンのシューズ」で上書きされてしまい、「ケリーのバッグ」が消えてしまいます。

###コード
CodePenのコードがこちらです。
上書きされないようにするために修正すべき点をご教授願えませんでしょうか。

html

1<h1>クリスマスプレゼント</h1> 2<div class="list"> 3 <div class="userdata"> 4 <p> 5 <a href="http://example.com/girls/kelly"> 6 <span class="name1">ケリー</span>&nbsp; 7 <span class="name2">@kelly</span> 8 </a> 9 </p> 10 </div> 11 <div data-item="バッグ" data-urltype="http://example.net/product/123" class="Target"> 12 <img src="http://urx.red/OUBm" alt=""> 13 </div> 14</div> 15 16<div class="list"> 17 <div class="userdata"> 18 <p> 19 <a href="http://example.com/girls/kelly"> 20 <span class="name1">エレン</span>&nbsp; 21 <span class="name2">@ellen</span> 22 </a> 23 </p> 24 </div> 25 <div data-item="シューズ" data-urltype="http://example.net/product/456" class="Target"> 26 <img src="http://ur0.link/P03G" alt=""> 27 </div> 28</div> 29 30<div id="options_output"> 31 <p>ここにクリックした内容のCookieが出力される。</p> 32</div>

jquery

1$(function() { 2 var hers_length = 5; 3 4 // クッキー登録 5 $('.Target').on('click', function() { 6 7 var user = $(this).closest('.list').find('.userdata a').html(); 8 var title = $('h1').text(); 9 var urltype = $(this).attr('data-urltype'); 10 var item = $(this).attr('data-item'); 11 12 var params = JSON.parse($.cookie('options') || "{}"); 13 if (typeof params !== "object" || typeof params.title == "undefined") { 14 params = { 15 user: [], 16 title: [], 17 urltype: [], 18 item: [] 19 }; 20 } 21 22 params.user.push(user); 23 params.title.push(title); 24 params.urltype.push(urltype); 25 params.item.push(item); 26 27 if (params.user.length > hers_length) { 28 params.user.shift(); 29 params.title.shift(); 30 params.urltype.shift(); 31 params.item.shift(); 32 } 33 34 var ul = $('<ul>'); 35 params.user.forEach(function() { 36 var output = '<p>' + user + 'が<span>' + title + '</span>に欲しいのは<span data-urltype=' + urltype + '">' + item + '</span>です。'; 37 $('<li>').append(output).appendTo(ul); 38 }) 39 40 $('#options_output').html(ul); 41 $.cookie('options', JSON.stringify(params)); 42 43 }); 44 45 var cookie = $.cookie('options'); 46 if (cookie) { 47 var params = JSON.parse(cookie); 48 var ul = $('<ul>'); 49 params.user.forEach(function(user, i) { 50 var output = '<p>' + user + 'が<span>' + params.title[i] + '</span>に欲しいのは<span data-urltype=' + params.urltype[i] + 51 '">' + params.item[i] + '</span>です。'; 52 $('<li>').append(output).appendTo(ul); 53 }) 54 $('#options_output').html(ul); 55 } 56}); 57

###補足情報
jQueryは2.1.3です。
cookieの保存には、jQueryプラグイン「jquery.cookie.js」を使用しています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

しかし、2つの画像の片方をクリックすると、もう片方のCookieが上書きされてしまうというのが今回の問題です。

上書きされているのではなく、正しく出力できていないだけです。クリック時の表示を行うparams.user.forEachの中ですべてもとの変数で書き出して配列を見ていない、かつ配列の個数分書き出してしまっているので、同じものが回数分だけ連なってしまいます。


以下、完全に間違いでした

Cookieは、ドメインごとに同じキーのものは1つしか保持できませんので、同じキーで複数回書き込めば上書きされます。

なので、「キー自体を変える」などの対応が必要となります。

投稿2019/01/05 05:48

編集2019/01/05 06:32
maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

christmas-tree

2019/01/05 06:12

「クリック時の内容」を「それまでに保存された内容」と追加して、新たに保存する。このようなことはできないんですか!?
maisumakun

2019/01/05 06:32

すみません、まったく別件でした(全面的に回答内容を書き換えています)。
christmas-tree

2019/01/06 08:02 編集

回答のご修正ありがとうございます。
guest

0

ベストアンサー

プログラムの流れを見直してみてください。

1回目、ケリーをクリック

js

1 user = '<span class="name1">ケリー...'; 2 title = 'クリスマスプレゼント'; 3 urltype = 'http://example.net/product/123'; 4 item = 'バッグ'; 5 params = { 6 user: ['<span class="name1">ケリー...'], 7 title: ['クリスマスプレゼント'], 8 urltype: ['http://example.net/product/123'], 9 item: ['バッグ'] 10 };

となります。
さて、この状態で

js

1 params.user.forEach(function() { 2 var output = '<p>' + user + 'が<span>' + title + '</span>に欲しいのは<span data-urltype=' + urltype + '">' + item + '</span>です。'; 3 $('<li>').append(output).appendTo(ul); 4 })

↑の部分はループを1周するのですが、その場合、user変数には何が入っているでしょう?
そうですね。'<span class="name1">ケリー...'です。

2回目、エレンをクリック

js

1 user = '<span class="name1">エレン...'; 2 title = 'クリスマスプレゼント'; 3 urltype = 'http://example.net/product/456'; 4 item = 'シューズ'; 5 params = { 6 user: ['<span class="name1">ケリー...','<span class="name1">エレン...'], 7 title: ['クリスマスプレゼント','クリスマスプレゼント'], 8 urltype: ['http://example.net/product/123','http://example.net/product/456'], 9 item: ['バッグ','シューズ'] 10 };

となります。
さて、この状態で

js

1 params.user.forEach(function() { 2 var output = '<p>' + user + 'が<span>' + title + '</span>に欲しいのは<span data-urltype=' + urltype + '">' + item + '</span>です。'; 3 $('<li>').append(output).appendTo(ul); 4 })

↑の部分はループを2周するのですが、1周目の場合、user変数には何が入っているでしょう?
当然、'<span class="name1">エレン...'です。
では、2周目の場合は?
もちろん、'<span class="name1">エレン...'です。
user変数に代入をするコードが1か所しかありませんから、当然、内容はずっと同じです。せっかくparams変数にクッキーの内容を納めてあるのですが、そちらを見に行っていません。



解決方法ですが、2つあると思います。
0. params変数を配列にする
0. forEachのコールバック第2引数に配列の添え字が入っているので、params.user[i]のように配列の要素を参照する。

ふたつ目はあまりよくないと思います。

投稿2019/01/05 07:08

Lhankor_Mhy

総合スコア35860

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

christmas-tree

2019/01/05 07:41

ありがとうございます。 userの数だけforeadhしてるのは問題ないんだと思いますが、その中のvar outputで定義した各値が、どうして、同じ値になるのですか?? レベルが違うとこうも分からないものですね。優しく教えて下さっているのだと思いますが、まるでわかりません。user変数に代入をするコードが1か所しかないから、内容が同じになるというのも分からなければ、params変数を配列にするなどの解決方法も分かりませんでした……
Lhankor_Mhy

2019/01/05 08:07

なるほど。 ちなみに、 var x = 1; for (var i=0; i<2; i++) {  alert(x); } を実行すると、「1」「1」と表示されるのですが、それは分かりますか?
christmas-tree

2019/01/05 08:19

はい、ぎりぎりで分かります。 まずxを1と定義して、2未満まで1をカウントアップして、アラートする。ですね。
Lhankor_Mhy

2019/01/05 08:24

同様に var x = 1; for (var i=0; i<2; i++) {  alert(i+'回目は'+x); } ↑は「0回目は1」「1回目は1」とアラートされます。
Lhankor_Mhy

2019/01/05 08:25

そして、 var x = 1; var i = {  x:0 } for (i.x=0; i.x<2; i.x++) {  alert(i.x+'回目は'+x); } ↑も「0回目は1」「1回目は1」とアラートされます。
Lhankor_Mhy

2019/01/05 08:27

ついて来れてますか? さて、 var user = 1; var params = {  user:0 } for (params.user=0; params.user<2; params.user++) {  alert( params.user + '回目は' + user ); } ↑も「0回目は1」「1回目は1」とアラートされるんです。 ここまでは大丈夫ですか?
christmas-tree

2019/01/05 08:35 編集

>17:24 なるほど、ループの中で、「x」はカウントアップされ、「i」は、回数を示してくれるんですね。 >17:27 わからないです。 var params = {  user:0 } では何をしているんでしょうか? 「配列params」に「user」というキーを作りそのキーの値が「0」?でしょうか? forの部分もわからないですね。
Lhankor_Mhy

2019/01/05 08:36

>17:25 >17:27 よく見てください。これは、i を params、x を user と名前を変えただけです。
christmas-tree

2019/01/05 08:50

失礼しました。17:25と17:27はいずれもわからないです。17:24までわかります。コメント編集致しました。
christmas-tree

2019/01/05 09:43 編集

なるほど、なんとなくわかりました。ありがとうございます。 ただ、paramsというオブジェクトの中にuserというプロパティを作成するときに「0」を代入しているのに、それ以前に「1」を代入しなければならない理由がちょっとわからないですが、、 var user = 1; // なぜここで「1」を代入するのかピンときません。 var params = {  user:0 // ここで「0」を代入するだけで良さそうな気がします。 } でもこれは大した点ではなさそうなので、とりあえず、ぜひ、続けて頂きたいです。 いつもでも結構です。どうぞお手すきの折にまた宜しくお願い致します。
Lhankor_Mhy

2019/01/05 09:47

なるほど。 user と params.user は、全く別のものである、というのは理解されていますか? つまり、 var user = 1; // なぜここで「1」を代入するのかピンときません。 var params = {  user:0 // ここで「0」を代入するだけで良さそうな気がします。 } と var x = 1; // なぜここで「1」を代入するのかピンときません。 var params = {  user:0 // ここで「0」を代入するだけで良さそうな気がします。 } は、同じ意味を持ちます。
christmas-tree

2019/01/05 10:19 編集

はい、それらがいずれもわかりませんでした。 でも、user と params.user は、全く別のものなんですね?なるほど、失礼致しました。 var test = 1; var params = {  user:0 } for (params.user=0; params.user<2; params.user++) {  alert( params.user + '回目は' + test ); } でもいいわけですね。
Lhankor_Mhy

2019/01/05 10:21 編集

そうなんです。 なので、 params.user.forEach(function() {  var output = '<p>' + user //←これ と、 params = {  user: [], //←これ も、別物なんです。 だから、同じものが何回も出てしまうんです。
christmas-tree

2019/01/05 12:35

では、こちらで出来るはずではないのでしょうか? var output = '<p>' + params.user + 'が<span>' + params.title + '</span>に欲しいのは<span data-urltype=' + params.urltype + '">' + params.item + '</span>です。';
Lhankor_Mhy

2019/01/05 12:49

params.user は配列なんです。 params = {  user: [], //←これ この、[] は配列の初期化をするためのものなんです。 なので、params.user[0] のように添え字をつけて参照する必要があります。
christmas-tree

2019/01/06 06:17

なるほど、できました。長らくお付き合い頂き大変感謝致します。こちらでいかがでしょうか? params.user.forEach(function(user, i) { var output = '<p>' + params.user[i] + 'が<span>' + params.title[i] + '</span>に欲しいのは<span data-urltype=' + params.urltype[i] + '">' + params.item[i] + '</span>です。'; $('<li>').append(output).appendTo(ul); }) 最後にもしよろしければ教えてください。この解決方法はご回答2として「あまりよくない」と仰ってますが、それはなぜですか?
Lhankor_Mhy

2019/01/07 00:59

素晴らしいですね。ご解決されてなによりです。 「あまりよくない」についてなのですが。 現状のデータは、user[i] と title[i] が同じ系列のデータ、という構造だと思います。 これは、たとえば住所録で「名前の部」「住所の部」「電話番号の部」と分かれていて、それぞれn番目のデータが同じ人のデータだよ、というわかりにくい感じだと思います。 個人的な好みですが、直観的ではないと思います。
christmas-tree

2019/02/09 18:16

大変申し訳ございません。ご返信が遅くなりました。なるほど、よくわかりました。最後までご丁寧に教えて頂いたこと、心より感謝申し上げます。どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問