PageSourceSearch

https://cdn.grail.bz/js/design/common.js?lm=20261001105449

js grail.bz collected 2026-10-02 05:07:02 UTC 39,162 bytes, 1,243 lines download raw bytes

1/**
2 * common.js
3 */
4
5/* ----------------------------------------------------------
6 init
7---------------------------------------------------------- */
8$(function () {
9  bgGenerator();
10  navGlobal();
11  navGlobalSub();
12  navLocal();
13  headerHoriScroll();
14  headerSearch();
15  miniCart();
16  BoxCmnSearchSP();
17  pageScroll();
18  pageTopBtn();
19  lineClamp();
20  customModal();
21  commonAccordion();
22  telLink();
23  selectboxPlaceholder();
24  eyePeekPassword();
25  deliveryDateFix();
26  deliveryAddFavorite();
27//  deliveryCancelOrder();
28  exchangeModalChoice();
29  refundModalChoice();
30  countCheckbox();
31  fjBanner();
32});
33
34$(window).on('scroll', function() {
35  pageTopBtn();
36});
37
38/* ----------------------------------------------------------
39  clickEvent
40---------------------------------------------------------- */
41var clickEvent = 'click';
42if ('ontouchstart' in window || 'onmsgesturechange' in window) {
43  clickEvent = 'touchend';
44};
45
46/* ----------------------------------------------------------
47  check screen size
48---------------------------------------------------------- */
49var mq = window.matchMedia('screen and (min-width: 769px)');
50var isPC = mq.matches;
51
52mq.addListener(function () {
53  isPC = mq.matches;
54  $(window).trigger('breakpointChange');
55});
56
57/* ----------------------------------------------------------
58  lock screen
59---------------------------------------------------------- */
60var lockScreen = function () {
61  var $html = $('html');
62  var top   = $(window).scrollTop();
63
64  if(!$html.hasClass('is-fixed')) {
65    $html
66        .addClass('is-fixed')
67        .css({ top: (top * -1) })
68        .data('top', top);
69  }
70};
71var lockScreen_abs = function () {
72  var $html = $('html');
73  var $body = $('body');
74
75  if(!$html.hasClass('is-absolute')) {
76    $html
77        .addClass('is-absolute');
78    $body
79        .addClass('is-cart-modal-open');
80  }
81};
82
83/* ----------------------------------------------------------
84  unlock screen
85---------------------------------------------------------- */
86var unlockScreen = function () {
87  var $html = $('html');
88  var top   = $html.data('top') || 0;
89
90  if($html.hasClass('is-fixed')) {
91    $html
92        .removeClass('is-fixed')
93        .css({ top: '' });
94    $(window).scrollTop(top);
95  }
96};
97var unlockScreen_abs = function () {
98  var $html = $('html');
99  var $body = $('body');
100
101  if($html.hasClass('is-absolute')) {
102    $html
103        .removeClass('is-absolute');
104
105    $body
106        .removeClass('is-cart-modal-open');
107  }
108};
109/* ----------------------------------------------------------
110  pageScroll
111---------------------------------------------------------- */
112var pageScroll = function () {
113  $('.js-scroll').on('click', function () {
114    var speed = 400;
115    var href= $(this).attr("href") || '';
116    var minus = $('.header').height() || 0;
117    var target = $(href == '#' || href == '' ? 'html' : href);
118    var position = target.offset().top - minus;
119
120    if(href == '#'){
121      $('body,html').animate({scrollTop:0}, speed, 'swing');
122    } else {
123      $('body,html').animate({scrollTop:position}, speed, 'swing');
124    }
125
126    return false;
127  });
128};
129
130/* ----------------------------------------------------------
131  pageTopBtn
132---------------------------------------------------------- */
133var pageTopBtn = function () {
134  if ($('#btn-float-pagetop').length == 0) {
135    return false;
136  }
137
138  var winHeight = $(window).innerHeight();
139  var footerBtn = $('.btn-footer-pagetop').offset().top + 20;
140  var endPos = footerBtn - winHeight;
141  var $pageTop  = $('#btn-float-pagetop');
142  var scrollTop = $(window).scrollTop();
143  $pageTop.toggleClass('is-visible', ((isPC && scrollTop > 100) || (!isPC && scrollTop > 100 && scrollTop < endPos)));
144};
145
146/* ----------------------------------------------------------
147  navGlobal
148---------------------------------------------------------- */
149var navGlobal = function () {
150  var $nav = $('#nav-global');
151
152  var closeNavGlobal = function () {
153    $nav.removeClass('is-open');
154    $('#nav-global-overlay').fadeOut(200);
155    unlockScreen();
156  };
157
158  // create overlay element
159  $('<div id="nav-global-overlay" class="nav-global-overlay"></div>').appendTo('body');
160
161  $('#header-btn-menu').on('click', function () {
162    $nav
163        .toggleClass('is-open')
164        .find('.nav-global-scroller').scrollTop(0);
165    $('#nav-global-overlay').stop().fadeToggle(200);
166    lockScreen();
167  });
168
169  // close when clicked outside
170  $nav.on('click', function (e) {
171    var $target = $(e.target);
172    if ($target.closest('.nav-global-in').length === 0) {
173      closeNavGlobal();
174    }
175  });
176
177  // close button
178  $nav.children('.btn-close-menu').on('click', function () {
179    closeNavGlobal();
180  });
181
182  // close when breakpoint changed
183  $(window).on('breakpointChange', function () {
184    if (isPC && $nav.hasClass('is-open')) {
185      closeNavGlobal();
186    }
187  });
188
189  // swipe closing detection
190  var touchstartX = 0;
191  var touchendX = 0;
192  var touchstartY = 0;
193  var touchendY = 0;
194  var lengthX = 0;
195  var angleDeg = 0;
196  var gestureZone = document.getElementById('nav-global');
197
198  gestureZone.addEventListener('touchstart', function(event) {
199    touchstartX = event.changedTouches[0].screenX;
200    touchstartY = event.changedTouches[0].screenY;
201  }, false);
202
203  gestureZone.addEventListener('touchend', function(event) {
204    touchendX = event.changedTouches[0].screenX;
205    touchendY = event.changedTouches[0].screenY;
206    handleGesture();
207  }, false);
208
209  function handleGesture() {
210    lengthX = touchstartX - touchendX;
211    lengthY = touchstartY - touchendY;
212    angleDeg = Math.abs(Math.atan2(touchendY - touchstartY, touchendX - touchstartX) * 180 / Math.PI);
213
214    if (touchendX <= touchstartX && lengthX > 120 && angleDeg > 135) {
215      closeNavGlobal();
216    }
217  }
218};
219
220/* ----------------------------------------------------------
221  navGlobalSub
222---------------------------------------------------------- */
223var navGlobalSub = function () {
224  var $nav = $('#nav-global');
225
226  // check available nav-sub
227  $nav
228    .find('.nav-global-sub').siblings('.btn-nav-main')
229    .addClass('has-sub');
230
231  // fill nav-sub half column list
232  $nav.find('.list-nav-sub.col-half').each(function () {
233    var count = $(this).children('li').length;
234    if (count % 2 > 0) {
235      $(this).append('<li>&nbsp;</li>');
236    }
237  });
238
239  $nav.find('.btn-nav-main.has-sub').on('click', function (e) {
240    e.preventDefault();
241    $(this)
242      .toggleClass('is-open')
243      .next().stop().slideToggle(200);
244  });
245}
246
247/* ----------------------------------------------------------
248  headerHoriScroll
249---------------------------------------------------------- */
250var headerHoriScroll = function () {
251  var scrollLeft = 0;
252  var $header = $('#header');
253
254  $(window).on('scroll', function () {
255    if (isPC) {
256      scrollLeft = $(this).scrollLeft();
257      if (scrollLeft > 0) {
258        $header.css({ left: (scrollLeft * -1) })
259      }
260      else {
261        $header.css({ left: '' })
262      }
263    }
264    else {
265      $header.removeAttr('style')
266    }
267  });
268};
269
270/* ----------------------------------------------------------
271  headerSearch
272---------------------------------------------------------- */
273var headerSearch = function () {
274  var $header = $('#header');
275  var $headerSearch = $header.find('.header-search');
276  var $boxPoppular = $headerSearch.find('.box-search-popular');
277  var $boxSuggest = $headerSearch.find('.box-search-suggestion');
278
279  // search button SP
280  $header.find('.btn-search-sp').on('click', function () {
281    $boxPoppular.show();
282    $headerSearch.stop().fadeToggle(150, function () {
283      if (!isPC) {
284        // lockscreen
285        if ($(this).is(':visible')) {
286          lockScreen();
287        }
288        else {
289          unlockScreen();
290        }
291
292        // add maxHeight when screen is too short
293        var $boxList = $boxPoppular.find('.list-search-ranking');
294        var winHeight = $(window).innerHeight();
295        var scrollTop = $(window).scrollTop();
296        var offsetTop = $boxList.offset().top;
297        var height = (winHeight - (offsetTop - scrollTop)) - 70;
298        $boxList.css({
299          overflow: 'auto',
300          maxHeight: height
301        });
302      }
303    });
304  });
305
306  // SP close when click outside
307  $headerSearch.on('click', function(e) {
308    if (!isPC && $(e.target).closest('.header-search-in').length === 0) {
309      $headerSearch.stop().fadeOut(150);
310      $boxSuggest.stop().fadeOut(150);
311      unlockScreen();
312    }
313  });
314
315  var closeSearchPC = function (e) {
316    if ($(e.target).closest('.mod-cmn-search').length ===0) {
317      $boxPoppular.stop().fadeOut(150);
318      $boxSuggest.stop().fadeOut(150);
319    }
320  }
321
322  // popular keyword & search suggestion
323  $headerSearch.find('.input-search')
324    // show popular keyword when focus
325    .on('focus', function () {
326      if (isPC && $(this).val() === '') {
327        $boxPoppular.stop().fadeIn(150);
328        $(document).on('click', closeSearchPC);
329      }
330    })
331    // show search suggestion when typing
332    .on('keyup', function () {
333      if ($(this).val().trim() !== '') {
334        $boxPoppular.stop().fadeOut(150);
335        $boxSuggest.stop().fadeIn(150);
336        //サジェスト表示
337        search_word_zeta_suggest_call_api();
338      }
339    });
340
341  // reset when breakpoint changed
342  $(window).on('breakpointChange', function () {
343    if (isPC) {
344      $headerSearch.removeAttr('style');
345      $boxPoppular.find('.list-search-ranking').removeAttr('style');
346      unlockScreen();
347    }
348  });
349
350  if (window.location.hash == '#search-box') {
351    if (isPC) {
352      $headerSearch.find('.input-search').trigger('focus');
353    } else {
354      $header.find('.btn-search-sp').trigger('click');
355    }
356    window.location.hash = '';
357  }
358};
359
360/* ----------------------------------------------------------
361  navLocal
362---------------------------------------------------------- */
363var navLocal = function () {
364  $('.nav-local').find('.nav-local-sub').each(function () {
365    var closeTimer, openTimer;
366    var $navSub = $(this);
367
368    // hover event for PC
369    $navSub.parent('li').on('mouseenter', function () {
370      var $self = $(this);
371
372      if (isPC) {
373        clearTimeout(closeTimer);
374        openTimer = setTimeout(function () {
375          $self.children('.btn-nav-main').addClass('is-active');
376          $self.children('.nav-local-sub').stop().fadeIn(150);
377        }, 200);
378      }
379    })
380    .on('mouseleave', function () {
381      var $self = $(this);
382
383      if (isPC) {
384        clearTimeout(openTimer);
385        closeTimer = setTimeout(function() {
386          $self.children('.btn-nav-main').removeClass('is-active');
387          $self.children('.nav-local-sub').stop().fadeOut(150);
388        }, 200);
389      }
390    });
391
392    // click event for SP
393    $navSub.siblings('.btn-nav-main').addClass('has-sub');
394    $navSub.siblings('.btn-nav-main.has-sub').on('click', function (e) {
395      if (!isPC) {
396        e.preventDefault();
397        $(this)
398          .toggleClass('is-open')
399          .next().stop().slideToggle(200);
400      }
401    });
402  });
403};
404
405/* ----------------------------------------------------------
406  mini cart
407---------------------------------------------------------- */
408var miniCart = function () {
409  var $miniCart = $('#mod-mini-cart');
410
411  function heightCalc () {
412    // temporarily visible
413    var isOpen = false;
414    if ($miniCart.is(':hidden')) {
415      isOpen = true;
416      $miniCart.css({
417        display: 'block',
418        visibility: 'hidden'
419      });
420    }
421
422    var $boxCart = $miniCart.find('.box-cart-detail');
423    var winHeight = $(window).innerHeight();
424    var scrollTop = $(window).scrollTop();
425    var offsetTop = $boxCart.offset().top;
426    var height = (winHeight - (offsetTop - scrollTop));
427
428    $boxCart.css({ maxHeight: '' });
429
430    if (offsetTop + $boxCart.height() > scrollTop + winHeight) {
431      if (!isPC && height > 440) {
432        height = 440;
433      }
434
435      $boxCart.css({
436        overflow: 'auto',
437        maxHeight: height
438      });
439    }
440
441    // clear stlye
442    if (isOpen) {
443      $miniCart.removeAttr('style');
444    }
445  }
446
447  $('#btn-mini-cart').on('click', function () {
448    // lock or unlockscreen
449    if (!isPC && $miniCart.is(':hidden')) {
450      lockScreen_abs();
451    }
452    else if (!isPC && $miniCart.is(':visible')) {
453      unlockScreen_abs();
454    }
455
456    // calculate height before show
457    if ($miniCart.find('.box-cart-detail').length > 0) {
458      heightCalc();
459    }
460
461    $miniCart.stop().fadeToggle(150);
462  });
463
464  // resize event
465  var resizeTimer;
466  $(window).on('resize', function(e) {
467    clearTimeout(resizeTimer);
468    resizeTimer = setTimeout(function() {
469      if ($miniCart.is(':visible') && $miniCart.find('.box-cart-detail').length > 0) {
470        heightCalc();
471      }
472    }, 200);
473  });
474
475  // close button
476  $miniCart.find('.btn-close').on('click', function () {
477    $miniCart.stop().fadeOut(150);
478    if (!isPC) {
479      unlockScreen_abs();
480    }
481  });
482
483  // close when click outside
484  $(document).on(clickEvent + '.minicart', function (e) {
485    if ($miniCart.is(':visible')
486      && $(e.target).closest('.mod-mini-cart').length === 0
487      && !$(e.target).is('#btn-mini-cart')
488      && $(e.target).closest('#btn-mini-cart').length === 0) {
489      $miniCart.stop().fadeOut(150);
490      if (!isPC) {
491        unlockScreen_abs();
492      }
493    }
494  });
495
496  // update button
497  $miniCart.find('.card-product-cart-01').each(function () {
498    var $card = $(this);
499    $card.find('.select-quantity').children('select').on('change', function () {
500      $card.find('.btn-update').addClass('is-visible');
501    })
502  });
503};
504
505/* ----------------------------------------------------------
506  background generator
507---------------------------------------------------------- */
508var bgGenerator = function () {
509  $('[data-bg-image]').each(function () {
510    var bgPath = $(this).data('bg-image');
511    $(this).css('background-image', 'url(' + bgPath + ')');
512  });
513};
514
515/* ----------------------------------------------------------
516  search box in SP content area
517---------------------------------------------------------- */
518var BoxCmnSearchSP = function () {
519  $('.js-box-search-sp').each(function () {
520    var $this = $(this);
521    var $boxPoppular = $this.find('.box-search-popular');
522    var $boxSuggest = $this.find('.box-search-suggestion');
523
524    $this.find('.input-search').on('focus', function () {
525      if ($(this).val() === '') {
526        $boxPoppular.stop().fadeIn(150);
527      }
528    }).on('blur', function () {
529      $boxPoppular.stop().fadeOut(150);
530      $boxSuggest.stop().fadeOut(150);
531    }).on('keyup', function () {
532      if ($(this).val().trim() !== '') {
533        $boxPoppular.stop().fadeOut(150);
534        $boxSuggest.stop().fadeIn(150);
535        //サジェスト表示
536        search_word_sp_zeta_suggest_call_api();
537      }
538    });
539  });
540};
541
542/* ----------------------------------------------------------
543  lineClamp
544---------------------------------------------------------- */
545var lineClamp = function () {
546  if (typeof(webkitLineClamp) === 'undefined' || !isPC) {
547    return false;
548  }
549
550  $('.js-line-clamp').each(function () {
551    var maxLine = $(this).data('line-clamp') || 2;
552    webkitLineClamp($(this)[0], maxLine);
553  });
554};
555
556/* ----------------------------------------------------------
557  customModal
558---------------------------------------------------------- */
559var customModal = function (btn) {
560  var ua = window.navigator.userAgent;
561  var msie = ua.indexOf("MSIE ");
562  var $modal = $('#modal-cmn-container');
563  var closeTimeout;
564
565  var closeModal = function () {
566    clearTimeout(closeTimeout);
567    $modal.stop().fadeOut(200, function () {
568      $(this).find('.modal-content').hide();
569      $(this).trigger("fadeOutComplete");
570    });
571    unlockScreen();
572  };
573
574
575  var button = btn != undefined ? $(btn) : $('.js-open-modal')
576
577  button.on('click', function (e) {
578    e.preventDefault();
579    var target = $(this).attr('href') || '';
580    var closeTime = $(this).data('modal-close') || 0;
581
582    // set content height for IE
583    if (isPC && msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) {
584      var $clone = $(target).clone();
585      var height = 0;
586
587      $clone.css({
588        position: 'absolute',
589        zIndex: '-1',
590        display: 'block',
591        visibility: 'hidden'
592      });
593  
594      $('body').append($clone);
595      height = $clone.outerHeight(true);
596      $clone.remove();
597      $modal.find('.modal-inner').height(height);
598
599      if($('.exchange').length){
600        $('.exchange .modal-inner').height('664px').css('box-sizing','border-box');
601      }
602    }
603
604    // open main modal
605    if($modal.is(':hidden')) {
606      lockScreen();
607      $(target).show();
608      $modal.stop().fadeIn(200, function() {
609        $(this).trigger("fadeInComplete");
610      });
611    }
612    // if modal is already opened then swap content
613    else {
614      $modal.find('.modal-content:visible').fadeOut(150, function () {
615        $(this).trigger("fadeOutComplete");
616        $(target).stop().fadeIn(200, function() {
617          $(this).trigger("fadeOutComplete");
618        });
619      });
620    }
621
622    // auto close setting
623    if (closeTime > 0) {
624      closeTimeout = setTimeout(closeModal, (closeTime * 1000));
625    }
626  });
627
628  // close modal events
629  $modal.on('click', function (e) {
630    if ($(e.target).closest('.modal-content').length === 0 
631        || $(e.target).closest('.js-close-modal-btn').length === 1
632        || $(e.target).hasClass('.js-close-modal-btn')) {
633      closeModal();
634      return false;
635    }
636  });
637
638  // close modal btn
639  $('.js-close-modal').on('click', closeModal);
640};
641
642/* ----------------------------------------------------------
643  common accordion
644---------------------------------------------------------- */
645var commonAccordion = function () {
646  $('.js-cmn-accordion').on('click', function (e) {
647    e.preventDefault();
648    var $self = $(this);
649
650    if (!isPC && !$(this).hasClass('is-active')) {
651      $('.js-cmn-accordion.is-active')
652        .removeClass('is-active')
653        .next().stop().slideUp(200);
654      $self
655        .toggleClass('is-active')
656        .next().stop().slideToggle(200, function () {
657          var header = $('#header').length ? $('#header').height() : 0;
658          var pos = $self.offset().top - header;
659          $('body, html').animate({ scrollTop: pos }, 400, 'swing');
660        });
661    }
662    else {
663      $(this)
664        .toggleClass('is-active')
665        .next().stop().slideToggle(250);
666    }
667  });
668};
669
670/* ----------------------------------------------------------
671  telLink
672---------------------------------------------------------- */
673var telLink = function () {
674  var ua = navigator.userAgent;
675  if (ua.indexOf('iPhone') < 0 && ua.indexOf('Android') < 0) {
676    $('.js-tel-link').each(function () {
677      var html = $(this).html();
678      var cls  = $(this).attr('class');
679      $(this).replaceWith( '<span class="' + cls + '">' + html + '</span>');
680    });
681  }
682};
683
684/* ----------------------------------------------------------
685  selectboxPlaceholder
686---------------------------------------------------------- */
687var selectboxPlaceholder = function () {
688  $('.js-select-placeholder').each(function () {
689    if ($(this).val() === '') {
690      $(this).addClass('is-placeholder');
691    }
692
693    $(this).on('change', function () {
694      $(this).toggleClass('is-placeholder', $(this).val() === '');
695    });
696  });
697};
698
699/* ----------------------------------------------------------
700  eyePeekPassword
701---------------------------------------------------------- */
702var eyePeekPassword = function () {
703  $('.form-cmn-eye-peek').each(function () {
704    $(this).find('.btn-eye-peek').on('click', function () {
705      $(this)
706        .toggleClass('is-active')
707        .siblings('input')
708        .attr('type', function(index, attr) {
709          return attr === 'password' ? 'text' : 'password';
710        });
711    });
712  });
713};
714
715/*--2020/09/04 add--*/
716/* ----------------------------------------------------------
717  deliveryDateFix
718---------------------------------------------------------- */
719var deliveryDateFix = function () {
720  $('.box-order-detail-delivery select').change(function() {
721    // var val = $(this).val();
722      if ($(".btn-fix-delivery").hasClass('is-hidden')) {
723        $('.btn-fix-delivery').removeClass("is-hidden").addClass("is-show");
724      }
725      return false;
726  });
727  $('.btn-fix-delivery').on('click', function() {
728      if ($(".btn-fix-delivery").hasClass('is-show')) {
729        $('.btn-fix-delivery').removeClass("is-show").addClass("is-hidden");
730      }
731      return false;
732  });
733};
734
735/* ----------------------------------------------------------
736  deliveryAddFavorite
737---------------------------------------------------------- */
738var deliveryAddFavorite = function () {
739  $('.btn-add-favorite .btn').on("click", function(){
740    if ($(this).hasClass('is-off')) {
741      $(this).children().text("お気に入り登録済み");
742      $(this).removeClass("is-off").addClass("is-on");
743    }
744    else {
745      $(this).children().text("お気に入りに追加する");
746      $(this).removeClass("is-on").addClass("is-off");
747    }
748    return false;
749  });
750};
751
752/* ----------------------------------------------------------
753  deliveryCancelOrder
754---------------------------------------------------------- */
755var deliveryCancelOrder = function () {
756    var this_btn = $('.btn-cancel-delivery .btn');
757    this_btn.children().text("カートに入れる");
758    this_btn.removeClass("is-off").addClass("is-on");
759};
760/* ----------------------------------------------------------
761  exchangeModalChoice
762---------------------------------------------------------- */
763var exchangeModalChoice = function () {
764  $('.modal-cmn-container.exchange .btn-buy.choice.stock').on("click", function(){
765    $(".box-item-info-in.after.stock").addClass("is-active");
766    return false;
767  });
768};
769
770/* ----------------------------------------------------------
771  refundModalChoice
772---------------------------------------------------------- */
773var refundModalChoice = function () {
774  $('.modal-cmn-container.exchange .btn-buy.choice.refund').on("click", function(){
775    $(".box-item-info.after .btn-exchange").addClass("is-hidden");
776    $(".box-item-info-in.after.refund").addClass("is-active");
777    return false;
778  });
779};
780
781/* ----------------------------------------------------------
782  exchangeModalSwitch
783---------------------------------------------------------- */
784var exchangeModalSwitch = function () {
785  $(window).on('load resize', function(){
786    var winW = $(window).width();
787    var devW = 768;
788    if (winW <= devW) {
789      let link = document.getElementById('switchDevice');
790      let oldHref = link.getAttribute('href');
791      let newHref = oldHref.replace('#modal-colorsizefix-confirm-pc', '#modal-colorsizefix-confirm-sp');
792      link.setAttribute('href', newHref);
793    }
794    return false;
795  });
796};
797
798/* ----------------------------------------------------------
799  countCheckbox
800---------------------------------------------------------- */
801var countCheckbox = function () {
802  $("input[type=checkbox]").click(function(){
803    if ($(this).hasClass('s-reason-exchange')) {
804      var $count = $("input[type=checkbox]:checked").length;
805      var $not = $('input[type=checkbox]').not(':checked')
806
807      if($count >= 2) {
808        $not.attr("disabled",true);
809      }else{
810        $not.attr("disabled",false);
811      }
812    }
813  });
814};
815
816/* ----------------------------------------------------------
817  fjBanner(ORDER from overseas)
818---------------------------------------------------------- */
819var fjBanner = function () {
820	if (document.querySelectorAll("#fjbanner > .space").length) {
821		if ($('.bnr-cmn-notice').length) {
822			$('.bnr-cmn-notice').removeClass('mt-pc-60 mt-sp-60');
823		} else {
824			$('.hero-cmn-01').removeClass('mt-pc-60 mt-sp-60');
825			if ($('.nav-breadcrumb').length) {
826				$('.nav-breadcrumb').removeClass('mt-pc-60 mt-sp-60');
827			} else {
828				$('.contents-normal').removeClass('mt-pc-60 mt-sp-60');
829			}
830		}
831	} else if (document.querySelectorAll("#fjbanner > *").length) {
832		if ($('.bnr-cmn-notice').length) {
833			$('.bnr-cmn-notice').addClass('mt-pc-60 mt-sp-60');
834		} else {
835			$('.hero-cmn-01').addClass('mt-pc-60 mt-sp-60');
836			if ($('.nav-breadcrumb').length) {
837				$('.nav-breadcrumb').addClass('mt-pc-60 mt-sp-60');
838			} else {
839				$('.contents-normal').addClass('mt-pc-60 mt-sp-60');
840			}
841		}
842	}
843};
844
845/* ----------------------------------------------------------
846  drawerMenu
847---------------------------------------------------------- */
848(() => {
849  const drawerButton = document.querySelector(".js-drawer-button");
850  if (!drawerButton) return;
851  const drawerMenu = document.querySelector(".js-drawer-menu");
852  const menuItems = drawerMenu.querySelectorAll(".js-menu-list li button");
853  const closeButton = document.querySelector(".js-drawer-close");
854
855  function openMenu() {
856    document.body.style.overflow = "hidden";
857    drawerButton.setAttribute("aria-expanded", "true");
858    drawerMenu.dataset.expanded = "true";
859  }
860
861  function closeMenu() {
862    document.body.style.overflow = "initial";
863    drawerButton.setAttribute("aria-expanded", "false");
864    drawerMenu.dataset.expanded = "false";
865  }
866
867  drawerButton.addEventListener("click", () => {
868    (drawerMenu.dataset.expanded === "true" ? closeMenu : openMenu)();
869  });
870
871  menuItems.forEach((item) => {
872    item.addEventListener("click", closeMenu);
873  });
874
875  closeButton.addEventListener("click", closeMenu);
876})();
877
878/* ----------------------------------------------------------
879  Tab
880---------------------------------------------------------- */
881(() => {
882  const tabs = document.querySelectorAll('[role="tab"]');
883  const tabPanels = document.querySelectorAll('[role="tabpanel"]');
884  if (!tabs.length || !tabPanels.length) return;
885
886  function changeTab(selectedTab) {
887    tabs.forEach((tab) => {
888      const isActive = tab === selectedTab;
889      tab.classList.toggle("is-active", isActive);
890      tab.setAttribute("aria-selected", isActive);
891      tab.setAttribute("tabindex", isActive ? "0" : "-1");
892    });
893
894    tabPanels.forEach((panel) => {
895      panel.toggleAttribute("hidden", panel.getAttribute("aria-labelledby") !== selectedTab.id);
896      panel.setAttribute("tabindex", panel.hidden ? "-1" : "0");
897    });
898  }
899
900  tabs.forEach((tab) => tab.addEventListener("click", () => changeTab(tab)));
901})();
902
903/* ----------------------------------------------------------
904  Filter Drawer
905---------------------------------------------------------- */
906(() => {
907  const drawerMenu = document.querySelector(".js-drawer-menu");
908  if (!drawerMenu) return;
909
910  function preparePanel(panelId) {
911    if (typeof window.prepareSpSubCategoryPanel === "function") {
912      window.prepareSpSubCategoryPanel(panelId);
913    }
914    return document.getElementById(panelId);
915  }
916
917  function closePanel(panel) {
918    if (!panel) return;
919    panel.dataset.expanded = "false";
920    panel.hidden = true;
921  }
922
923  function getValueTrigger(panelId) {
924    return Array.from(drawerMenu.querySelectorAll(".js-trigger")).find((trigger) => {
925      return trigger.getAttribute("aria-controls") === panelId && trigger.querySelector(".js-value");
926    });
927  }
928
929  drawerMenu.addEventListener("click", (event) => {
930    const backButton = event.target.closest(".js-panel-back");
931    if (backButton) {
932      closePanel(backButton.closest(".sub-filter"));
933      return;
934    }
935
936    const trigger = event.target.closest(".js-trigger");
937    if (!trigger || !drawerMenu.contains(trigger)) return;
938
939    const panelId = trigger.getAttribute("aria-controls");
940    const panel = preparePanel(panelId);
941    if (!panel) return;
942
943    panel.dataset.expanded = "true";
944    panel.hidden = false;
945  });
946
947  drawerMenu.addEventListener("change", (event) => {
948    const input = event.target;
949    if (!input.matches('input[type="radio"], input[type="checkbox"]')) return;
950
951    const panel = input.closest(".sub-filter");
952    if (!panel) return;
953
954    const panelId = panel.id;
955    const subCategoryTrigger = drawerMenu.querySelector(".js-sub-category");
956    const subCategoryValueDisplay = subCategoryTrigger ? subCategoryTrigger.querySelector(".js-value") : null;
957
958    if (input.type === "radio") {
959      const selectedValue = input.value;
960      const valueTrigger = getValueTrigger(panelId);
961      const valueDisplay = valueTrigger ? valueTrigger.querySelector(".js-value") : null;
962
963      if (valueDisplay) {
964        valueDisplay.textContent = selectedValue;
965      }
966
967      if (panelId === "category-panel-1") {
968        const categoryTrigger = input.closest(".js-trigger");
969        const selectedAriaControls = categoryTrigger ? categoryTrigger.getAttribute("aria-controls") : null;
970        preparePanel(selectedAriaControls);
971
972        if (subCategoryTrigger && selectedAriaControls) {
973          subCategoryTrigger.setAttribute("aria-controls", selectedAriaControls);
974        }
975        if (subCategoryValueDisplay) {
976          subCategoryValueDisplay.textContent = selectedValue;
977        }
978      } else {
979        closePanel(panel);
980        closePanel(document.getElementById("category-panel-1"));
981
982        if (subCategoryValueDisplay && panelId.indexOf("-sub-panel-1") > 0) {
983          subCategoryValueDisplay.textContent = selectedValue;
984        }
985      }
986      return;
987    }
988
989    const checkboxes = panel.querySelectorAll('input[type="checkbox"]');
990    const selectedValues = Array.from(checkboxes)
991      .filter((checkbox) => checkbox.checked)
992      .map((checkbox) => checkbox.value);
993
994    const valueTrigger = getValueTrigger(panelId);
995    const valueDisplay = valueTrigger ? valueTrigger.querySelector(".js-value") : null;
996    if (valueDisplay) {
997      valueDisplay.textContent = selectedValues.length ? selectedValues.join(" / ") : "指定なし";
998    }
999  });
1000})();
1001/* ----------------------------------------------------------
1002  Tag Toggle
1003  zeta.suggest-src.jsに移動
1004---------------------------------------------------------- */
1005//(() => {
1006//  const selectedTagsContainer = document.querySelector(".js-selected-tags");
1007//  if (!selectedTagsContainer) return;
1008//  const addTagContainer = document.querySelector(".tag-list.add");
1009//  const addTagButtons = document.querySelectorAll(".js-add-tag");
1010//  const tagSearch = document.querySelector(".js-tag-search");
1011//  const suggestionList = document.querySelector(".js-tag-suggestion-list");
1012//
1013//  const allTags = [
1014//    { name: "トップス", kana: "とっぷす" },
1015//    { name: "シャツ", kana: "しゃつ" },
1016//    { name: "ワンピース", kana: "わんぴーす" },
1017//    { name: "ボトムス", kana: "ぼとむす" },
1018//    { name: "ジャケット", kana: "じゃけっと" },
1019//    { name: "パンツ", kana: "ぱんつ" },
1020//    { name: "スカート", kana: "すかーと" },
1021//    { name: "アウター", kana: "あうたー" },
1022//    { name: "秋", kana: "あき" },
1023//  ];
1024//
1025//  function updateTags() {
1026//    const tags = Array.from(selectedTagsContainer.children).map((li) => li.dataset.tag);
1027//    const removeButtons = selectedTagsContainer.querySelectorAll(".js-remove-tag");
1028//
1029//    document.querySelectorAll(".hidden-tag").forEach((input) => input.remove());
1030//
1031//    tags.forEach((tag) => {
1032//      const input = document.createElement("input");
1033//      input.type = "hidden";
1034//      input.name = "tags[]";
1035//      input.value = tag;
1036//      input.classList.add("hidden-tag");
1037//      document.getElementById("tag-form").appendChild(input);
1038//    });
1039//
1040//    removeButtons.forEach((removeButton) => {
1041//      removeButton.addEventListener("click", (event) => {
1042//        const li = event.target.closest("li");
1043//        const tagName = li.dataset.tag;
1044//        li.remove();
1045//
1046//        // 関連タグに戻す(先頭に追加)
1047//        const isAlreadyInAddList = addTagContainer.querySelector(`[data-tag="${tagName}"]`);
1048//        if (!isAlreadyInAddList) {
1049//          const newLi = document.createElement("li");
1050//          newLi.innerHTML = `<button type="button" class="add-tag js-add-tag" data-tag="${tagName}">${tagName}</button>`;
1051//          addTagContainer.prepend(newLi);
1052//
1053//          newLi.querySelector("button").addEventListener("click", () => {
1054//            addTag(tagName);
1055//            newLi.remove();
1056//          });
1057//        }
1058//
1059//        updateTags();
1060//      });
1061//    });
1062//  }
1063//
1064//  function addTag(tag) {
1065//    if ([...selectedTagsContainer.children].some((li) => li.dataset.tag === tag)) return;
1066//    if (selectedTagsContainer.children.length >= 4) return;
1067//
1068//    const li = document.createElement("li");
1069//    li.dataset.tag = tag;
1070//    li.innerHTML = `<span class="remove-tag">${tag}<button type="button" class="js-remove-tag">✕</button></span>`;
1071//    selectedTagsContainer.prepend(li); // 先頭に追加
1072//    updateTags();
1073//  }
1074//
1075//  addTagButtons.forEach((button) => {
1076//    button.addEventListener("click", () => {
1077//      const tag = button.dataset.tag;
1078//      addTag(tag);
1079//      button.closest("li").remove(); // 関連タグから削除
1080//    });
1081//  });
1082//
1083//  function toHiragana(str) {
1084//    return str.replace(/[\u30A1-\u30FA]/g, (match) => String.fromCharCode(match.charCodeAt(0) - 0x60));
1085//  }
1086//
1087//  tagSearch.addEventListener("input", () => {
1088//    const query = tagSearch.value.trim().toLowerCase();
1089//    const queryHiragana = toHiragana(query);
1090//    suggestionList.innerHTML = "";
1091//
1092//    if (!query) {
1093//      suggestionList.style.display = "none";
1094//      return;
1095//    }
1096//
1097//    const selectedTags = Array.from(selectedTagsContainer.children).map((li) => li.dataset.tag);
1098//    const filteredTags = allTags.filter((tag) => (tag.name.toLowerCase().startsWith(query) || tag.kana.startsWith(queryHiragana)) && !selectedTags.includes(tag.name));
1099//
1100//    if (filteredTags.length === 0) {
1101//      suggestionList.style.display = "none";
1102//      return;
1103//    }
1104//
1105//    filteredTags.forEach((tag) => {
1106//      const li = document.createElement("li");
1107//      li.innerHTML = `<button class="tag-suggestion-item" type="button" data-tag="${tag.name}" tabindex="2">${tag.name}</button>`;
1108//
1109//      const button = li.querySelector("button");
1110//      button.addEventListener("click", () => {
1111//        if (selectedTagsContainer.children.length >= 4) return;
1112//
1113//        // 関連タグに同じものがあれば削除
1114//        const existingAddTag = addTagContainer.querySelector(`[data-tag="${tag.name}"]`);
1115//        if (existingAddTag) {
1116//          existingAddTag.closest("li").remove();
1117//        }
1118//
1119//        const newLi = document.createElement("li");
1120//        newLi.dataset.tag = tag.name;
1121//        newLi.innerHTML = `<span class="remove-tag">${tag.name}<button type="button" class="js-remove-tag">✕</button></span>`;
1122//        selectedTagsContainer.prepend(newLi); // サジェストも先頭に追加
1123//        updateTags();
1124//
1125//        tagSearch.value = "";
1126//        suggestionList.style.display = "none";
1127//      });
1128//
1129//      suggestionList.appendChild(li);
1130//    });
1131//
1132//    suggestionList.style.display = "block";
1133//  });
1134//
1135//  document.addEventListener("click", (event) => {
1136//    if (!tagSearch.contains(event.target) && !suggestionList.contains(event.target)) {
1137//      suggestionList.style.display = "none";
1138//    }
1139//  });
1140//})();
1141
1142/* ----------------------------------------------------------
1143  Tag Toggle
1144---------------------------------------------------------- */
1145(() => {
1146  const searchInput = document.querySelector(".js-keyword-search");
1147  if (!searchInput) return;
1148  const suggestionBox = document.querySelector(".js-keyword-suggestion");
1149
1150  searchInput.addEventListener("input", () => {
1151    if (searchInput.value.trim() !== "") {
1152      suggestionBox.classList.add("is-active");
1153    } else {
1154      suggestionBox.classList.remove("is-active");
1155    }
1156  });
1157
1158  document.addEventListener("click", (e) => {
1159    if (!searchInput.contains(e.target) && !suggestionBox.contains(e.target)) {
1160      suggestionBox.classList.remove("is-active");
1161    }
1162  });
1163})();
1164
1165/* ----------------------------------------------------------
1166Shipping list
1167---------------------------------------------------------- */
1168(() => {
1169const shippingLists = document.querySelectorAll(".js-shipping-list");
1170if (!shippingLists) return;
1171
1172shippingLists.forEach(function (list) {
1173  const items = list.querySelectorAll("li");
1174  const totalCount = items.length;
1175
1176  items.forEach(function (item, index) {
1177    if (index >= 4) {
1178      item.style.display = "none";
1179    }
1180  });
1181
1182  if (totalCount >= 5) {
1183    const totalElement = document.createElement("p");
1184    totalElement.className = "total js-shipping-total";
1185    totalElement.textContent = `合計${totalCount}件の商品が含まれています。`;
1186
1187    list.insertAdjacentElement("afterend", totalElement);
1188  }
1189});
1190})();
1191
1192/* ----------------------------------------------------------
1193Shipping progress
1194---------------------------------------------------------- */
1195(() => {
1196const progressElement = document.querySelector(".js-progress");
1197if (!progressElement) return;
1198const step = parseInt(progressElement.getAttribute("data-step"), 10);
1199const stepList = progressElement.querySelector(".js-step-list");
1200const listItems = stepList.querySelectorAll("li");
1201const currentElement = progressElement.querySelector(".js-progress-current");
1202
1203if (currentElement && listItems[step - 1]) {
1204  currentElement.textContent = listItems[step - 1].textContent;
1205}
1206
1207listItems.forEach(function (item, index) {
1208  if (index < step) {
1209    item.classList.add("completed");
1210  }
1211});
1212})();
1213
1214/* ----------------------------------------------------------
1215Shipping select
1216---------------------------------------------------------- */
1217(() => {
1218const trigger = document.querySelector(".js-select-trigger");
1219const dropdown = document.querySelector(".js-select-dropdown");
1220if (!trigger) return;
1221
1222function toggleDropdown() {
1223  trigger.classList.toggle("is-open");
1224  dropdown.classList.toggle("is-open");
1225}
1226
1227function closeDropdown() {
1228  trigger.classList.remove("is-open");
1229  dropdown.classList.remove("is-open");
1230}
1231
1232trigger.addEventListener("click", function (e) {
1233  e.stopPropagation();
1234  toggleDropdown();
1235});
1236
1237dropdown.addEventListener("click", function (e) {
1238  e.stopPropagation();
1239});
1240
1241document.addEventListener("click", closeDropdown);
1242})();
1243

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.