javascriptのLocalStorage を使ってお気に入り機能を自作してみた ③実装編-組み込み-

javascriptのLocalStorage を使ってお気に入り機能を自作してみた ③実装編-組み込み-

どうも7noteです。プラグインより多機能なお気に入り機能を作成。前回の続き

①準備編がまだの方はこちら
②実装編-基盤作り-がまだの方はこちら

wordpressで自作のお気に入り機能を使いたい人はこちら

実運用レベルで使ってみる(コピペで動くよ)

押したらお気に入りに追加。もう一度押したら削除されるように作ります。

完成イメージ

movie.gif
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>

<ul>
  <li no="1" class="add" onclick="addfav('1')"><span>♡</span>No:1 りんご</li>
  <li no="1" class="remove" onclick="removefav('1')"><span>♥</span>No:1 りんご</li>
  <li no="2" class="add" onclick="addfav('2')"><span>♡</span>No:2 みかん</li>
  <li no="2" class="remove" onclick="removefav('2')"><span>♥</span>No:2 みかん</li>
  <li no="3" class="add" onclick="addfav('3')"><span>♡</span>No:3 ばなな</li>
  <li no="3" class="remove" onclick="removefav('3')"><span>♥</span>No:3 ばなな</li>
</ul>

<style>
ul li.remove span {
  color: #F00;
}
</style>

<script>
/* 【解説Aパート】 "表示ソースの切り替え" */
function togleitem(oid,event){
    if(event == 'add'){
        // 未チェック(class="add")を非表示にして、チェック済(class="remove")を表示する
        $('li.add[no=' + oid + ']').hide();
        $('li.remove[no=' + oid + ']').show();
    } else if(event == 'remove'){
        // チェック済(class="remove")を非表示にして、未チェック(class="add")を表示する
        $('li.add[no=' + oid + ']').show();
        $('li.remove[no=' + oid + ']').hide();
    }
}


/* 【解説Bパート】 "ページロード時にローカルストレージの中をチェック" */
$(function(){
  $('ul .remove').hide();  // お気に入り中の表示は一時的に非表示に。

  // お気に入りリストに存在するか確認
  var key = 'お気に入りID';
  var getjson = localStorage.getItem(key);
  var oidlist = JSON.parse(getjson);
  if(oidlist != null){
    oidlist.forEach( function( oid ) {
      togleitem(oid,'add');
    });
  }

})  

/* 【解説Cパート】 "お気に入りに追加機能" */
function addfav(oid){

    var key = 'お気に入りID';                       // キーの名前を指定

    // ローカルストレージから値を取得
    var getjson = localStorage.getItem(key);
    var oidlist = JSON.parse(getjson);

    if(oidlist == null){
        // 初めて「お気に入りID」というキーがローカルストレージに登録される時の処理
        oidary = new Array(oid);
        var setjson = JSON.stringify(oidary);
        localStorage.setItem(key, setjson);

        togleitem(oid,'add');

    } else {
        // 既に「お気に入りID」というキーが存在する時
        if(oidlist.indexOf(oid) == -1){
            // 且つ、まだお気に入りIDに登録されていない時
            oidlist.push(oid);
            var setjson = JSON.stringify(oidlist);
            localStorage.setItem(key, setjson);

            togleitem(oid,'add');
        }
    }
}

/* 【解説Dパート】 "お気に入りから削除機能" */
function removefav(oid){

    var key = 'お気に入りID';                       // キーの名前を指定

    // ローカルストレージから値を取得
    var getjson = localStorage.getItem(key);
    var oidlist = JSON.parse(getjson);

    if(oidlist != null){
        // 「お気に入りID」というキーが存在した時
        var checkitem = oidlist.indexOf(oid);     // 配列の何番目に該当のIDがあるかを見る
        if(checkitem != -1){
            // 「お気に入りID」の中に該当のIDが見つかった時
            oidlist.splice( checkitem, 1 );
            var setjson = JSON.stringify(oidlist);
            localStorage.setItem(key, setjson);

            togleitem(oid,'remove');
        }
    }
}
</script>

</body>
</html>

〜〜解説〜〜

javascriptの処理を大きく4つの機能に分けて解説していきます。

【解説Aパート】 表示ソースの切り替え

function togleitem(oid,event){
    if(event == 'add'){  // 引数の[event]が`add`の時
        // 未チェック(class="add")を非表示にして、チェック済(class="remove")を表示する
        $('li.add[no=' + oid + ']').hide();
        $('li.remove[no=' + oid + ']').show();
    } else if(event == 'remove'){  // 引数の[event]が`remove`の時
        // チェック済(class="remove")を非表示にして、未チェック(class="add")を表示する
        $('li.add[no=' + oid + ']').show();
        $('li.remove[no=' + oid + ']').hide();
    }
}

パートAでは別段ややこしい処理を書いているわけではありませんが、no属性とクラス(addもしくはremove)で特定の<li>を見つけだし、eventが[add]ならお気に入りに追加済みの見た目に変更し、逆に[remove]なら未追加の表示にします。

【解説Bパート】 ページロード時にローカルストレージの中をチェック

$(function(){
  $('ul .remove').hide();  // お気に入り中の表示は一時的に非表示に。

  // お気に入りリストに存在するか確認
  var key = 'お気に入りID';  // ローカルストレージのキーを指定
  var getjson = localStorage.getItem(key);  // ローカルストレージから値を取得
  var oidlist = JSON.parse(getjson);        // JSON形式から配列に直す
  if(oidlist != null){                      // 配列が空でなければ
    oidlist.forEach( function( oid ) {      // 配列の中身を1つずつ[oid]に入れてループを回す
      togleitem(oid,'add');                 // togleitem()関数を動かす ※パートAで書いたやつ
    });
  }

})

パートBでは、ページロードした時に過去にお気に入りにチェックを入れた情報を元に表示するソースをお気に入り状態に変更する処理が書いています。

まず、2行目でデフォルトの状態(つまり全てお気に入り非チェック)にします。そして、ローカルストレージからお気に入りリストを取得してきて、もしお気に入りリストが登録されていれば、登録されているIDの<li>はチェック済の状態に切り替える。という処理を書いています。

【解説Cパート】 お気に入りに追加機能

function addfav(oid){

    var key = 'お気に入りID';                       // キーの名前を指定

    // ローカルストレージから値を取得
    var getjson = localStorage.getItem(key);
    var oidlist = JSON.parse(getjson);

    if(oidlist == null){
        // 初めて「お気に入りID」というキーがローカルストレージに登録される時の処理
        oidary = new Array(oid);               // 初めてなので、新しい配列を作成
        var setjson = JSON.stringify(oidary);  // 配列をJSON形式に変換
        localStorage.setItem(key, setjson);    // ローカルストレージにお気に入りIDを保存

        togleitem(oid,'add');                  // クリックされた対象の<li>の表示を切り替え

    } else {
        // 既に「お気に入りID」というキーが存在する時
        if(oidlist.indexOf(oid) == -1){
            // 且つ、まだお気に入りIDに登録されていない時
            oidlist.push(oid);                     // 配列にクリックされたIDを追加
            var setjson = JSON.stringify(oidlist); // またJSON形式に変換
            localStorage.setItem(key, setjson);    // ローカルストレージにお気に入りIDを保存

            togleitem(oid,'add');                  // クリックされた対象の<li>の表示を切り替え
        }
    }
}

パートCでは、お気に入りにIDを登録(保存)する時の処理をかいています。

まず、お気に入りが追加されるシーンとしては2パターンあります。

1.ローカルストレージに初めてお気に入りIDが登録される時
2.既にお気に入りリストが登録されていて、他のIDがさらに追加される時

この2パターンがあるため、まず最初にローカルストレージの中身を確認し、「お気に入りID」というキーが既に登録されているかどうかをif文で分岐させます。
まだ登録されていなければ、新しく「お気に入りID」というキーを作成し、値にクリックしたIDを入れます。
既に登録されているのであれば、取得したお気に入りリストの配列の最後にクリックしたIDを追加します。
どちらのパターンでもパートAの関数を使い、ソースを切り替えて完了です。

【解説Dパート】 お気に入りから削除機能

function removefav(oid){

    var key = 'お気に入りID';                       // キーの名前を指定

    // ローカルストレージから値を取得
    var getjson = localStorage.getItem(key);
    var oidlist = JSON.parse(getjson);

    if(oidlist != null){
        // 「お気に入りID」というキーが存在した時
        var checkitem = oidlist.indexOf(oid);     // 配列の何番目に該当のIDがあるかを見る
        if(checkitem != -1){
            // 「お気に入りID」の中に該当のIDが見つかった時
            oidlist.splice( checkitem, 1 );   // 配列から該当IDを削除
            var setjson = JSON.stringify(oidlist); // JSON形式に変換
            localStorage.setItem(key, setjson);    // ローカルストレージに保存

            togleitem(oid,'remove');               // クリックされた対象の<li>の表示を切り替え
        }
    }
}

ここまで読んでいる方であればほとんど説明は不要かもしれません。

削除をする場合は、配列の何番目にIDがあるかを調べないといけないので、indexOf()を使って、配列の何番目に該当IDがあるのかを調べます。
あとはspliceを使って該当IDを削除し、またJSON形式にしてからローカルストレージに保存。その後、ソースの表示を切り替えています。

おまけ php編 〜wordpressの投稿IDに応用〜

ここからは初級〜中級者向けのwordpressでお気に入り機能を自作した人向けの内容になります。

wordpressでローカルストレージを使ったお気に入り機能を実装

仕組み

1.onclickでリンク先を指定して起動
2.ローカルストレージからデータを取得
3.取得したデータをpostで渡す
4.postのデータを受け取って変数に格納
5.変数のIDを使ってwordpressのループを作成

xxxx.php
<!-- 飛び先のURLを引数に指定 -->
<div onclick="oidlisttrans('http://hogehoge.com/xxx/yyyy.php')">お気に入りリストを見る</div>

<script>
    // ローカルストレージにあるparamsのデータをpostで送信
    function post(path, params, method='post') {
        const form = document.createElement('form');
        form.method = method;
        form.action = path;
        for (const key in params) {
            if (params.hasOwnProperty(key)) {
                const hiddenField = document.createElement('input');
                hiddenField.type = 'hidden';
                hiddenField.name = key;
                hiddenField.value = params[key];
                form.appendChild(hiddenField);
            }
        }
        document.body.appendChild(form);
        form.submit();
    }

    // お気に入りリストにデータをpost()を使って送信
    function oidlisttrans(link,data='all'){
        var key = 'お気に入りID';
        var getjson = localStorage.getItem(key);
        var oidlist = JSON.parse(getjson);
        obj = {
            'IDリスト': oidlist
        };
        post(link, obj);
    }

</script>

飛び先のページ(上と同一ページでも可能)

yyyy.php
<?php
$idlist = explode( ',', $_POST['IDリスト'] );

$wp_query = new WP_Query();
$args = array(
    'post_status' => 'publish',
    'post__in' => $idlist,
    'orderby' => 'post__in',
);
$wp_query->query($args);
?>
<?php if (have_posts()) : ?>
    <?php while (have_posts()) : the_post(); ?>
        //ループ内の処理を自由に書く
    <?php endwhile; ?>
<?php else: ?>
    // 投稿がなかった時の処理
<?php endif; ?>

こんな感じの書き方でwordpressでも応用して使えるかな?

ちょっと長丁場になりましたがいろいろ使い道があると思います!

まとめ

長くなるためCSSはほとんど省きましたが、自由に表示を切り替えたり見た目を変更できるので、
好きな位置に好きなボタンを配置できるので、プラグインなどを使ったけどうまくいかない方の参考に少しでもなればいいかなと思います。

おそまつ!