PageSourceSearch

https://www.kigawaya.com/js/kigawaya.js

js kigawaya.com collected 2026-10-05 01:31:27 UTC 18,352 bytes, 617 lines download raw bytes

1function MM_findObj(n, d) { //v4.01
2  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
3    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
4  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
5  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
6  if(!x && d.getElementById) x=d.getElementById(n); return x;
7}
8function MM_swapImage() { //v3.0
9  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
10   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
11}
12function MM_swapImgRestore() { //v3.0
13  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
14}
15
16function MM_preloadImages() { //v3.0
17  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
18    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
19    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
20}
21
22
23
24$(document).ready(function(){
25    $('.accordion_head').click(function() {
26        $(this).next().slideToggle();
27    }).next().hide();
28});
29
30$(document).ready(function(){
31  $('.bxslider').bxSlider({
32    mode: 'fade',
33    auto: true,
34	speed: 2000,
35	pause: 7000,
36	controls: false
37  });
38});
39
40
41
42var currentDate = new Date(); 
43jQuery(function(){
44	jQuery('.nyuka-date').each(function(){
45		time = (jQuery(this).text()).split(":");
46		var entryDate = new Date(time[0], time[1]-1, time[2], time[3], time[4], time[5]); 
47		var now = (entryDate.getTime()/(24*60*60*1000)) - (currentDate.getTime()/(24*60*60*1000)); 
48		now = Math.ceil(now);
49		if (now == 0) {
50			jQuery(this).html('<div class="today">本日入荷</div>');
51			jQuery(this).css('display', 'inline');
52		} else if (now > 0) {
53			jQuery(this).html('<div class="future">' + Number(time[1]) + '月' + Number(time[2]) + '日 入荷予定</div>');
54			jQuery(this).css('display', 'inline');
55		} else {
56			jQuery(this).html('<div class="old"></div>');
57			jQuery(this).css('display', 'inline');
58		}
59	});
60});
61
62//ヘッダクリッカブルマップ用
63document.addEventListener('DOMContentLoaded', () => {
64  const image = document.getElementById('main-image');
65  const label = document.getElementById('hover-label');
66  const areas = document.querySelectorAll('map[name="bottlemap"] area');
67
68  function showLabel(event) {
69    const area = event.target;
70    const rect = image.getBoundingClientRect();
71    const scaleX = image.offsetWidth / image.naturalWidth;
72    const scaleY = image.offsetHeight / image.naturalHeight;
73
74    const coords = area.coords.split(',').map(Number);
75    const x = coords[0] * scaleX;
76    const y = coords[1] * scaleY;
77
78    label.style.left = `${x}px`;
79    label.style.top = `${y - 30}px`;
80    label.textContent = area.dataset.label || area.alt || '';
81    label.style.opacity = 1;
82  }
83
84  function hideLabel() {
85    label.style.opacity = 0;
86  }
87
88  areas.forEach(area => {
89    area.addEventListener('mouseenter', showLabel);
90    area.addEventListener('mouseleave', hideLabel);
91  });
92});
93
94/* hover-area(クリックエリア)を data-url へ遷移させる */
95document.addEventListener('click', (e) => {
96  const area = e.target.closest('.hover-area');
97  if (!area) return;
98
99  const url = area.getAttribute('data-url');
100  if (!url) return;
101
102  window.location.href = url;
103});
104
105// キーボード操作も対応(任意)
106document.addEventListener('keydown', (e) => {
107  if (e.key !== 'Enter' && e.key !== ' ') return;
108  const area = document.activeElement?.closest?.('.hover-area');
109  if (!area) return;
110
111  const url = area.getAttribute('data-url');
112  if (!url) return;
113
114  e.preventDefault();
115  window.location.href = url;
116});
117
118// スマホメニュー「商品一覧」ドロワー
119// カテゴリ構造はHTMLに直書き。サブカテゴリの開閉状態を保存・復元。
120document.addEventListener('DOMContentLoaded', () => {
121  const drawer = document.getElementById('spDrawer');
122  const btn = document.querySelector('.js-open-catalog');
123  if (!drawer || !btn) return;
124
125  // 開いているサブカテゴリを保存するキー
126  // aria-controls の値(例: spCatSakeSub / spCatWineSub)を保存する
127  const STORAGE_KEY = 'kgw_sp_drawer_open_submenus';
128
129  const readOpenSubmenus = () => {
130    try {
131      const raw = localStorage.getItem(STORAGE_KEY);
132      const value = raw ? JSON.parse(raw) : [];
133      return Array.isArray(value) ? value : [];
134    } catch (e) {
135      return [];
136    }
137  };
138
139  const writeOpenSubmenus = (ids) => {
140    try {
141      localStorage.setItem(STORAGE_KEY, JSON.stringify(ids));
142    } catch (e) {
143      // localStorage が使えない環境では何もしない
144    }
145  };
146
147  const getSubmenuId = (toggle) => {
148    return toggle.getAttribute('aria-controls') || '';
149  };
150
151  const syncAria = (toggle, group) => {
152    toggle.setAttribute('aria-expanded', group.classList.contains('is-open') ? 'true' : 'false');
153  };
154
155  const saveSubmenuState = () => {
156    const openIds = [];
157
158    drawer.querySelectorAll('.js-sp-sub-toggle').forEach((toggle) => {
159      const group = toggle.closest('.sp-cat__group');
160      const id = getSubmenuId(toggle);
161
162      if (group && id && group.classList.contains('is-open')) {
163        openIds.push(id);
164      }
165    });
166
167    writeOpenSubmenus(openIds);
168  };
169
170  const open = () => {
171    drawer.classList.add('is-open');
172    drawer.setAttribute('aria-hidden', 'false');
173    btn.setAttribute('aria-expanded', 'true');
174  };
175
176  const close = () => {
177    drawer.classList.remove('is-open');
178    drawer.setAttribute('aria-hidden', 'true');
179    btn.setAttribute('aria-expanded', 'false');
180  };
181
182  btn.addEventListener('click', (e) => {
183    e.preventDefault();
184    drawer.classList.contains('is-open') ? close() : open();
185  });
186
187  // 背景 / ×(data-drawer-close)で閉じる
188  drawer.addEventListener('click', (e) => {
189    if (e.target.closest('[data-drawer-close]')) close();
190  });
191
192  // サブカテゴリ開閉
193  // ページ遷移後も、前回開いていたサブカテゴリを復元する
194  const savedOpenIds = readOpenSubmenus();
195
196  drawer.querySelectorAll('.js-sp-sub-toggle').forEach((toggle) => {
197    const group = toggle.closest('.sp-cat__group');
198    if (!group) return;
199
200    const id = getSubmenuId(toggle);
201
202    if (id && savedOpenIds.includes(id)) {
203      group.classList.add('is-open');
204    } else {
205      group.classList.remove('is-open');
206    }
207
208    syncAria(toggle, group);
209
210    toggle.addEventListener('click', (e) => {
211      e.preventDefault();
212
213      group.classList.toggle('is-open');
214      syncAria(toggle, group);
215      saveSubmenuState();
216    });
217  });
218
219  // ドロワー内リンクを押したら、開いているサブカテゴリ状態を保存してから閉じて遷移
220  drawer.addEventListener('click', (e) => {
221    const link = e.target.closest('a');
222    if (!link || !drawer.contains(link)) return;
223
224    saveSubmenuState();
225    close();
226  });
227
228  // ESCで閉じる(PC検証用)
229  document.addEventListener('keydown', (e) => {
230    if (e.key === 'Escape' && drawer.classList.contains('is-open')) close();
231  });
232});
233
234
235/* =========================================================
236   URL追跡パラメータ(_gl / _ga / gclid など)をアドレスバーから除去する
237   - カート等の別ドメイン跨ぎで付与されるGoogle Analyticsのlinker等が原因で
238     URLが長くなるのを「表示上だけ」解消する目的。
239   - 計測はページ読込時に行われるため、window load 後にreplaceStateで
240     URLだけをクリーンにする(ページ遷移なし / リロードなし)。
241   ========================================================= */
242(function () {
243  function cleanTrackingParams() {
244    try {
245      const url = new URL(location.href);
246      const strip = new Set(['_gl', '_ga', 'gclid', 'fbclid', 'yclid', 'msclkid']);
247      let changed = false;
248
249      for (const k of [...url.searchParams.keys()]) {
250        if (strip.has(k) || k.startsWith('_ga_')) {
251          url.searchParams.delete(k);
252          changed = true;
253        }
254      }
255
256      if (changed) {
257        const clean =
258          url.pathname +
259          (url.searchParams.toString() ? '?' + url.searchParams.toString() : '') +
260          url.hash;
261        history.replaceState(null, '', clean);
262      }
263    } catch (e) {
264      // 何もしない(古い環境対策)
265    }
266  }
267
268  // GA等が先にクエリを読む時間を確保しやすいタイミングで実行
269  window.addEventListener('load', cleanTrackingParams);
270})();
271
272
273/* =========================================================
274   木川屋|トップ 新着情報:カテゴリ切替 & 表示件数制御JS
275   - 「全部」: 30件
276   - 各カテゴリ: 8件
277   ========================================================= */
278(function(){
279  const box = document.querySelector('.kgw-news');
280  if(!box) return;
281
282  const tabs = box.querySelectorAll('.kgw-news__tab');
283  const items = Array.from(box.querySelectorAll('.kgw-news__item'));
284  const maxAll = 50;
285  const maxCat = 30;
286
287  function applyFilter(label){
288    const limit = (label === 'all') ? maxAll : maxCat;
289    let shown = 0;
290
291    items.forEach(li => {
292      const v = (li.getAttribute('data-news-label') || '').trim();
293      const hit = (label === 'all') || (v === label);
294      li.style.display = (hit && shown < limit) ? '' : 'none';
295      if(hit && shown < limit) shown++;
296    });
297  }
298
299  tabs.forEach(btn => {
300    btn.addEventListener('click', () => {
301      tabs.forEach(b => { b.classList.remove('is-active'); b.setAttribute('aria-pressed','false'); });
302      btn.classList.add('is-active');
303      btn.setAttribute('aria-pressed','true');
304
305      applyFilter(btn.dataset.newsFilter || 'all');
306
307      const sc = box.querySelector('.kgw-news__scrollbox');
308      if(sc) sc.scrollTop = 0;
309    });
310  });
311
312  applyFilter('all');
313})();
314
315
316/* =========================================================
317最近見た商品
318   ========================================================= */
319(function () {
320  var STORAGE_KEY = "kgw_recently_viewed_items";
321  var MAX_ITEMS = 6;
322
323  function normalizeUrl(url) {
324    if (!url) return "";
325    return url.split("#")[0].split("?")[0];
326  }
327
328  function escapeHtml(str) {
329    if (str == null) return "";
330    return String(str)
331      .replace(/&/g, "&amp;")
332      .replace(/</g, "&lt;")
333      .replace(/>/g, "&gt;")
334      .replace(/"/g, "&quot;")
335      .replace(/'/g, "&#39;");
336  }
337
338  function getItems() {
339    try {
340      var raw = localStorage.getItem(STORAGE_KEY);
341      var items = raw ? JSON.parse(raw) : [];
342      return Array.isArray(items) ? items : [];
343    } catch (e) {
344      return [];
345    }
346  }
347
348  function saveItems(items) {
349    try {
350      localStorage.setItem(STORAGE_KEY, JSON.stringify(items));
351    } catch (e) {}
352  }
353
354  function addItem(item) {
355    if (!item || !item.url || !item.name) return;
356
357    item.url = normalizeUrl(item.url);
358
359    var items = getItems();
360
361    items = items.filter(function (x) {
362      return normalizeUrl(x.url) !== item.url;
363    });
364
365    items.unshift({
366      name: item.name,
367      url: item.url,
368      image: item.image || ""
369    });
370
371    if (items.length > MAX_ITEMS) {
372      items = items.slice(0, MAX_ITEMS);
373    }
374
375    saveItems(items);
376  }
377
378  function render(selector) {
379    var container = document.querySelector(selector || "#kgw-recently-viewed-list");
380    var area = document.getElementById("kgw-recently-viewed-area");
381    if (!container) return;
382
383    var currentUrl = normalizeUrl(location.href);
384    var items = getItems().filter(function (item) {
385      return normalizeUrl(item.url) !== currentUrl;
386    });
387
388    if (!items.length) {
389      container.innerHTML = '<p class="kgw-recently-viewed--empty">最近見た商品はありません。</p>';
390      if (area) area.style.display = "none";
391      return;
392    }
393
394    if (area) area.style.display = "";
395
396    container.innerHTML = items.map(function (item) {
397      var imageHtml = item.image
398        ? '<div class="kgw-recent-item__image-wrap"><img class="kgw-recent-item__image" src="' + escapeHtml(item.image) + '" alt="' + escapeHtml(item.name) + '"></div>'
399        : '';
400
401      return ''
402        + '<div class="kgw-recent-item">'
403        +   '<a href="' + escapeHtml(item.url) + '">'
404        +     imageHtml
405        +     '<div class="kgw-recent-item__name">' + escapeHtml(item.name) + '</div>'
406        +   '</a>'
407        + '</div>';
408    }).join("");
409  }
410
411  window.KGWRecentlyViewed = {
412    addItem: addItem,
413    render: render
414  };
415})();
416
417/* =========================================================
418   お気に入り商品
419   - localStorage保存
420   - ハートボタンで追加/解除
421   - 商品詳細・商品一覧の両方で利用
422   ========================================================= */
423(function () {
424  var STORAGE_KEY = "kgw_favorite_items";
425  var MAX_ITEMS = 30;
426
427  function normalizeUrl(url) {
428    if (!url) return "";
429    return String(url).split("#")[0].split("?")[0];
430  }
431
432  function escapeHtml(str) {
433    if (str == null) return "";
434    return String(str)
435      .replace(/&/g, "&amp;")
436      .replace(/</g, "&lt;")
437      .replace(/>/g, "&gt;")
438      .replace(/"/g, "&quot;")
439      .replace(/'/g, "&#39;");
440  }
441
442  function getItems() {
443    try {
444      var raw = localStorage.getItem(STORAGE_KEY);
445      var items = raw ? JSON.parse(raw) : [];
446      return Array.isArray(items) ? items : [];
447    } catch (e) {
448      return [];
449    }
450  }
451
452  function saveItems(items) {
453    try {
454      localStorage.setItem(STORAGE_KEY, JSON.stringify(items));
455    } catch (e) {}
456  }
457
458  function isFavorite(url) {
459    var targetUrl = normalizeUrl(url);
460    if (!targetUrl) return false;
461
462    return getItems().some(function (item) {
463      return normalizeUrl(item.url) === targetUrl;
464    });
465  }
466
467  function addItem(item) {
468    if (!item || !item.url || !item.name) return;
469
470    var normalizedUrl = normalizeUrl(item.url);
471    var items = getItems();
472
473    items = items.filter(function (x) {
474      return normalizeUrl(x.url) !== normalizedUrl;
475    });
476
477    items.unshift({
478      name: item.name,
479      url: normalizedUrl,
480      image: item.image || ""
481    });
482
483    if (items.length > MAX_ITEMS) {
484      items = items.slice(0, MAX_ITEMS);
485    }
486
487    saveItems(items);
488  }
489
490  function removeItem(url) {
491    var targetUrl = normalizeUrl(url);
492    var items = getItems().filter(function (item) {
493      return normalizeUrl(item.url) !== targetUrl;
494    });
495
496    saveItems(items);
497  }
498
499  function toggleItem(item) {
500    if (!item || !item.url) return false;
501
502    if (isFavorite(item.url)) {
503      removeItem(item.url);
504      return false;
505    }
506
507    addItem(item);
508    return true;
509  }
510
511  function getItemFromButton(button) {
512    return {
513      name: button.getAttribute("data-favorite-name") || "",
514      url: button.getAttribute("data-favorite-url") || "",
515      image: button.getAttribute("data-favorite-image") || ""
516    };
517  }
518
519  function syncButton(button) {
520    var url = button.getAttribute("data-favorite-url") || "";
521    var active = isFavorite(url);
522    var labelText = active ? "お気に入りから外す" : "お気に入りに追加";
523
524    button.classList.toggle("is-active", active);
525    button.setAttribute("aria-pressed", active ? "true" : "false");
526    button.setAttribute("aria-label", labelText);
527    button.setAttribute("title", labelText);
528
529    var heart = button.querySelector(".kgw-favorite-button__heart");
530    if (heart) {
531      heart.innerHTML = '<i class="fa-solid fa-heart" aria-hidden="true"></i>';
532    }
533
534    var text = button.querySelector(".kgw-favorite-button__text");
535    if (text) {
536      text.textContent = labelText;
537    }
538  }
539
540  function syncAllButtons() {
541    var buttons = document.querySelectorAll(".js-kgw-favorite-button");
542    buttons.forEach(function (button) {
543      syncButton(button);
544    });
545  }
546
547  function render(selector) {
548    var container = document.querySelector(selector || "#kgw-favorite-list");
549    var area = document.getElementById("kgw-favorite-area");
550
551    if (!container) return;
552
553    var items = getItems();
554
555    if (!items.length) {
556      container.innerHTML = '<p class="kgw-favorite-products--empty">お気に入り商品はまだありません。</p>';
557      if (area) area.style.display = "none";
558      return;
559    }
560
561    if (area) area.style.display = "";
562
563    container.innerHTML = items.map(function (item) {
564      var imageHtml = item.image
565        ? '<div class="kgw-favorite-item__image-wrap"><img class="kgw-favorite-item__image" src="' + escapeHtml(item.image) + '" alt="' + escapeHtml(item.name) + '"></div>'
566        : '<div class="kgw-favorite-item__image-wrap kgw-favorite-item__image-wrap--noimage"></div>';
567
568      return ''
569        + '<div class="kgw-favorite-item">'
570        +   '<a href="' + escapeHtml(item.url) + '">'
571        +     imageHtml
572        +     '<div class="kgw-favorite-item__name">' + escapeHtml(item.name) + '</div>'
573        +   '</a>'
574        +   '<button type="button" class="kgw-favorite-button kgw-favorite-button--card js-kgw-favorite-button"'
575        +     ' data-favorite-name="' + escapeHtml(item.name) + '"'
576        +     ' data-favorite-url="' + escapeHtml(item.url) + '"'
577        +     ' data-favorite-image="' + escapeHtml(item.image || "") + '"'
578        +     ' aria-pressed="true"'
579        +     ' aria-label="お気に入りから外す"'
580        +     ' title="お気に入りから外す">'
581        +     '<span class="kgw-favorite-button__heart" aria-hidden="true"><i class="fa-solid fa-heart"></i></span>'
582        +     '<span class="kgw-favorite-button__text">お気に入りから外す</span>'
583        +   '</button>'
584        + '</div>';
585    }).join("");
586
587    syncAllButtons();
588  }
589
590  document.addEventListener("click", function (e) {
591    var button = e.target.closest(".js-kgw-favorite-button");
592    if (!button) return;
593
594    e.preventDefault();
595    e.stopPropagation();
596
597    var item = getItemFromButton(button);
598    toggleItem(item);
599
600    syncAllButtons();
601    render("#kgw-favorite-list");
602  });
603
604  document.addEventListener("DOMContentLoaded", function () {
605    syncAllButtons();
606    render("#kgw-favorite-list");
607  });
608
609  window.KGWFavoriteItems = {
610    addItem: addItem,
611    removeItem: removeItem,
612    toggleItem: toggleItem,
613    isFavorite: isFavorite,
614    render: render,
615    syncAllButtons: syncAllButtons
616  };
617})();

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.