JavaScriptでタイマーセットして、コンテンツの表示・非表示を制御


2019年4月22日

皆さんこんにちは!

花粉症が治らないせいなのか、毎晩定期的に起きてそのまま眠れない老人末吉です。

GWに備えたコンテンツの表示・非表示スクリプト

さて、もういくつねるとGWがやってきます。
今回のGWは10連休もあり、いくつかの企業さんは実際に10連休取られることもあるでしょう。

そんなときに困ることがひとつ、GW中の更新です。

きっと多くのウェブ担当者さんは以下のことをお考えでしょう。
GW中に終了するサービスがあるけど、更新のために休日出勤したくない・・・

きっと多くの経営者さんは以下のことをお考えでしょう。
たった1時間の業務のために従業員を出社させ、手当を払わなければいけないのか・・・

ならば、もうJavaScriptを使用して自動的にコンテンツの表示・非表示を制御しましょう。

JavaScript

/**
 * HTMLエレメント内に書かれたdata属性の日付に従い、
 * コンテンツを表示・非表示処理する。
 */
window.onload = () => {
  const elements = document.querySelectorAll('.js-timer');
  elements.forEach((el) => {
    const now = new Date().getTime();
    const start = new Date(el.dataset.start).getTime();
    const end = new Date(el.dataset.end).getTime();
    let flag = false; // Global Flag
    /**
     * 現在が開始日以降か判定
     *
     * @return Boolean;
     */
    const checkerStart = () => {
      if (now > start) {
        return true;
      } else {
        return false;
      }
    };
    /**
     * 現在が終了日以前か判定
     *
     * @return Boolean;
     */
    const checkerEnd = () => {
      if (now < end) {
        return true;
      } else {
        return false;
      }
    };
    /*
     * メイン判定処理
     */
    if (start && end) {
      if (checkerStart() && checkerEnd()) flag = true;
    } else if (start && !end) {
      if (checkerStart()) flag = true;
    } else if (!start && end) {
      if (checkerEnd()) flag = true;
    } else {
      flag = false;
    }
    if (!flag) el.setAttribute('style', 'display: none;');
  });
};

HTML

<!DOCTYPE>
<html lang="ja">
  <head>
    <meta charset="UTF-8">
    <title>コンテンツの日付を判定して表示、非表示</title>
  </head>
  <body>
    <div class="js-timer" data-start="2019/04/01 0:00" data-end="2019/05/01 0:00">aaaa1</div>

    <div class="js-timer" data-start="2019/04/10 0:00">eeee1</div>

    <div class="js-timer" data-end="2019/05/15 0:00">cccc1</div>

    <script src="./timer.js" async></script>
  </body>
</html>

コードレビュー

はい荒っぽいコードですが、見ていきましょう。

const elements = document.querySelectorAll('.js-timer');
elements.forEach((el) => {});

まずはHTMLの中から js-timer というclassを持ったエレメントを拾い出し、
forEachでひとつひとつまわします。

const now = new Date().getTime();
const start = new Date(el.dataset.start).getTime();
const end = new Date(el.dataset.end).getTime();
let flag = false; // Global Flag
/**
 * 現在が開始日以降か判定
 *
 * @return Boolean;
 */
const checkerStart = () => {
  if (now > start) {
    return true;
  } else {
    return false;
  }
};
/**
 * 現在が終了日以前か判定
 *
 * @return Boolean;
 */
const checkerEnd = () => {
  if (now < end) {
    return true;
  } else {
    return false;
  }
};

now に現在の時刻、startにHTML要素に書かれた表示開始日(data-start)、endにHTML要素に書かれた表示終了日(data-end)をしまいます。

そして flag に false をセットしておきます。

また、checkerStart は”今”が表示開始日以降か判定し、そうであればtrueを返します。そうでなければfalseです。
checkerEndは”今”が表示終了日以前か判定し、そうであればtrueを返します。そうでなければfalseです。

/*
 * メイン判定処理
 */
if (start && end) {
  if (checkerStart() && checkerEnd()) flag = true;
} else if (start && !end) {
  if (checkerStart()) flag = true;
} else if (!start && end) {
  if (checkerEnd()) flag = true;
} else {
  flag = false;
}

さて、ここからが判定処理です。

表示開始日と表示終了日、どちらもセットされていれば一個目のifが走ります。

表示開始日のみ、あるいは表示終了日のみであればその後の処理が走ります。

どれもそれぞれ、先ほどの無名関数checkerStartとcheckerEndが走り判定がtrueであれば、flagをtrueに変更します。

そして・・・

if (!flag) el.setAttribute('style', 'display: none;');

flagがfalseであるならば、その要素に display: none; を付与します。
trueであるならば、表示してよい期間内ということなので何もしません。

まとめ

もちろんこの仕組みは逆にしてしまってもよいです。
最初にdisplay: none;になってる要素を検出し、表示期間内であれば表示するということもOKです。

ただし、その場合はその要素が display: float; や display: block; でありたかった場合困ります。
そのため、.is-hide { display: none !important; } など非表示にするutility classを用意し、表示期間内であればis-hideを取り除くといった処理にしましょう。

 

本記事に書いたスクリプトはES5では動きませんので、babel等でトランスパイルして使用してください!

 

さて、これにてGWを満喫できるようになったGWの担当者さん、よいGWを!

Share Button