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

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

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

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

Q&A

解決済

4回答

10871閲覧

JavaScriptでデータの保存

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

0グッド

1クリップ

投稿2016/07/02 09:09

JavaScript

1<div id="dayCount"></div> 2<script> 3var count1 = 0; 4counter(); 5 6function counter(){ 7 count1 += 1; 8 save(); 9} 10 11window.onload = function(){ 12 var count_load = localStorage.getItem("count1"); 13 document.getElementById("dayCount").innerHTML = count_load; 14} 15 16function save(){ 17 localStorage.setItem("count1" , document.getElementById("dayCount").innerHTML); 18} 19</script>

というコードなのですがページを更新してもcount1は保存されているのですが、更新後にボタンを押すとまた一からカウントされます
どうすれば続きからカウントしてくれますか?

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

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

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

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

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

sounisi5011

2016/07/02 09:57 編集

「ボタン」に該当するコードを見つけられません。コード全体を質問本文に書いてください。または、「ボタン」が何を意味するのか、分かるように書いてください。
guest

回答4

0

いい加減な読み方をしていて、いい加減なことを書いてしまい、追記追記で訂正しましたが、煩雑になったので削除しました。元のいい加減な回答が知りたい方は編集履歴をご覧ください。

本題

他の部分をばっさり削除してこれではダメですか?

JavaScript

1window.onload = function(){ 2 var count_load = localStorage.getItem("count1"); 3 document.getElementById("dayCount").innerHTML = count_load; 4 localStorage.setItem("count1", count_load + 1); 5}

投稿2016/07/02 10:26

編集2016/07/02 10:40
Zuishin

総合スコア28660

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

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

harashow1701

2016/07/02 23:44

ローカルストレージのcount1に値が何も保存されてない場合に読み込んだらどうなるの?何もない時用に初期値0で返すようにしないといけないのかな。
Zuishin

2016/07/02 23:55

そこが問題になるのは最初の一回だけなので、あらかじめ初期化しておけばいいんじゃないでしょうか? もちろん無い場合は 0 を設定するようコーディングしても結構です。ただし初回以外毎回無用なチェックをする事になります。
guest

0

ベストアンサー

JavaScript

1var count1 = 0; 2counter(); 3 4function counter(){ 5 count1 += 1; 6 save(); 7} 8 9window.onload = function(){ 10 var count_load = localStorage.getItem("count1"); 11 document.getElementById("dayCount").innerHTML = count_load; 12} 13 14function save(){ 15 localStorage.setItem("count1" , document.getElementById("dayCount").innerHTML); 16}

このコードを見る限りでは、以下の問題が挙げられます。

  • 変数count1が、初期化とカウントアップ以外で使用されていない。

ページを読み込んだ後、このコードは以下の順に動作します。

  1. var count1 = 0;を実行。
    変数count1の値に0を代入して初期化。
  2. counter();を実行。
    counter関数を呼び出す。
  3. count1 += 1;を実行。
    変数count1の値をカウントアップし、1に変更。
  4. save();を実行。
    save関数を呼び出す。
  5. localStorage.setItem("count1" , document.getElementById("dayCount").innerHTML);を実行。
    <div id="dayCount"></div>内のinnerHTMLの値(この時点では空文字列となる値)を、LocalStorageにcount1キーと関連付けて保存。
  6. window.onloadに関数を設定。
  7. ページ読み込みが完了し、window.onloadに設定した関数が実行される。
  8. var count_load = localStorage.getItem("count1");を実行。
    LocalStorageにcount1キーと関連付けて保存した値(空文字列)を取り出し、変数count_loadに代入。
  9. document.getElementById("dayCount").innerHTML = count_load;を実行。
    <div id="dayCount"></div>内のinnerHTMLの値を、変数count_loadの値(空文字列)に変更。

このうち、カウントに使用されている(と思われる)変数count1は、1番目と3番目の処理、
コードで言えば、以下の箇所のみで使用されているように見えます。

JavaScript

1var count1 = 0;

JavaScript

1 count1 += 1;

値を0に初期化した後、カウントアップして1にしている。ただそれだけです。
「この変数の値がLocalStorageに保存される」事がこのコードの要件(本来求める動作)だと考えられますが、このコードでLocalStorageに保存されているのは、id属性にdayCountが指定された要素(<div id="dayCount"></div>)内の「innerHTMLの値」だけです。
そしてこの「innerHTMLの値」の空文字列をLocalStorageに保存してから、再度取り出し、
再びinnerHTMLへと設定しなおしています。
が、この間にこの空文字列がカウントの値へ変更されてはいません。

これが、カウントアップされない原因です。そもそもカウントの値が保存されていません。
実際、以下の実際に書いてみたサンプルでもカウントアップどころか、何も表示されない状態になっています。

※空文字列は0文字の文字列データのため、何も表示されない。

LocalStorageを利用したカウントアップのサンプルコード


解決するには、変数count1の値をLocalStorageに保存するようにしましょう。

まず、変数count1を初期化するときに、0をそのまま代入するのではなく、LocalStorageから読みだした値を変数count1に代入するようにします。
ただし、LocalStorageにカウントの値が無い場合には、代わりに0を代入するようにします。
このあたりの処理は、「LocalStorageからカウントの値を読み出し、カウントの数値か0を返す」関数としてひとまとめにしてしまったほうが良いと思います。
ここでは、これらの処理をload関数にまとめることにします。

load関数で取得したカウントの値を変数count1に代入し、それから変数count1をカウントアップします。
そして、カウントアップした値をLocalStorageに保存して、innerHTMLの値も更新します。
この時、innerHTMLの値をLocalStorageに保存するような処理にしては駄目です。
LocalStorageに保存するのは、変数count1の値です。
そしてinnerHTMLは、変数count1の値を書き込むだけにしましょう。

以上の処理を、全て「window.onloadに設定する関数」の中で書きます
window.onloadに指定された関数」は非同期処理されるため、外側のコードが最後まで実行された後に呼び出されてしまいます。
このため、外側と内側とでコードの実行タイミングが異なるようになってしまいます。
これを混同するとえらく面倒になるうえに、殆どの場合は期待した動作をしてくれなくなるので、
全ての処理は「window.onloadに設定する関数」の中に書いてしまいましょう。

ただし、関数定義は除きます。
関数定義はあくまで関数を定義するだけであって、その場で動作するコードではないため、window.onloadの外に書いても問題はありません。

※関数定義を内側に書いても間違いではありません。動作します。このあたりは、見やすさや好みの差だと私は思います。この例では見やすさのため、外側に書くことにします。

以上の修正案を具体的なコードにしたものが以下になります。

JavaScript

1window.onload = function() { 2 /** 3 * @type {number} 4 * 5 * LocalStorageから、カウントの値を読み込む。 6 */ 7 var count1 = load(); 8 9 /* カウントアップ */ 10 count1 += 1; 11 12 /* カウントアップした値を保存 */ 13 save(count1); 14 15 /* カウントを表示 */ 16 document.getElementById("dayCount").innerHTML = count1; 17}; 18 19/** 20 * LocalStorageに保存しておいたカウントの値を数値で取り出す。 21 * 22 * LocalStorageに値が保存されていない場合、代わりに0を返す。 23 * また、値が正の整数以外の場合も0を返す。 24 * (LocalStorageの値は簡単に改変されてしまうため、その対策) 25 * 26 * @return {number} カウントを示す数値 27 */ 28function load() { 29 /** 30 * @type {string|null} 31 * 32 * LocalStorageに保存されていた文字列値を取り出す。 33 * LocalStorageに値が保存されていない場合、代わりにnullが返される。 34 */ 35 var count_data = localStorage.getItem("count1"); 36 37 /** 38 * @type {number} 39 * 40 * 保存されていた値を数値に変換。nullの場合は0になる。 41 * また、数値に変換できない文字列値はNaN(非数)という特殊な数値になる。 42 */ 43 var count = Number(count_data); 44 45 /* 46 * 値が適切な数値(0とNaN以外の数値であり、かつ、1以上の数値であり、かつ、整数値である)かどうか判定。 47 * 条件に合致した場合は数値をそのまま返し、それ以外の場合は0を返す。 48 */ 49 if ( 50 count && // 0とNaN以外の数値か判定 51 1 <= count && // 1以上の数値か判定 52 Math.floor(count) === count // 整数値か判定 53 ) { 54 return count; 55 } else { 56 return 0; 57 } 58} 59 60/** 61 * LocalStorageにカウントの値を保存する 62 * 63 * @param {number} count LocalStorageに保存するカウントの値 64 */ 65function save(count) { 66 localStorage.setItem("count1", count); 67}

動作サンプル:LocalStorageを利用したカウントアップのサンプルコード

投稿2016/07/02 11:44

編集2016/07/03 07:10
sounisi5011

総合スコア697

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

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

harashow1701

2016/07/02 23:41

この回答を書くのに費やした時間が気になります!!
sounisi5011

2016/07/03 04:11

> 回答を書くのに費やした時間 多分1時間未満…いや、2時間未満です
harashow1701

2016/07/03 07:44

すごい。。時間単価5000円なら一万円の価値。
guest

0

ロードするたびに下記が実行されているので、0から計算が始まってしまっています。

var count1 = 0;

なので、「ロード時にまずローカルストレージを参照し、値が保存されていなければ0を代入する」という形に改める必要があります。
また、ローカルストレージには文字列として保存されているので、数値として計算するために型変換も行います。

javascript

1function counter(count){ 2 count += 1; 3 save(count); 4}; 5 6function save(count){ 7 localStorage.setItem("count1" , count); 8}; 9 10window.onload = function(){ 11 var count_load = parseInt(localStorage.getItem("count1") || 0); 12 document.getElementById("dayCount").innerHTML = count_load; 13 14 counter(count_load); 15};

以上のコードでいかがでしょうか?

補足

元々のコードではローカルストレージ上に正しい値が保存できていない可能性がありますので、
一旦下記のように値を消去してからお試しください。

localStorage.clear("count1");

投稿2016/07/02 11:27

編集2016/07/02 11:45
yamato_hikawa

総合スコア2092

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

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

sounisi5011

2016/07/02 11:52 編集

parseInt関数の第二引数は、きちんと「10」に指定したほうが良いです。古いブラウザでは8進数と解釈され、予期しない動作を引き起こす可能性があります。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/parseInt > 第1引数のstringが「0」で始まるときは、第2引数のradixは8(8進法)または10(10進法)とされます。厳密には、基数がどちらになるかは実装によります。ECMAScript 5 の仕様では10(10進法)です。ただし、まだすべてのブラウザがサポートしている訳ではありません。したがって、parseInt()関数を使うとき基数は必ず与えてください。 http://liginc.co.jp/web/js/31018 > 何でこうなったかっていうと、parseInt()は第二引数で基数を設定できるんですよね。 > ちゃんとここに来るのは10進数なんだよって教えてあげないと、0から始まる文字は8進数と解釈されてしまうようです。 最も、今の時代、ES5に非対応のブラウザ(この問題を引き起こすブラウザ。例えばIE8とか)がどれほど生き残っているのか疑問ではあるのですが… やらないよりはやったほうが良いと考えます。
guest

0

ちゃんとしたコードに直せばok

投稿2016/07/02 09:20

harashow1701

総合スコア854

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

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

sounisi5011

2016/07/02 09:37 編集

どこがどう「ちゃんと」していないコードなのか、その具体的な説明が必要だと考えます。
harashow1701

2016/07/02 23:42 編集

私もそう考えます。ま、毎回、カウント値をロードの度に0にしてたら、そりゃー、上手く行かんですわ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問