PageSourceSearch

https://fortune-cookie.tokyo/assets/js/top-countdown-banner.js?v=1.0.610

js fortune-cookie.tokyo collected 2026-10-07 17:57:54 UTC 2,968 bytes, 86 lines download raw bytes

1(function () {
2    'use strict';
3
4    var ticker = document.getElementById('top-countdown-banner');
5    if (!ticker) return;
6
7    // 開催中はカウントダウン数字が無いので tick 不要 (spec §3.5)
8    if (ticker.dataset.eventActive === '1') return;
9
10    var targetIso = ticker.getAttribute('data-target');
11    if (!targetIso) return;
12
13    var target = new Date(targetIso).getTime();
14    if (isNaN(target)) return;
15
16    var elD = ticker.querySelector('[data-tcb-d]');
17    var elH = ticker.querySelector('[data-tcb-h]');
18    var elM = ticker.querySelector('[data-tcb-m]');
19    var elS = ticker.querySelector('[data-tcb-s]');
20    if (!elD || !elH || !elM || !elS) return;
21
22    var URGENT_CLASS = 'top-countdown-banner--urgent';
23
24    function pad2(n) {
25        return String(n).padStart(2, '0');
26    }
27
28    // 前回書いた値(値が変わるときだけ DOM を書く)
29    var last = { d: null, h: null, m: null, s: null, urgent: null };
30    var finished = false;
31    var fallbackIntervalId = null;
32    var clock = window.CountdownSyncClock;
33    var useSharedClock = !!(clock && typeof clock.subscribeSecond === 'function' && typeof clock.unsubscribe === 'function');
34
35    function setText(el, key, value) {
36        if (last[key] === value) return;
37        el.textContent = value;
38        last[key] = value;
39    }
40
41    function finish() {
42        finished = true;
43        if (useSharedClock) clock.unsubscribe(tick);
44        if (fallbackIntervalId !== null) {
45            clearInterval(fallbackIntervalId);
46            fallbackIntervalId = null;
47        }
48    }
49
50    function tick() {
51        if (finished) return;
52        var remaining = Math.max(0, target - Date.now());
53        var diff = remaining;
54        var day  = Math.floor(diff / 86400000); diff -= day  * 86400000;
55        var hour = Math.floor(diff / 3600000);  diff -= hour * 3600000;
56        var min  = Math.floor(diff / 60000);    diff -= min  * 60000;
57        var sec  = Math.floor(diff / 1000);
58
59        setText(elD, 'd', String(day));
60        setText(elH, 'h', pad2(hour));
61        setText(elM, 'm', pad2(min));
62        setText(elS, 's', pad2(sec));
63
64        // 開催まで 1 時間 (= 3,600,000 ms) を切ったら水色キラキラモードを発火
65        var urgent = remaining < 3600000;
66        if (last.urgent !== urgent) {
67            if (urgent) {
68                ticker.classList.add(URGENT_CLASS);
69            } else {
70                ticker.classList.remove(URGENT_CLASS);
71            }
72            last.urgent = urgent;
73        }
74
75        // 残り 0 を描画したら以降は表示が変わらないので止める
76        if (remaining === 0) finish();
77    }
78
79    if (useSharedClock) {
80        // 秒境界に揃えた共有スケジューラ(購読時に即 1 回 tick する。非表示タブでは止まる)
81        clock.subscribeSecond(tick);
82    } else {
83        tick();
84        if (!finished) fallbackIntervalId = setInterval(tick, 1000);
85    }
86})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.