

**localStorageの保存の仕方を教えてください**

todoリストを作っています。

[code]

    <div id="today" class="tab-pane active">
                        <p>今日やること</p>
                        <div class="task-wrapper">
                            <span style="white-space: nowrap;" class="add-task-wrapper">
                                    <form id="form-a" class="add-task-wrappers">
                                        <input type="button" value="+" class="add-mark" id="plus-a">
                                        <input style="background-color:rgb(206, 214, 95)"placeholder="今日やることを追加してください" class="add-task" id="WantToAdda"  value="" >
                                    </form>
                            </span>
                            <ul id="todolist-a" class="todolist">
                                <!-- todolistを追加 -->
                            </ul>
                        </div>
                    </div>
    
[/code]

[code]

    let plusa=document.getElementById("plus-a");
    plusa.addEventListener('click',function(){
        let newTask = document.getElementById("WantToAdda").value;
        let lists = document.getElementById("todolist-a");
        if(newTask!=""){
        lists.insertAdjacentHTML("afterbegin","<li><p>◉</p>"+newTask+"<i class='far fa-trash-alt gomi'></i></li>");
    
[/code]

inputタグに入れた文字をtodolistとしてのなかに追加していきます。  
`<li><p>◉</p>*文字列(タスク)*<i class="far fa-trash-alt gomi"></i></li>`  
という形で追加していきます。  

の◉もクリックでマークが変わるようになっています。  
マークとタスクをセットで保存したいのですが、どのようにしたらいいのでしょうか？  
削除機能もあるので、削除もできるようにします。ページを読み込みなおしたときに、タスクとマークがそのままになるようにしたいです。

> 配列にしてJSON.stringify()でlocalstorageに保存  
>  localstorageから取り出して `JSON.parse()` で配列に戻してJavaScriptで追記・編集・削除などを行ってまた保存する際に
> `JSON.stringify()` の繰り返し。

と教えてもらったのですが、わかりません。どのタイミングで何をどのように保存するのでしょうか。


CC BY-SA 4.0
2019-10-29T23:51:00.390
60096
2020-06-25T05:06:55.693
2019-10-30T00:46:49.403
3060
36408
question
javascript html
localStorageでうまく保存できません。助けてください


乱暴な方法からまともな方法まで3通り紹介します。

## A. innerHTMLをそのまま保存・復帰する

  * TODOリストが更新されたとき(提示されているclickハンドラ内や、◉を変更したとき、データを削除したとき)、`todolist-a`要素の `innerHTML`を`localStorage`に保存。
  * ページロード時に、`localStorage`内にデータがあれば、そのデータを`todolist-a`要素の`innerHTML`にセット。

提示されているコードに数行足せば実現できますが、まったくもって雑な方法であり、リスト内のマークアップを変更することが難しくなります。ふつうはこの手段は取らないでしょう。

## B. HTMLを一次情報とし、必要なときだけデータ配列を生成する

  * TODOリストが更新されたとき、`todolist-a`内のDOM構造を調べて、以下のような配列を構築し、`JSON.stringify()`して`localStorage`に保存

[code]

    [
      {status:'◉', task:'家賃を払う'},
      {status:'◉', task:'〇〇さんのメールに返答する'},
    ]
    
[/code]

  * ページロード時に、`localStorage`内にデータがあれば`JSON.parse()`で配列データを復帰して、その配列データから`todolist-a`内のマークアップを再構築

## C. 配列を一次情報とする

  * 上記のような配列を保存する都度構築するのではなく、常に保持しておく。
  * TODO項目に変更があった場合は、該当する配列要素を見つけてそこだけを更新し、`JSON.stringify()`と`localStorage`で保存する。例: 3番目の<li>のゴミ箱アイコンが押されたら、配列の3番目の項目を削除する
  * ページロード時にすることは同じ

* * *

Cが一番マトモだと思いますが、データ量が少ないならBで十分だと思います。  
JavaScriptのデータとHTML表現の対応付けを簡単にできるようにするライブラリが世の中にはたくさんあります。


CC BY-SA 4.0
2019-10-30T06:38:48.057
60116
2019-10-31T01:23:07.540
2019-10-31T01:23:07.540
3475
3475
60096
answer


このようにできます。

[code]

    var data;
    
    // データを読みます
    data = JSON.parse(localStorage.save_data);
    
    // データを読む前にあったのか分岐で掌理します
    var save_data = localStorage.save_data;
    if (save_data) {
        data = JSON.parse(localStorage.save_data);
        // data によって、アプリを書いてるとか
        ...
    } else {
        data = [];
    }
    
    // データを localStorage に保存します
    localStorage.save_data = JSON.stringify(data);
    
[/code]

適当にデモを作ってみた： <https://jsfiddle.net/jLcqbdfk/3/> (コードスニペットの機能は CORS のせいで
localStorage 使えないので別サイトにいます)


CC BY-SA 4.0
2019-10-30T18:10:44.743
60147
2019-10-30T18:10:44.743
5882
60096
answer