JS

ネイティブネタ帳

UI

モーダル

タブ

ドロワー

スライダー

スクロール

アコーディオン

目次

ローディングアニメーション

ツールチップ

ヘッダー

テーブル

グラフ

背景

ニュースティッカー

フォーム

フォーム

文字

文字の装飾

文字の操作

文字のカウント

数字の操作

ウィンドウ

ウィンドウ操作

タイトルの操作

ページ遷移時の動き

class

classの操作

要素

要素の操作

要素の追加

API

WP REST API

Google Books APIs

楽天市場API

openBD

画像・動画

画像の操作

YouTube

リンク

Google Analytics

cookie

検索

検索

お気に入り登録

JavaScriptのdocument.cookieで記事一覧レイアウトの設定をページリロードしても生かして表示

お気に入り登録をすると、お気に入り記事一覧に登録することができます。

document.cookie

JavaScriptのdocument.cookieで記事一覧レイアウトの設定をページリロードしても生かして表示

JavaScriptのdocument.cookieで記事一覧レイアウトの設定をページリロードしても生かして表示

JavaScriptではcookieの取得・保存・削除を行うことができます。

そんなcookieを使って、ユーザーが選択した「記事一覧レイアウト」の設定を、ページ離脱後も生かすJavaScriptのスニペットについて解説していきます。

document.cookie

JavaScriptの document.cookie は、Webブラウザ上に保存された情報のcookieを読み書きすることができます。

cookieを追加する時

JavaScriptでcookieを追加する時、以下のような記述をします。

document.cookie = 'value=クッキー名; max-age=9999';

max-age はそのcookieの寿命で表され、上記のような9999だと大体3時間弱です。

かかかず
かかかず

value のところは任意の名称でOKです。

cookieを削除する時

追加したcookieを削除する場合、max-ageの値を0に設定して、Cookieを有効期限切れにすることで削除の扱いにします。

document.cookie = "value=cookie名;max-age=0;";

記事一覧のサンプル

ここで選択したレイアウトは、ページ遷移や更新をしても生きる形です。ので、試してみる場合は「カード」のレイアウトを選択してから、そのままページ更新をしてみてください。

かかかず
かかかず

cookieを使っているので、ブラウザを閉じてから開いても選択した設定が生きます。

cookieを使ったサンプルのコード

コードは、HTML・JavaScript・CSSの3種です。順に解説していきます。

HTML

HTMLは大きく分けて、「レイアウトを変更するボタン」の要素と、「記事一覧」の2つでできています。

コード量は記事一覧に関するものがほとんどで、各記事のコンポーネントは li のリストタグで作っています。

<!-- レイアウト変更のボタンここから -->
<ul class="cookieSwitch">
	<li><p id="styleList" class="activeOn"><i class="fas fa-th-list"></i>リスト</p></li>
	<li><p id="styleCard"><i class="fas fa-th-large"></i>カード</p></li>
</ul>
<!-- レイアウト変更のボタンここまで -->
<!-- 記事一覧のレイアウト -->
<section class="SwitchBlock">
<div class="changeCard">
	<ul>
		<li class="changeItem defaultList">
			<a href="https://dubdesign.net/javascript/addeventlistener-scroll/">
				<p class="itemCat dfont">JavaScript ネタ帳</p>
				<img src="https://dubdesign.net/wp-content/uploads/2021/12/java003.jpg" alt="JavaScriptの.addEventListenerのスクロールでclassの追加と削除">
				<div class="changeItemTxt">
					<time class="pubdate sng-link-time dfont" itemprop="datePublished" datetime="2021年12月15日">2021年12月15日</time>
					<p class="itemTitle">JavaScriptの.addEventListenerのスクロールでclassの追加と削除</p>
					<ul class="itemTag">
<li>JavaScript</li><li>コピペ</li><li>スクロール</li></ul>
				</div>
			</a>
		</li>
		<li class="changeItem defaultList">
			<a href="https://dubdesign.net/download/html-css/javascript-yubinbango/">
				<p class="itemCat dfont">HTML・CSS</p>
				<img src="https://dubdesign.net/wp-content/uploads/2021/08/yuubinnbangou_eyecatch.jpg" alt="JavaScriptのコピペでできる郵便番号を入力すると住所を自動で表示してくれるプラグインYubinBango">
				<div class="changeItemTxt">
					<time class="pubdate sng-link-time dfont" itemprop="datePublished" datetime="2021年8月4日">2021年8月4日</time>
					<p class="itemTitle">JavaScriptのコピペでできる郵便番号を入力すると住所を自動で表示してくれるプラグインYubinBango</p>
					<ul class="itemTag">
<li>CSS</li><li>HTML</li><li>JavaScript</li></ul>
				</div>
			</a>
		</li>
		<li class="changeItem defaultList">
			<a href="https://dubdesign.net/javascript/hover-tooltip/">
				<p class="itemCat dfont">JavaScript ネタ帳</p>
				<img src="https://dubdesign.net/wp-content/uploads/2022/02/javatooltip.jpg" alt="JavaScriptの.addEventListener()でhoverした時ツールチップを表示">
				<div class="changeItemTxt">
					<time class="pubdate sng-link-time dfont" itemprop="datePublished" datetime="2022年2月23日">2022年2月23日</time>
					<p class="itemTitle">JavaScriptの.addEventListener()でhoverした時ツールチップを表示</p>
					<ul class="itemTag">
<li>JavaScript</li><li>コピペ</li><li>ツールチップ</li></ul>
				</div>
			</a>
		</li>
		<li class="changeItem defaultList">
			<a href="https://dubdesign.net/admiration/tail-grafic/">
				<p class="itemCat dfont">見て学ぶデザイン</p>
				<img src="https://dubdesign.net/wp-content/uploads/2020/05/0503_tairu_eyecatch.jpg" alt="イラストや写真をタイルのように隙間無く敷き詰めたデザイン">
				<div class="changeItemTxt">
					<time class="pubdate sng-link-time dfont" itemprop="datePublished" datetime="2020年5月3日">2020年5月3日</time>
					<p class="itemTitle">イラストや写真をタイルのように隙間無く敷き詰めたデザイン</p>
					<ul class="itemTag">
<li>広告</li></ul>
				</div>
			</a>
		</li>
	</ul>
</div>
</section>
<!-- 記事一覧のレイアウトここまで -->
かかかず
かかかず

ボタン内のアイコンはFontawesomeを使っています。

JavaScript

JavaScriptは、「ページロード時のcookieチェック」と「ボタンクリック時の処理」の2つで、これらを .addEventListener の「DOMContentLoaded=HTMLの配置が完了次第」と、「click=クリック」のイベントでそれぞれ分けて作っています。

/* ロード時のcookie有無チェック */
window.addEventListener('DOMContentLoaded', (event) => {
/* cookieを取得 */
   function getCookieArray(){
      var arr = new Array();
      if(document.cookie != ''){
         var tmp = document.cookie.split('; ');
         for(var i=0;i<tmp.length;i++){
            var data = tmp[i].split('=');
            arr[data[0]] = decodeURIComponent(data[1]);
         }
      }
      return arr;
   }
   var arr = getCookieArray();
   var result = arr["value"];
/* valueのcookieがない時 */
   if(result == null){
      console.log("no cookie");
   } else {
      var theme = result;
      if(theme == 'cardCookie'){
/* valueの値でcardCookieがある時 */
         var elements = document.getElementsByClassName("changeItem");
         var i;
           for (i = 0; i < elements.length; i++) {
             elements[i].classList.remove('defaultList');
             elements[i].classList.add('gridCard');
         }
         document.getElementById("styleCard").classList.add('activeOn');
         document.getElementById("styleList").classList.remove('activeOn');
         console.log('CardStyle');
      } else {
/* valueの値でcardCookieがない時 */
         var elements = document.getElementsByClassName("changeItem");
         var i;
           for (i = 0; i < elements.length; i++) {
             elements[i].classList.remove('gridCard');
             elements[i].classList.add('defaultList');
         }
         document.getElementById("styleList").classList.add('activeOn');
         document.getElementById("styleCard").classList.remove('activeOn');
         console.log('notCardStyle');
      }
   }
});

/* リストへ変更 */
document.querySelector('#styleList').addEventListener('click', () => {
var elements = document.getElementsByClassName("changeItem");
var i;
  for (i = 0; i < elements.length; i++) {
    elements[i].classList.remove('gridCard');
    elements[i].classList.add('defaultList');
}
document.getElementById("styleList").classList.add('activeOn');
document.getElementById("styleCard").classList.remove('activeOn');
document.cookie = "value=cardCookie;max-age=0;";
console.log('cookieDelete');
});

/* カードへ変更 */
document.querySelector('#styleCard').addEventListener('click', () => {
var elements = document.getElementsByClassName("changeItem");
var i;
  for (i = 0; i < elements.length; i++) {
    elements[i].classList.remove('defaultList');
    elements[i].classList.add('gridCard');
}
document.getElementById("styleCard").classList.add('activeOn');
document.getElementById("styleList").classList.remove('activeOn');
document.cookie = 'value=cardCookie; max-age=9999';
console.log('cookieGet');
});

特に冒頭の「ページロード時のcookieチェック」は、ifの条件分岐で処理を分けているので、一緒に記述してあるコメントアウトと共にご覧ください。

ページロード時の処理

このスニペットでは、HTMLの配置が終わったタイミングでcookieチェックを行い、JavaScriptがclassの追加・削除をおこないます。その為、ロード時の処理が重めなので、PHPなどのバック側でcookieの条件分岐で処理を行った方がいいかもしれません。

WordPress(PHP)でcookieの条件分岐を行わせる場合は、以下の記事も参考にしてみてください。

クッキーの条件分岐 cookieで条件分岐

CSS

レイアウトはFlexboxを使い、JavaScriptでclassを付け替えた時にCSSが紐づき表示を切り替えます。

その為、CSSはレイアウトに関する記述がほとんどになっています。

/* ボタンのレイアウト */
ul.cookieSwitch {
    border: none;
    padding: 0;
    list-style: none;
    display: flex;
    justify-content: flex-end;
    flex-wrap: wrap;
    margin: 0;
    gap: 20px;
}
ul.cookieSwitch li p {
    margin: 0;
    display: inline-block;
    cursor: pointer;
    padding: 5px 20px 3px;
    background: #ddd;
    color: #FFF;
    border-radius: 2px;
    font-size: 0.9rem;
}
ul.cookieSwitch li p.activeOn {
    background: #707070;
}
ul.cookieSwitch li p i {
    margin-right: 5px;
}
/* ボタンここまで */

/* レイアウト共通 */
.changeCard ul {
    padding: 0;
    list-style: none;
    border: none;
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0;
    margin-top: 5px;
}
.changeItemTxt {
    width: 62%;
}
.changeItemTxt p.itemTitle {
    font-size: 1.1rem;
    line-height: 1.56;
    margin: 0;
    font-weight: bold;
    color: #313131;
    margin-bottom: 10px;
}
.changeItemTxt ul.itemTag {
    padding: 0;
    margin: 0;
    display: flex;
    justify-content: flex-start;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
}
.changeItemTxt ul.itemTag li {
    background: #f1f1f1;
    color: #707070;
    font-size: 0.7rem;
    padding: 2px 10px;
    position: relative;
}
.changeItemTxt ul.itemTag li:before {
    padding-right: 3px;
    font-family: "Font Awesome 5 Free";
    font-weight: 900;
    font-size: 1em;
    content: "\f02b";
    vertical-align: baseline;
    color: #aaa;
}
p.itemCat {
    position: absolute;
    left: 22px;
    top: 22px;
    background: #6bb6ff;
    color: #FFF;
    border-radius: 9999px;
    font-size: 0.7rem;
    display: inline-block;
    padding: 1px 12px 0px;
    z-index: 2;
}
/* 共通ここまで */

/* List */
li.changeItem.defaultList {
    width: 100%;
    padding: 0;
}
li.changeItem.defaultList a {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    border-radius: 2px;
    background: #fff;
    cursor: pointer;
    transition: 0.2s ease-in-out;
    padding: 15px;
    position: relative;
    align-items: center;
    text-decoration: none;
    border-top: solid 1px #eee;
    padding-right: 10px;
    cursor: pointer;
}
li.changeItem.defaultList:last-child a {
    border-bottom: solid 1px #EEE;
}
li.changeItem.defaultList a:hover {
    background: #fafafa;
}
li.changeItem.defaultList a img {
    width: 35%;
    margin-right: 3%;
}

@media screen and (max-width: 767px) {
/* (ここにモバイル用スタイルを記述) */
li.changeItem.defaultList a {
    flex-direction: column;
}
li.changeItem.defaultList a img {
    width: 100%;
    margin: 0 0 15px;
}
li.changeItem.defaultList a .changeItemTxt {
    width: 100%;
}
}

/* GridCard変更後 */
li.changeItem.gridCard {
    width: 47.5%;
    margin-bottom: 30px;
}
li.changeItem.gridCard a {
    display: flex;
    flex-direction: column;
    border: none;
    border-radius: 2px;
    background: #fff;
    box-shadow: 0 0 3px 0 rgb(0 0 0 / 12%), 0 2px 3px 0 rgb(0 0 0 / 22%);
    cursor: pointer;
    transition: 0.2s ease-in-out;
    height: 100%;
    padding: 0;
    position: relative;
    text-decoration: none;
}
li.changeItem.gridCard a:hover {
    box-shadow: 0 15px 30px -5px rgb(0 0 0 / 15%), 0 0 5px rgb(0 0 0 / 10%);
    transform: translateY(-4px);
}
li.changeItem.gridCard a p.itemCat {
    top: 10px;
    left: 10px;
}
li.changeItem.gridCard a .changeItemTxt {
    width: 100%;
    padding-left: 18px;
    padding-right: 18px;
    padding-bottom: 10px;
}
li.changeItem.gridCard a img {
    width: 100%;
    margin: 0 0 12px;
}
li.changeItem.gridCard .changeItemTxt ul.itemTag {
    display:none;
}
@media screen and (max-width: 767px) {
/* (ここにモバイル用スタイルを記述) */
li.changeItem.gridCard {
    width: 100%;
    margin-bottom: 20px;
}
}

UI

  • 他のウィンドウが開くことができないポップアップのUIです。

    モーダル

    モーダル

  • 並列な関係を持つ情報を1つずつ格納するUIです。

    タブ

    タブ

  • サイドから全体を覆うほど大きいメニュー表示するUIです。

    ドロワー

    ドロワー

  • 画像などのコンテンツをスライド表示させるUIです。

    スライダー

    スライダー

  • スクロールで表示が変化するスニペットです。

    スクロール

    スクロール

  • クリックすると隠れていた部分が開閉するUIです。

    アコーディオン

    アコーディオン

  • ページのhタグを取得して目次を生成するスニペットです。

    目次

    目次

  • ページの読み込み時にアニメーションをするスニペットです。

    ローディングアニメーション

    ローディングアニメーション

  • マウスオーバーした際に表示される補足説明です。

    ツールチップ

    ツールチップ

  • ページ内上部にあるナビゲーションUIです。

    ヘッダー

    ヘッダー

  • 行と列の組み合わせでできているUIです。

    テーブル

    テーブル

  • データを表やグラフで可視化して見せるUIです。

    グラフ

    グラフ

  • 背景をアニメーションで動かすスニペットです。

    背景

    背景

  • 短いテキスト情報をスクロール表示するUIです。

    ニュースティッカー

    ニュースティッカー

フォーム

  • ラジオボタン、チェックボックス、ドロップダウンリストなどを通じて、ユーザーが入力できるUIです。

    フォーム

    フォーム

文字

  • 文字列をJavaScriptで装飾・動きをつけるスニペットです。

    文字の装飾

    文字の装飾

  • 文字列の操作をして、置換・変更を行うスニペットです。

    文字の操作

    文字の操作

  • 文字列をカウントして表示などを行うスニペットです。

    文字のカウント

    文字のカウント

  • 数字の要素を取得して、変更するスニペットです。

    数字の操作

    数字の操作

ウィンドウ

classの操作

  • 要素を取得して、classを追加・削除するスニペットです。

    classの操作

    classの操作

要素の操作

API

  • WordPressのAPIを取得して表示するスニペットです。

    WP REST API

    WP REST API

  • Google Books APIsで書籍の情報を表示するスニペットです。

    Google Books APIs

    Google Books APIs

  • 楽天市場のAPIを取得して表示するスニペットです。

    楽天市場API

    楽天市場API

  • openBDのAPIを取得して表示するスニペットです。

    openBD

    openBD

画像・動画

  • 画像を取得して、アニメーションなどの変化を加えるスニペットです。

    画像の操作

    画像の操作

  • YouTubeの動画を表示するスニペットです。

    YouTube

    YouTube

リンク

  • ページ内のリンクを取得して変更・操作するスニペットです。

    リンク

    リンク

  • Google Analyticsとの連携をするスニペットです。

    Google Analytics

    Google Analytics

cookie

  • ブラウザのcookieを利用するスニペットです。

    cookie

    cookie

検索

  • 指定した要素の中から検索を行うスニペットです。

    検索

    検索