待合室通過後の残り時間表示(ページ内表示)

PC向け/スマホ向けサイト両対応
All-in-One対応

概要

待合室通過後、10分の滞在制限時間の有効期限時刻と残り時間をページの右下に薄く固定表示し、残り時間をカウントダウンします
有効期限が過ぎると赤く表示します
タップすると終了し表示が消えます

動作イメージ
注意
待合室の通過後の制限時間(滞在可能時間)はサイトによって異なります。
東京ディズニーリゾート オンライン予約・購入サイトでは10分となっており、このブックマークレットでは10分で計算しています。
他のサイトで利用するために計算する制限時間を変更したい場合は、下記の「カスタマイズ」の内容を参考に、数字部分を変更してブックマークレットの登録を行ってください
(入室時刻の取得はできますが、滞在可能時間の取得ができないためこのような仕様になっています)


※ブックマークレットの登録・利用方法が分からない場合は、基本的な使い方のページを参考にしてください

ブックマークレット文字列

以下の文字列でブックマークレットを登録し、待合室ページで使用してください

ダミー登録用の空ページのリンク
スマホの場合
iPhone Safari / Chrome および Android Chrome など
ブックマークレット文字列
PCブラウザの場合
以下のリンクボタンを、ブラウザのブックマークバーへドラッグ&ドロップして登録してください
(カスタマイズ)待合室通過後の制限時間を10分以外に変更する場合
他サイトで利用する場合など、制限時間を10分以外に変更する場合は、ブックマークレット登録時に文字列の末尾にある「10」の部分を書き換えてから登録してください
(待合室通過後の滞在可能時間は、サイトによって異なります)

使い方

待合室を通過した後の予約サイトの任意のページで、ブックマークレットを呼び出してください
ページの右下に有効期限の時刻と残り時間(分/秒)を表示します。残り時間は自動的にカウントダウンします


有効期限が切れると赤く表示します。この状態でリロードすると待合室に戻されます

表示部分をタップすると終了し表示が消えます(再度表示する場合は、再度ブックマークレットを呼び出してください)
ブックマークレットの仕様上、ページをリロードしたり別のページに移動した場合は表示が消えます

ソースコードおよび処理概要

ブックマークレット化前のソースコードです
ご自身で表示等カスタマイズされたい方はご自由にご利用ください
※ブックマークレット化の方法については記載していません

簡単な解説

JavaScriptコード
コピー
javascript: (function (duration_min) {
  if (document.querySelector('#queuePassedLimit')) {
    return;
  };
  const dateFormat = (date, format) => {
    const _fmt = {
      hh: date => { return ('0' + date.getHours()).slice(-2) },
      mm: date => { return ('0' + date.getMinutes()).slice(-2) },
      ss: date => { return ('0' + date.getSeconds()).slice(-2) },
      dd: date => { return ('0' + date.getDate()).slice(-2) },
      yyyy: date => { return date.getFullYear() + '' },
      MM: date => { return ('0' + (date.getMonth() + 1)).slice(-2) },
    };
    const _priority = ['dd', 'yyyy', 'MM', 'hh', 'mm', 'ss'];
    return _priority.reduce((res, fmt) => res.replace(fmt, _fmt[fmt](date)), format);
  };
  const getHMS = (total_sec) => {
    if (total_sec <= 0) {
      return [0, 0, 0];
    }
    const hours = Math.floor(total_sec / 60 / 60);
    const minutes = Math.floor((total_sec - hours * 60 * 60) / 60);
    const seconds = Math.floor(total_sec - (hours * 60 + minutes) * 60);
    return [hours, minutes, seconds]
  };
  const acceptedCookie = document.cookie.split('; ').find(row => row.startsWith('QueueITAccepted-'));
  if (!acceptedCookie) {
    alert('待合室通過の情報が見つかりませんでした');
    return;
  };

  const el = document.createElement('div');
  el.id = 'queuePassedLimit';
  el.style.cssText = 'padding:4px;position:fixed;right:0;bottom:0;z-index:20000;background-color:rgba(0,0,0,0.4);color:white;text-align:center;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);';
  el.innerHTML = '初期化中';

  document.body.appendChild(el);
  const cookieValue = decodeURIComponent(acceptedCookie.split('=')[1]);
  const searchParams = new URLSearchParams(cookieValue);
  const qIssueTime = searchParams.get('IssueTime');
  let timerId;
  if (qIssueTime) {
    timerId = setInterval(() => {
      const acceptedCookie = document.cookie.split('; ').find(row => row.startsWith('QueueITAccepted-'));
      const issueDate = new Date(Number(qIssueTime * 1000));
      let limit_text = '';
      let remain = -1;
      if (duration_min) {
        const limitDate = new Date(issueDate.getTime());
        limitDate.setMinutes(limitDate.getMinutes() + duration_min);
        remain = limitDate - new Date();

        let remain_text = '*** 期限切れ ***';
        if (remain > 0 && acceptedCookie) {
          const [_, remain_min, remain_sec] = getHMS(remain/1000);
          remain_text = `残り: ${remain_min}分${remain_sec}秒`;
        }
        limit_text += `有効期限: ${dateFormat(limitDate, 'hh:mm:ss')}<br>(${remain_text})`;
      }
      el.innerHTML = limit_text;
      if (remain <= 0 || !acceptedCookie) {
        el.style.backgroundColor = 'rgba(255,0,0,0.4)';
        clearInterval(timerId);
      };
    }, 1000);
    el.addEventListener('click', () => {
      clearInterval(timerId);
      el.remove();
    });
  } else {
    alert('不明なデータ形式です');
    return;
  };
})(10);