PageSourceSearch

https://www.ybc.co.jp/wp/wp-content/plugins/eventbank-calendar/assets/calendar.js?ver=1.0

js ybc.co.jp collected 2026-10-02 05:34:33 UTC 10,139 bytes, 369 lines download raw bytes

1document.addEventListener("DOMContentLoaded", () => {
2
3    /* =============================
4       state
5    ============================= */
6
7    let current = new Date();
8    let currentData = [];
9    let holidays = {};
10
11    /* =============================
12       DOM cache
13    ============================= */
14
15    const calendarEl = document.getElementById("ecb-calendar");
16    const eventsEl   = document.getElementById("ecb-events");
17    const loadingEl  = document.getElementById("ecb-loading");
18    const titleEl    = document.getElementById("ecb-title");
19    const prevBtn    = document.getElementById("ecb-prev");
20    const nextBtn    = document.getElementById("ecb-next");
21    const areaSelect = document.getElementById("ecb-area");
22    const headerEl   = document.querySelector(".header");
23    const updatedEl  = document.getElementById("ecb-updated");
24
25    /* =============================
26       エリア変更
27    ============================= */
28
29    if(areaSelect){
30        areaSelect.addEventListener("change",()=>{
31            loadCalendar(current.getFullYear(),current.getMonth()+1);
32        });
33    }
34
35    /* =============================
36       util
37    ============================= */
38
39    const pad = n => String(n).padStart(2,"0");
40
41    const formatDate = date => {
42        const d = new Date(date);
43        return `${d.getFullYear()}年${d.getMonth()+1}月${d.getDate()}日`;
44    };
45
46    const formatNow = () => {
47        const d = new Date();
48        return `${d.getFullYear()}年${d.getMonth()+1}月${d.getDate()}日 ${d.getHours()}時更新`;
49    };
50
51    const showLoading = () => {
52        loadingEl.style.display = "flex";
53        calendarEl.style.display = "none";
54    };
55
56    const hideLoading = () => {
57        loadingEl.style.display = "none";
58        calendarEl.style.display = "block";
59    };
60
61    /* =============================
62       祝日API
63    ============================= */
64
65    async function loadHolidays(){
66        try{
67            const res = await fetch("https://holidays-jp.github.io/api/v1/date.json");
68            holidays = await res.json();
69        }catch(e){
70            console.error("祝日取得失敗", e);
71            holidays = {};
72        }
73    }
74
75    /* =============================
76       API
77    ============================= */
78
79    async function loadCalendar(year, month){
80
81        showLoading();
82
83        try{
84            const area = areaSelect.value;
85
86            const res = await fetch(ECB.ajax_url,{
87                method:"POST",
88                headers:{
89                    "Content-Type":"application/x-www-form-urlencoded"
90                },
91                body:new URLSearchParams({
92                    action:"ecb_get_calendar",
93                    nonce:ECB.nonce,
94                    year:year,
95                    month:month,
96                    pref:area
97                })
98            });
99
100            const data = await res.json();
101
102            hideLoading();
103
104            if(!data.success){
105                calendarEl.innerHTML = "<p>読み込み失敗</p>";
106                return;
107            }
108
109            /* 更新日時(確実版) */
110            if(updatedEl){
111                updatedEl.textContent = "最終更新:" + formatNow();
112            }
113
114            /* データセット */
115            currentData = data.data.calendar;
116
117            titleEl.textContent = `${year}年 ${month}月`;
118
119            renderCalendar(year,month);
120
121            showTodayEvents();
122
123        }catch(e){
124
125            hideLoading();
126            calendarEl.innerHTML = "<p>エラー発生</p>";
127            console.error("エラー内容:", e);
128
129        }
130    }
131
132    /* =============================
133       calendar render
134    ============================= */
135
136    function renderCalendar(year,month){
137
138        const firstDate = new Date(year,month-1,1);
139        const firstDay  = firstDate.getDay();
140
141        const lastDate  = new Date(year,month,0).getDate();
142        const prevLast  = new Date(year,month-1,0).getDate();
143
144        let html = `<table class="ecb-table">`;
145
146        /* weekday */
147
148        html += `<tr class="week-head">`;
149
150        ["日","月","火","水","木","金","土"].forEach((w,i)=>{
151            const cls = i===0 ? "sun" : i===6 ? "sat" : "";
152            html += `<th class="${cls}">${w}</th>`;
153        });
154
155        html += "</tr><tr>";
156
157        let cellCount = 0;
158
159        /* prev month */
160
161        for(let i=0;i<firstDay;i++){
162            const d = prevLast - firstDay + i + 1;
163            html += `<td class="other-month">${d}</td>`;
164            cellCount++;
165        }
166
167        /* current month */
168
169        for(let d=1; d<=lastDate; d++){
170
171            const dateStr = `${year}-${pad(month)}-${pad(d)}`;
172
173            let cls = "";
174
175            const isHoliday = holidays[dateStr];
176            const dayObj = currentData.find(x => x.date === dateStr);
177
178            const weekIndex = cellCount % 7;
179
180            if(weekIndex===0) cls+=" sun";
181            if(weekIndex===6) cls+=" sat";
182
183            if(isHoliday){
184                cls += " holiday";
185            }
186
187            if(dayObj){
188                if(dayObj.today) cls+=" today";
189                if(dayObj.past) cls+=" past";
190                if(dayObj.events.length) cls+=" has-event";
191            }
192
193            html += `
194            <td class="${cls}" data-date="${dateStr}">
195                <div class="day">${d}</div>
196                ${isHoliday ? `<div class="holiday-name">${isHoliday}</div>` : ""}
197            </td>
198            `;
199
200            cellCount++;
201
202            if(cellCount % 7 === 0 && d !== lastDate){
203                html += "</tr><tr>";
204            }
205
206        }
207
208        /* next month */
209
210        const totalCells = firstDay + lastDate;
211        const rows = Math.ceil(totalCells / 7);
212        const maxCells = rows * 7;
213
214        for(let i=totalCells;i<maxCells;i++){
215            const nextDay = i-totalCells+1;
216            html += `<td class="other-month">${nextDay}</td>`;
217        }
218
219        html += "</tr></table>";
220
221        calendarEl.innerHTML = html;
222
223        const todayCell = calendarEl.querySelector("td.today");
224        if(todayCell) todayCell.classList.add("active");
225    }
226
227    /* =============================
228       event card html
229    ============================= */
230
231    function createEventHTML(ev){
232
233        const priceClass =
234            ev.price_name === "有料" ? "is-paid" : "is-free";
235
236        const inoutClass =
237            ev.inout_name === "屋外" ? "is-outdoor" : "is-indoor";
238
239        const imgSrc = ev.img
240        ? `https://api.eventbank.jp/image/${ev.img}`
241        : `${ECB.plugin_url}assets/img/noimage.jpg`;
242
243        return `
244        <div class="event-card">
245            <a href="${ECB.site_url}
245eventdetail/?eid=${ev.id}">
246                <div class="event-card__top">
247                    <img src="${imgSrc}" alt="${ev.title}">
248                    <div class="txt">
249                        <h4>${ev.title}</h4>
250                        <p>${ev.catchcopy}</p>
251                        <div class="cat">
252                            <span class="price_text ${priceClass}">${ev.price_name}</span>
253                            <span class="city">${ev.city_name}</span>
254                            <span class="inout_name ${inoutClass}">${ev.inout_name}</span>
255                        </div>
256                    </div>
257                </div>
258                <table>
259                    <tr>
260                        <th>会場</th>
261                        <td>${ev.place}</td>
262                    </tr>
263                    <tr>
264                        <th>開催期間</th>
265                        <td>${ev.date_display}</td>
266                    </tr>
267                </table>
268            </a>
269        </div>
270        `;
271    }
272
273    /* =============================
274       今日イベント
275    ============================= */
276
277    function showTodayEvents(){
278
279        const todayData = currentData.find(d => d.today);
280        if(!todayData) return;
281
282        let html = `<h3>${formatDate(todayData.date)}</h3>`;
283
284        if(todayData.events.length){
285            html += todayData.events.map(createEventHTML).join("");
286        }else{
287            html += "<p>イベントはありません。</p>";
288        }
289
290        eventsEl.innerHTML = html;
291    }
292
293    /* =============================
294       click
295    ============================= */
296
297    calendarEl.addEventListener("click", e => {
298
299        const td = e.target.closest("td[data-date]");
300        if(!td) return;
301
302        const date = td.dataset.date;
303
304        const dayData = currentData.find(x => x.date === date);
305
306        let html = `<h3>${formatDate(date)}</h3>`;
307
308        if(dayData && dayData.events.length){
309            html += dayData.events.map(createEventHTML).join("");
310        }else{
311            html += "<p>イベントはありません。</p>";
312        }
313
314        eventsEl.innerHTML = html;
315
316        scrollToEvents();
317
318        calendarEl.querySelectorAll("td").forEach(td=>{
319            td.classList.remove("active");
320        });
321
322        td.classList.add("active");
323
324    });
325
326    /* =============================
327       scroll
328    ============================= */
329
330    function scrollToEvents(){
331
332        const headerHeight =
333            headerEl ? headerEl.offsetHeight : 0;
334
335        const rect = eventsEl.getBoundingClientRect();
336
337        const pos =
338            window.scrollY + rect.top - headerHeight;
339
340        window.scrollTo({
341            top:pos,
342            behavior:"smooth"
343        });
344    }
345
346    /* =============================
347       navigation
348    ============================= */
349
350    prevBtn.addEventListener("click", () => {
351        current.setMonth(current.getMonth()-1);
352        loadCalendar(current.getFullYear(), current.getMonth()+1);
353    });
354
355    nextBtn.addEventListener("click", () => {
356        current.setMonth(current.getMonth()+1);
357        loadCalendar(current.getFullYear(), current.getMonth()+1);
358    });
359
360    /* =============================
361       init
362    ============================= */
363
364    (async () => {
365        await loadHolidays();
366        loadCalendar(current.getFullYear(), current.getMonth()+1);
367    })();
368
369});

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.