PageSourceSearch

https://www.mir.co.jp/common/js/common.js

js mir.co.jp collected 2026-10-02 03:57:17 UTC 71,295 bytes, 2,117 lines download raw bytes

1/**
2 * common.js
3 *
4 * @version 1.1.0
5 * @namespace
6 * @constructor
7 * @module
8 * @execution
9 * @requires
10 * - jquery.js
11 * - jquery.cookie.js
12 * - jquery.colorbox.js
13 * - slick.js
14 */
15
16
17/**
18 * @namespace COMMON
19 */
20var COMMON = COMMON || {};
21
22
23/**
24 * @constructor Util
25 */
26COMMON.Util = function(){
27  'use strict';
28  this.$win = $(window);
29  this.$doc = $(document);
30  this.ua = navigator.userAgent.toLowerCase();
31  this.ver = window.navigator.appVersion.toLowerCase();
32  this.url = location.href;
33  this.path = location.pathname.replace('index.html', '');
34  this.dir = this.path.split('/');
35  this.hash = location.hash;
36  this.query = location.search;
37  this.view = 1530;
38  this.breakPoint1 = 767;
39  this.state = {
40    current: 'is-current',
41    open: 'is-open',
42    active: 'is-active',
43    hidden: 'is-hidden',
44    fixed: 'is-fixed',
45    disabled: 'is-disabled',
46    selected: 'is-selected',
47    safety: 'is-safety',
48    ready: 'is-ready',
49    new: 'is-new'
50  };
51  this.param = {
52    open: 'open',
53    move: 'move'
54  };
55  this.factor = {
56    equalHeight: '.js-equalHeight'
57  };
58};
59
60COMMON.Util.prototype = {
61  /**
62   * @method isRangeSP
63   * @return {Boolean}
64   */
65  isRangeSP: function(){
66    'use strict';
67    var clientW = document.documentElement.clientWidth,
68        winW = window.innerWidth ? window.innerWidth : (this.$win.width() ? this.$win.width() : clientW);
69    return (winW <= this.breakPoint1) ? true : false;
70  },
71  /**
72   * @method isRangePC
73   * @return {Boolean}
74   */
75  isRangePC: function(){
76    'use strict';
77    var clientW = document.documentElement.clientWidth,
78        winW = window.innerWidth ? window.innerWidth : (this.$win.width() ? this.$win.width() : clientW);
79    return (this.breakPoint1 < winW) ? true : false;
80  },
81  /**
82   * @method deviceChecker
83   * @return {String}
84   */
85  deviceChecker: function(){
86    'use strict';
87    if(this.ua.indexOf('iphone') !== -1) { return 'iphone'; }
88    else if(this.ua.indexOf('ipod') !== -1) { return 'ipod'; }
89    else if(this.ua.indexOf('ipad') !== -1) { return 'ipad'; }
90    else if(this.ua.indexOf('android') !== -1 && this.ua.indexOf('mobile') !== -1) { return 'android mobile'; }
91    else if(this.ua.indexOf('android') !== -1 && this.ua.indexOf('mobile') === -1) { return 'android tablet'; }
92    else if(this.ua.indexOf('windows phone') !== -1) { return 'windows phone'; }
93    else { return 'desktop'; }
94  },
95  /**
96   * @method winOSChecker
97   * @return {String}
98   */
99  winOSChecker: function(){
100    'use strict';
101    if(this.ua.match(/win(dows )?nt 10\.0/)) { return 'win10'; }
102    else if(this.ua.match(/win(dows )?nt 6\.3/)) { return 'win8.1'; }
103    else if(this.ua.match(/win(dows )?nt 6\.2/)) { return 'win8'; }
104    else if(this.ua.match(/win(dows )?nt 6\.1/)) { return 'win7'; }
105    else { return false; }
106  },
107  /**
108   * @method isMobile
109   * @return {Boolean}
110   */
111  isMobile: function(){
112    'use strict';
113    return (this.deviceChecker() === 'iphone' || this.deviceChecker() === 'ipod' || this.deviceChecker() === 'android mobile' || this.deviceChecker() === 'windows phone') ? true : false;
114  },
115  /**
116   * @method isTablet
117   * @return {Boolean}
118   */
119  isTablet: function(){
120    'use strict';
121    return (this.deviceChecker() === 'ipad' || this.deviceChecker() === 'android tablet') ? true : false;
122  },
123  /**
124   * @method isDesktop
125   * @return {Boolean}
126   */
127  isDesktop: function(){
128    'use strict';
129    return (!this.isMobile() && !this.isTablet()) ? true : false;
130  },
131  /**
132   * @method isBrowser
133   * @param {String}
134   * @return {Boolean}
135   */
136  isBrowser: function(_browser){
137    'use strict';
138    var browser = ['chrome', 'safari', 'firefox', 'edge', 'ie11'],
139        browser_old = ['ie8', 'ie9', 'ie10'];
140    switch(_browser){
141      case browser[0]: return(this.ua.indexOf('chrome')  !== -1 && this.ua.indexOf('edge') === -1) ? true : false;
142      case browser[1]: return(this.ua.indexOf('safari')  !== -1 && this.ua.indexOf('chrome') === -1) ? true : false;
143      case browser[2]: return(this.ua.indexOf('firefox') !== -1) ? true : false;
144      case browser[3]: return(this.ua.indexOf('edge') !== -1) ? true : false;
145      case browser[4]: return((this.ua.indexOf('rv 11') !== -1 || this.ua.indexOf('rv:11') !== -1) && (this.ua.indexOf('trident') !== -1)) ? true : false;
146      case browser_old[0]: return (this.ver.indexOf('msie 8') !== -1) ? true : false;
147      case browser_old[1]: return (this.ver.indexOf('msie 9') !== -1) ? true : false;
148      case browser_old[2]: return (this.ver.indexOf('msie 10') !== -1) ? true : false;
149      default: return false;
150    }
151  },
152  /**
153   * @method isFontSizeWatch
154   * @param {function}
155   * @return {Boolean}
156   */
157  isFontSizeWatch: function(callback){
158    'use strict';
159    var $elm,
160        $body = $('body'),
161        watchName = 'js-fontSizeWatch',
162        currentH = 0,
163        interval = 500,
164        HTML_FS_WATCH = $('<div class="' + watchName + '">&nbsp;</div>'),
165        CSS_FS_WATCH = { position: 'absolute', top: '0', display: 'block', padding: '0', visibility: 'hidden' };
166    // 監視用HTMLを生成する
167    if(!$('.' + watchName).length){
168      HTML_FS_WATCH.css(CSS_FS_WATCH).appendTo($body);
169    }
170    $elm = $('.' + watchName);
171    // 要素の高さを取得
172    var getHeight = function($elm){ return $elm.height(); };
173    // 要素の高さを比較して、異なればcallbackを実行
174    var watching = function(){
175      var h = getHeight($elm);
176      if(h === currentH){
177        return false;
178      } else {
179        currentH = h;
180        callback();
181      }
182    };
183    setInterval(watching, interval);
184  },
185  /**
186   * @method isWindowSizeWatch
187   * @param {function}
188   * @return {Boolean}
189   */
190  isWindowSizeWatch: function(callback){
191    'use strict';
192    var resize = false,
193        interval = 500;
194    this.$win.on('resize', function(){
195      // リサイズされている間は何もしない
196      if(resize !== false){ clearTimeout(resize); }
197      resize = setTimeout(function(){
198        callback();
199      }, interval);
200    });
201  }
202};
203
204/**
205 * @module
206 */
207COMMON.module = function(){
208  'use strict';
209  var u = new COMMON.Util();
210  return {
211    /**
212     * @method initialize
213     * - 初期化
214     */
215    initialize: function(){
216      this.respondBrowser();
217      this.smartView();
218      this.smoothScroll();
219      this.pagetopControl();
220      this.accordion();
221      this.tabs();
222      this.tabsSelect();
223      this.tabsMenu();
224      //this.equalHeight(true, true);  // onLoad
225      this.fitWidth();
226      //this.swapImg();  // onLoad
227      //this.heightCompare();  // onLoad
228      this.globalNavControl();
229      this.menuControl();
230      this.searchControl();
231      this.langControl();
232      this.popup();
233      this.rollover();
234      this.newCheck();
235      //this.modalControl();  // onLoad
236      this.sliderControl();
237      this.updateControl();
238      this.rwdImageMaps();
239      this.vueRenderingControl();
240      this.vueSliderControl();
241    },
242    /**
243     * @method respondBrowser
244     * - ブラウザ対応
245     */
246    respondBrowser: function(){
247      // vars
248      var $body = $('body'),
249          attrName = 'data-browser',
250          attrName2 = 'data-font';
251      // setting:属性設定
252      if(u.isBrowser('chrome')){ $body.attr(attrName, 'chrome'); }
253      else if(u.isBrowser('safari')){ $body.attr(attrName, 'safari'); }
254      else if(u.isBrowser('firefox')){ $body.attr(attrName, 'firefox'); }
255      else if(u.isBrowser('edge')){ $body.attr(attrName, 'edge'); }
256      else if(u.isBrowser('ie11')){ $body.attr(attrName, 'ie11'); }
257      // for Win7 IE11
258      if(u.winOSChecker() === 'win7'){ $body.attr(attrName2, 'meiryo'); }
259    },
260    /**
261     * @method smartView
262     * - viewport設定
263     */
264    smartView: function(){
265      // vars
266      var viewPoint = u.view;
267      // setting:デバイスごとにviewport設定
268      if(u.isTablet()){
269        $('meta[name="viewport"]').attr('content', 'width=' + viewPoint + 'px');
270      } else if(u.isMobile()){
271        $('meta[name="viewport"]').attr('content', 'width=device-width, initial-scale=1, minimum-scale=1.0, user-scalable=yes, shrink-to-fit=no');
272        // 電話番号付与
273        $('.js-tel-link').each(function(){
274          var telNum = $(this).text();
275          $(this).html($('<a>').attr('href', 'tel:' + telNum.replace(/\s+|-|\(|\)|[^\x01-\x7E\xA1-\xDF]/g, '')).append(telNum + '</a>'));
276        });
277      }
278    },
279    /**
280     * @method smoothScroll
281     * - スムーススクロール
282     */
283    smoothScroll: function(config){
284      // options
285      var c = $.extend({
286        escapeElement: '.js-esc-smoothScroll',
287        topmostElement: '#header',  // ページトップリンクに設定する要素(hrefの値)
288        scrollSpeed: 300,
289        easingType: 'swing'
290      }, config);
291      var $elm = $('a[href^="#"], area[href^="#"]').not('a[href="#"], area[href="#"], a[href^="#tab"], a[href^="#modal"], ' + c.escapeElement),
292          topmost = c.topmostElement,
293          speed = c.scrollSpeed,
294          easing = c.easingType,
295          suitableGap;
296      // function
297      var jumpMove = function(){
298        var position = $(u.hash).offset().top;
299        if(u.isRangeSP()){
300          suitableGap = 10;
301        } else {
302          suitableGap = 20;
303        }
304        // アンカー位置設定
305        position = position - suitableGap;
306        if(u.hash === topmost){
307          position = 0;
308        }
309        // スムース移動
310        $('html, body').animate({
311          scrollTop: position
312        }, speed, easing);
313      };
314      // control:アンカー移動制御
315      $elm.on('click', function(){
316        var self = $(this),
317            thisHref = self.attr('href'),
318            target = $(thisHref),
319            position;
320        // 遷移無効
321        if(target.offset() === undefined){
322          return false;
323        }
324        if(u.isRangeSP()){
325          suitableGap = 10;
326        } else {
327          suitableGap = 20;
328        }
329        // アンカー位置設定
330        position = target.offset().top - suitableGap;
331        if(thisHref === topmost){
332          position = 0;
333        }
334        // スムース移動
335        $('html, body').animate({
336          scrollTop: position
337        }, speed, easing);
338        // 無効化
339        return false;
340      });
341      // control:ページ遷移+アンカー移動制御
342      u.$win.on('load', function(){
343        if(u.url.indexOf('#') !== -1 && $(u.hash).offset() !== undefined){
344          if(u.isBrowser('ie11')){
345            setTimeout(function(){
346              jumpMove();
347            }, 250);
348          } else {
349            jumpMove();
350          }
351        }
352      });
353    },
354    /**
355     * @method pagetopControl
356     * - ページトップ制御
357     */
358    pagetopControl: function(config){
359      // options
360      var c = $.extend({
361        factorElement: '.js-pagetop'
362      }, config);
363      // vars
364      var $pagetop = $(c.factorElement),
365          dispY = 100,
366          fadeSpeed = 300;
367      // exit
368      if($pagetop.length === 0){ return false; }
369      // setting
370      $pagetop.hide();
371      // control
372      u.$win.on('scroll', function(){
373        var $this = $(this),
374            scrollY = $this.scrollTop();
375        // ページトップ表示制御
376        if(scrollY > dispY){
377          $pagetop.fadeIn(fadeSpeed);
378        } else {
379          $pagetop.fadeOut(fadeSpeed);
380        }
381      });
382    },
383    /**
384     * @method accordion
385     * - アコーディオン
386     */
387    accordion: function(config){
388      // options
389      var c = $.extend({
390        factorElement: '.js-accordion',
391        triggerElement: '.js-accordion_trigger',
392        panelElement: '.js-accordion_detail',
393        pcEscapeName: 'js-accordion_escape_pc',
394        panelDisplayType: 'allHide',  // 初期表示設定:「allHide」or「allShow」
395        slideSpeed: 200
396      }, config);
397      // vars
398      var $elm = $(c.factorElement),
399          accWrap = c.factorElement,
400          accTrigger = c.triggerElement,
401          accPanel = c.panelElement,
402          display = c.panelDisplayType,
403          pcEscape = c.pcEscapeName,
404          activeName = u.state.active,
405          speed = c.slideSpeed;
406      // exit
407      if($elm.length === 0){ return false; }
408      // setting:表示設定
409      $elm.each(function(){
410        var wrap = $(this),
411            trigger = wrap.find(accTrigger);
412        switch(display){
413          // 全非表示の場合
414          case 'allHide':
415            if(!u.isRangeSP() && !wrap.hasClass(pcEscape)){
416              if(trigger.hasClass(activeName)){
417                wrap.find(accPanel).show();
418              } else {
419                trigger.removeClass(activeName);
420                wrap.find(accPanel).hide();
421              }
422            }
423            break;
424          // 全表示の場合
425          case 'allShow':
426            if(!u.isRangeSP() && !wrap.hasClass(pcEscape)){
427              trigger.addClass(activeName);
428              wrap.find(accPanel).show();
429            }
430            break;
431          default:
432            break;
433        }
434      });
435      // control
436      $(accTrigger).on('click', function(){
437        var trigger = $(this),
438            wrap = trigger.parents(accWrap);
439        if(wrap.length){
440          if(!u.isRangeSP() && wrap.hasClass(pcEscape)){ return true; }
441          if(trigger.hasClass(activeName)){
442            trigger.removeClass(activeName);
443            wrap.find(accPanel).stop(true, true).slideUp(speed, function(){
444              // 再実行
445              COMMON.module.heightCompare();
446            });
447          } else {
448            trigger.addClass(activeName);
449            wrap.find(accPanel).stop(true, true).slideDown(speed, function(){
450              // 再実行
451              COMMON.module.heightCompare();
452            });
453            // 再実行
454            if(wrap.find(accPanel).find(u.factor.equalHeight).length){ COMMON.module.equalHeight(); }
455          }
456        }
457      });
458    },
459    /**
460     * @method tabs
461     * - タブ切り替え
462     */
463    tabs: function(config){
464      // options
465      var c = $.extend({
466        factorElement: '.js-tabs',
467        naviElement: '.js-tabs_navi',
468        triggerElement: '.js-tabs_trigger',
469        panelElement: '.js-tabs_detail',
470        firstDisplayTab: ''  // 初期表示タブ:タブのid「#xxxx」を指定(※何も指定しなければ一番最初のタブを表示)
471      }, config);
472      // vars
473      var $elm = $(c.factorElement),
474          tabWrap = c.factorElement,
475          tabNavi = c.naviElement,
476          tabTrigger = c.triggerElement,
477          tabPanel = c.panelElement,
478          currentName = u.state.current,
479          paramKey = {
480            open: u.param.open
481          },
482          paramValOpen = '';
483      // exit
484      if($elm.length === 0){ return false; }
485      // function:クエリ設定
486      var querySetting = function(){
487        var params = [];
488        params = u.query.split('?')[1].split('&');
489        for(var i=0; i<params.length; i++){
490          if(params[i].indexOf(paramKey.open + '=') !== -1){
491            paramValOpen = params[i].split(paramKey.open + '=')[1];
492          }
493        }
494      };
495      // function:アンカー移動
496      var anchorMoving = function(_target){
497        var topmost = '#header',
498            speed = 300,
499            easing = 'swing',
500            target = $(_target),
501            position,
502            suitableGap;
503        if(u.isRangeSP()){
504          suitableGap = 10;
505        } else {
506          suitableGap = 20;
507        }
508        // 遷移無効
509        if(target.offset() === undefined){
510          return false;
511        }
512        // アンカー位置設定
513        position = target.offset().top - suitableGap;
514        if(_target === topmost){
515          position = 0;
516        }
517        // スムース移動
518        $('html, body').animate({
519          scrollTop: position
520        }, speed, easing);
521      };
522      // setting:表示設定
523      if(u.query !== ''){
524        querySetting();
525      }
526      $elm.each(function(){
527        var wrap = $(this),
528            navi = wrap.find(tabNavi),
529            panel = wrap.find(tabPanel),
530            firstPanel = c.firstDisplayTab,
531            targetAnchor;
532        if(paramValOpen !== ''){
533          // URLにクエリがあり、かつ該当のタブ要素が存在していた場合
534          if($('#' + paramValOpen).length && $('#' + paramValOpen).is(tabPanel)){
535            firstPanel = '#' + paramValOpen;
536            navi.find(tabTrigger).parent().removeClass(currentName);
537          } else {
538            firstPanel = navi.find('li:first').find(tabTrigger).attr('href');
539          }
540        } else if(firstPanel !== ''){
541          // JS側で初期表示タブに指定がある場合
542        } else if(navi.find('li').hasClass(currentName)){
543          // HTML側で現在地の指定がある場合
544          firstPanel = $('.' + currentName, navi).find(tabTrigger).attr('href');
545        } else {
546          firstPanel = navi.find('li:first').find(tabTrigger).attr('href');
547        }
548        navi.find('a[href="' + firstPanel + '"]').parent().addClass(currentName);
549        panel.show().not(firstPanel).hide();
550        COMMON.module.heightCompare();
551        if(paramValOpen !== ''){
552          targetAnchor = $('#' + paramValOpen).closest(tabWrap);
553          setTimeout(function(){
554            anchorMoving(targetAnchor);
555          }, 200);
556        }
557        // 初期化
558        paramValOpen = '';
559      });
560      // control
561      $(tabTrigger).on('click', function(){
562        var trigger = $(this),
563            wrap = trigger.closest(tabWrap),
564            navi = wrap.find(tabNavi),
565            panel = wrap.find(tabPanel),
566            targetPanel = trigger.attr('href');
567        if(trigger.parent().hasClass(currentName)){
568          return false;
569        } else {
570          navi.find('li').removeClass(currentName);
571          navi.find('a[href="' + targetPanel + '"]').parent().addClass(currentName);
572          panel.show().not(targetPanel).hide();
573          // 再実行
574          COMMON.module.heightCompare();
575          if(wrap.find(targetPanel).find(u.factor.equalHeight).length){ COMMON.module.equalHeight(); }
576          return false;
577        }
578      });
579    },
580    /**
581     * @method tabsSelect
582     * - タブ切り替え(select)
583     */
584    tabsSelect: function(config){
585      // options
586      var c = $.extend({
587        factorElement: '.js-tabs-select',
588        naviElement: '.js-tabs-select_navi',
589        panelElement: '.js-tabs-select_detail',
590        naviLabel: '.js-tabs-select_label',
591        firstDisplayTab: ''  // 初期表示タブ:タブのid「#xxxx」を指定(※何も指定しなければ一番最初のタブを表示)
592      }, config);
593      // vars
594      var $elm = $(c.factorElement),
595          tabWrap = c.factorElement,
596          tabNavi = c.naviElement,
597          tabPanel = c.panelElement,
598          tabLabel = c.naviLabel,
599          paramKey = {
600            open: u.param.open
601          },
602          paramValOpen = '';
603      // exit
604      if($elm.length === 0){ return false; }
605      // function:クエリ設定
606      var querySetting = function(){
607        var params = [];
608        params = u.query.split('?')[1].split('&');
609        for(var i=0; i<params.length; i++){
610          if(params[i].indexOf(paramKey.open + '=') !== -1){
611            paramValOpen = params[i].split(paramKey.open + '=')[1];
612          }
613        }
614      };
615      // function:アンカー移動
616      var anchorMoving = function(_target){
617        var topmost = '#header',
618            speed = 300,
619            easing = 'swing',
620            target = $(_target),
621            position,
622            suitableGap;
623        if(u.isRangeSP()){
624          suitableGap = 10;
625        } else {
626          suitableGap = 20;
627        }
628        // 遷移無効
629        if(target.offset() === undefined){
630          return false;
631        }
632        // アンカー位置設定
633        position = target.offset().top - suitableGap;
634        if(_target === topmost){
635          position = 0;
636        }
637        // スムース移動
638        $('html, body').animate({
639          scrollTop: position
640        }, speed, easing);
641      };
642      // setting:表示設定
643      if(u.query !== ''){
644        querySetting();
645      }
646      $elm.each(function(){
647        var wrap = $(this),
648            navi = wrap.find(tabNavi),
649            label = wrap.find(tabLabel),
650            panel = wrap.find(tabPanel),
651            firstPanel = c.firstDisplayTab,
652            targetAnchor;
653        if(paramValOpen !== ''){
654          // URLにクエリがあり、かつ該当のタブ要素が存在していた場合
655          if($('#' + paramValOpen).length && $('#' + paramValOpen).is(tabPanel)){
656            firstPanel = paramValOpen;
657          } else {
658            if(navi.find('option:selected')){
659              firstPanel = navi.find('option:selected').val();
660            } else {
661              firstPanel = navi.find('option:first').val();
662            }
663          }
664        } else if(firstPanel !== ''){
665          // JS側で初期表示タブに指定がある場合
666        } else if(navi.find('option:selected')){
667          // HTML側で現在地の指定がある場合
668          firstPanel = navi.find('option:selected').val();
669        } else {
670          firstPanel = navi.find('option:first').val();
671        }
672        navi.val(firstPanel);
673        label.text(navi.find('option:selected').text());
674        panel.show().not('#' + firstPanel).hide();
675        COMMON.module.heightCompare();
676        if(paramValOpen !== ''){
677          targetAnchor = $('#' + paramValOpen).closest(tabWrap);
678          setTimeout(function(){
679            anchorMoving(targetAnchor);
680          }, 200);
681        }
682        // 初期化
683        paramValOpen = '';
684      });
685      // control
686      $(tabNavi).on('change', function(){
687        var navi = $(this),
688            wrap = navi.closest(tabWrap),
689            panel = wrap.find(tabPanel),
690            label = wrap.find(tabLabel),
691            targetPanel = '#' + navi.val();
692        label.text(navi.find('option:selected').text());
693        panel.show().not(targetPanel).hide();
694        // 再実行
695        COMMON.module.heightCompare();
696        if(wrap.find(targetPanel).find(u.factor.equalHeight).length){ COMMON.module.equalHeight(); }
697      });
698    },
699     /**
700     * @method tabsSelect2
701     * - タブメニュー(SP時アコーディオン)
702     */
703    tabsMenu: function(config){
704      // options
705      var c = $.extend({
706        factorElement: '.js-tabs-menu',
707        naviElement: '.js-tabs-menu_navi',
708        triggerElement: '.js-tabs-menu_trigger',
709        panelElement: '.js-tabs-menu_detail',
710        spPanelName: 'js-tabs-menu_detail_sp',
711        slideSpeed: 300,
712        firstDisplayTab: ''  // 初期表示タブ:タブのid「#xxxx」を指定(※何も指定しなければ一番最初のタブを表示)
713      }, config);
714      // vars
715      var $elm = $(c.factorElement),
716          tabWrap = c.factorElement,
717          tabNavi = c.naviElement,
718          tabTrigger = c.triggerElement,
719          tabPanel = c.panelElement,
720          spTabPanelName = c.spPanelName,
721          currentName = u.state.current,
722          paramKey = {
723            open: u.param.open
724          },
725          paramValOpen = '',
726          slideSpeed = c.slideSpeed;
727      // exit
728      if($elm.length === 0){ return false; }
729      // function:クエリ設定
730      var querySetting = function(){
731        var params = [];
732        params = u.query.split('?')[1].split('&');
733        for(var i=0; i<params.length; i++){
734          if(params[i].indexOf(paramKey.open + '=') !== -1){
735            paramValOpen = params[i].split(paramKey.open + '=')[1];
736          }
737        }
738      };
739      // function:アンカー移動
740      var anchorMoving = function(_target){
741        var topmost = '#header',
742            speed = 300,
743            easing = 'swing',
744            target = $(_target),
745            position,
746            suitableGap;
747        if(u.isRangeSP()){
748          suitableGap = 10;
749        } else {
750          suitableGap = 20;
751        }
752        // 遷移無効
753        if(target.offset() === undefined){
754          return false;
755        }
756        // アンカー位置設定
757        position = target.offset().top - suitableGap;
758        if(_target === topmost){
759          position = 0;
760        }
761        // スムース移動
762        $('html, body').animate({
763          scrollTop: position
764        }, speed, easing);
765      };
766      // setting:表示設定
767      if(u.query !== ''){
768        querySetting();
769      }
770      $elm.each(function(){
771        var wrap = $(this),
772            navi = wrap.find(tabNavi),
773            panel = wrap.find(tabPanel),
774            firstPanel = c.firstDisplayTab,
775            targetAnchor;
776        panel.each(function(){
777          var $this_panel = $(this),
778              panelContents = $this_panel.html(),
779              this_id = $this_panel.attr('id'),
780              this_parent = wrap.find(tabTrigger + '[href="#' + this_id + '"]');
781          this_parent.after('<div class="' + spTabPanelName + '" data-panel-id="' + this_id + '"></div>');
782          $(panelContents).appendTo('.' + spTabPanelName + '[data-panel-id="' + this_id + '"]');
783        });
784        $('.' + spTabPanelName, navi).hide();
785        panel.hide();
786        if(paramValOpen !== ''){
787          // URLにクエリがあり、かつ該当のタブ要素が存在していた場合
788          if($('#' + paramValOpen).length && $('#' + paramValOpen).is(tabPanel)){
789            firstPanel = '#' + paramValOpen;
790            navi.find(tabTrigger).removeClass(currentName);
791            navi.find('a[href="' + firstPanel + '"]').addClass(currentName);
792            navi.find('a[href="' + firstPanel + '"]').next('.' + spTabPanelName).show();
793          } else {
794            firstPanel = navi.find('li:first').find(tabTrigger).attr('href');
795            if(!u.isRangeSP()){
796              navi.find('a[href="' + firstPanel + '"]').addClass(currentName);
797            }
798          }
799        } else if(firstPanel !== ''){
800          // JS側で初期表示タブに指定がある場合
801        } else if(navi.find(tabTrigger).hasClass(currentName)){
802          // HTML側で現在地の指定がある場合
803          firstPanel = $('.' + currentName, navi).attr('href');
804          navi.find('a[href="' + firstPanel + '"]').addClass(currentName);
805          navi.find('a[href="' + firstPanel + '"]').next('.' + spTabPanelName).show();
806        } else {
807          firstPanel = navi.find('li:first').find(tabTrigger).attr('href');
808          if(!u.isRangeSP()){
809            navi.find('a[href="' + firstPanel + '"]').addClass(currentName);
810          }
811        }
812        $(firstPanel).show();
813        COMMON.module.heightCompare();
814        if(paramValOpen !== ''){
815          targetAnchor = $('#' + paramValOpen).closest(tabWrap);
816          setTimeout(function(){
817            anchorMoving(targetAnchor);
818          }, 200);
819        }
820        // 初期化
821        paramValOpen = '';
822      });
823      // control
824      $(tabTrigger).on('click', function(){
825        var trigger = $(this),
826            wrap = trigger.closest(tabWrap),
827            navi = wrap.find(tabNavi),
828            panel = wrap.find(tabPanel),
829            targetPanel = trigger.attr('href');
830        if(!u.isRangeSP()){
831          if(trigger.hasClass(currentName)){
832            return false;
833          } else {
834            navi.find(tabTrigger).removeClass(currentName);
835            trigger.addClass(currentName);
836            panel.show().not(targetPanel).hide();
837            // 再実行
838            COMMON.module.heightCompare();
839          }
840          // 再実行
841          if(wrap.find(targetPanel).find(u.factor.equalHeight).length){ COMMON.module.equalHeight(); }
842        } else {
843          if(trigger.hasClass(currentName)){
844            trigger.removeClass(currentName);
845            trigger.next('.' + spTabPanelName).slideUp(slideSpeed);
846          } else {
847            trigger.addClass(currentName);
848            trigger.next('.' + spTabPanelName).slideDown(slideSpeed);
849          }
850        }
851        return false;
852      });
853    },
854    /**
855     * @method equalHeight
856     * - 高さ揃え
857     * @param {Boolean} 文字可変に対応するかどうか
858     * @param {Boolean} リサイズに対応するかどうか
859     */
860    equalHeight: function(fsWatch, wsWatch, config){
861      // options
862      var c = $.extend({
863        factorElement: u.factor.equalHeight,
864        spEscapeElement: '.js-esc-sp-equalHeight, [data-row-sp="1"]',
865        alignChildPrefix: 'js-equalHeight_'
866      }, config);
867      // vars
868      var $elm = $(c.factorElement),
869          spEscElm = c.spEscapeElement,
870          childBaseName = c.alignChildPrefix,
871          $children,
872          $spChildren,
873          CSS_OBJ = { height: '' };
874      // exit
875      if($elm.length === 0){ return false; }
876      // setting
877      fsWatch = fsWatch || false;
878      wsWatch = wsWatch || true;
879      // function:childBaseNameのグループ化
880      var grouping = function(target){
881        var $groupedChildren = target.find('*[class*=' + childBaseName + ']'),
882            classNames = {},
883            groups = [];
884        $groupedChildren.each(function(){
885          var splitClass = $(this).attr('class').split(' '),
886              splitClassNum = splitClass.length,
887              newClassName;
888          for(var i = 0; i < splitClassNum; i++){
889            newClassName = splitClass[i].match(RegExp(childBaseName + '[a-z0-9,_,-]*', 'i'));
890            if(!newClassName){
891              continue;
892            } else {
893              newClassName.toString();
894              classNames[newClassName] = newClassName;
895            }
896          }
897        });
898        // childBaseNameの格納
899        for(var c in classNames){
900          if(u.isRangeSP()){
901            groups.push(target.not(spEscElm).find('.' + c));
902          } else {
903            groups.push(target.find('.' + c));
904          }
905        }
906        return groups;
907      };
908      // function:各要素の高さを揃える
909      var alignHeight = function(elm){
910        var maxH = 0;
911        elm.css(CSS_OBJ);
912        elm.each(function(){
913          if($(this).outerHeight() > maxH){
914            maxH = $(this).outerHeight();
915          }
916        });
917        return elm.outerHeight(maxH);
918      };
919      // function:初期化処理
920      var init = function(target){
921        var groups = grouping(target);
922        $children = target.children();
923        $spChildren = target.not(spEscElm).children();
924        var eqAct = function(eqObj){
925          var h = [],
926              child = [],
927              top = 0;
928          $.each(eqObj, function(){
929            // 非表示要素に適用させない場合.not(':hidden')を付与
930            var $group = $(this).not(':hidden');
931            $group.each(function(i){
932              $(this).css(CSS_OBJ);
933              h[i] = $(this).outerHeight();
934              if((top !== Math.round($(this).offset().top)) && (top !== Math.round($(this).offset().top)+1) && (top !== Math.round($(this).offset().top)-1)){
935                alignHeight($(child));
936                child = [];
937                top = Math.round($(this).offset().top);
938              }
939              child.push(this);
940            });
941          });
942          if(child.length > 1){ alignHeight($(child)); }
943        };
944        // childBaseName要素の高さを揃える
945        eqAct(groups);
946        // 子要素の高さを揃える
947        if(u.isRangeSP()){
948          eqAct($spChildren);
949          $(spEscElm).children().css(CSS_OBJ);
950          $(spEscElm).find('*[class*=' + childBaseName + ']').css(CSS_OBJ);
951        } else {
952          eqAct($children);
953        }
954      };
955      // 文字可変・リサイズへの対応可否
956      $elm.each(function(){
957        var self = $(this);
958        if(fsWatch){ u.isFontSizeWatch(function(){ init(self); }); } else { init(self); }
959        if(wsWatch){ u.isWindowSizeWatch(function(){ init(self); }); } else { init(self); }
960      });
961    },
962    /**
963     * @method fitWidth
964     * - キャプション幅揃え
965     */
966    fitWidth: function(config){
967      // options
968      var c = $.extend({
969        factorElement: '.js-fitWidth',
970        spEscapeElement: '.js-esc-sp-fitWidth',
971        isResize: true
972      }, config);
973      // vars
974      var $elm = $(c.factorElement),
975          spEscName = c.spEscapeElement.split('.')[1],
976          CSS_OBJ = { width: '' };
977      // exit
978      if($elm.length === 0){ return false; }
979      // function
980      var fitting = function(target){
981        var imageObj = new Image(),
982            targetImg = target.find('img'),
983            cssW,
984            naturalW,
985            setW,
986            setSrc = targetImg.attr('src');
987        // 画像読み込み完了後、コールバック
988        imageObj.onload = function(){
989          cssW = parseInt(targetImg.css('width'));
990          naturalW = imageObj.width;
991          setW = (cssW !== 0 && cssW < naturalW) ? cssW : naturalW;
992          if(u.isRangeSP() && target.hasClass(spEscName)){
993            target.css(CSS_OBJ);
994            return;
995          } else {
996            target.css(CSS_OBJ);
997          }
998          target.css({
999            'width': setW,
1000            'maxWidth': '100%'
1001          });
1002        };
1003        // 画像読み込み開始
1004        imageObj.src = setSrc;
1005      };
1006      // control
1007      $elm.each(function(){
1008        var self = $(this);
1009        fitting(self);
1010        // resize
1011        if(c.isResize){
1012          u.isWindowSizeWatch(function(){
1013            // 初期化
1014            self.css(CSS_OBJ);
1015            fitting(self);
1016          });
1017        }
1018      });
1019    },
1020    /**
1021     * @method swapImg
1022     * - ウィンドウ幅で画像切り替え
1023     */
1024    swapImg: function(config){
1025      // options
1026      var c = $.extend({
1027        factorElement: '.js-swapImg',
1028        retinaSuffix: '-r2x'
1029      }, config);
1030      // vars
1031      var $elm = $(c.factorElement),
1032          suffix = c.retinaSuffix;
1033      // exit
1034      if($elm.length === 0){ return false; }
1035      // function
1036      var swapping = function(img){
1037        if(u.isRangeSP()){
1038          if(img.attr('src').indexOf(suffix) === -1){
1039            img.attr('src', img.attr('src').replace(/^(.+)(\.[a-z]+)$/, '$1' + suffix + '$2'));
1040          }
1041        } else {
1042          if(img.attr('src').indexOf(suffix) !== -1){
1043            img.attr('src', img.attr('src').replace(new RegExp('^(.+)' + suffix + '(\.[a-z]+)$' ), '$1$2'));
1044          }
1045        }
1046      };
1047      // control
1048      $elm.each(function(){
1049        var self = $(this);
1050        swapping(self);
1051        // resize
1052        u.isWindowSizeWatch(function(){
1053          swapping(self);
1054        });
1055      });
1056    },
1057    /**
1058     * @method heightCompare
1059     * - 高さ比較制御
1060     */
1061    heightCompare: function(config){
1062      // options
1063      var c = $.extend({
1064        factorElement: '.js-heightCompare',
1065        switchElement: '.js-heightCompare_switch'
1066      }, config);
1067      // vars
1068      var $elm = $(c.factorElement),
1069          $switchElm = $(c.switchElement),
1070          $main = $('#main'),
1071          $footer = $('#footer'),
1072          fixedName = u.state.fixed;
1073      // exit
1074      if($elm.length === 0){ return false; }
1075      // function
1076      var comparing = function(){
1077        // init
1078        $switchElm.removeClass(fixedName).css('height', 'auto');
1079        $main.css('minHeight', 0);
1080        // vars
1081        var elmH = $elm.outerHeight(true),
1082            cmpH = document.body.clientHeight,
1083            winH = window.innerHeight;
1084        if(u.isRangePC()){
1085          if(elmH < winH){
1086            $main.css('minHeight', winH - $footer.outerHeight(true));
1087            $switchElm.addClass(fixedName);
1088            $switchElm.css('height', winH);
1089          } else {
1090            $main.css('minHeight', elmH - $footer.outerHeight(true));
1091            $switchElm.removeClass(fixedName);
1092            if(cmpH < elmH){
1093              $switchElm.css('height', elmH);
1094            } else {
1095              $switchElm.css('height', cmpH);
1096            }
1097          }
1098        } else {
1099          $main.css('minHeight', 0);
1100          $switchElm.removeClass(fixedName).css('height', 'auto');
1101        }
1102      };
1103      // init
1104      comparing();
1105
1106      // resize
1107      u.isWindowSizeWatch(function(){
1108        comparing();
1109      });
1110    },
1111    /**
1112     * @method globalNavControl
1113     * - グローバルナビ制御
1114     */
1115    globalNavControl: function(config){
1116      // options
1117      var c = $.extend({
1118        factorElement: '.js-globalNav',
1119        nav1Element: '.js-globalNav_1',
1120        nav2Element: '.js-globalNav_2',
1121        nav3Element: '.js-globalNav_3',
1122        nav4Element: '.js-globalNav_4',
1123        nav5Element: '.js-globalNav_5',
1124        nav6Element: '.js-globalNav_6'
1125      }, config);
1126      // vars
1127      var $elm = $(c.factorElement),
1128          $nav1 = $elm.find(c.nav1Element),
1129          $nav2 = $elm.find(c.nav2Element),
1130          $nav3 = $elm.find(c.nav3Element),
1131          $nav4 = $elm.find(c.nav4Element),
1132          $nav5 = $elm.find(c.nav5Element),
1133          $nav6 = $elm.find(c.nav6Element),
1134          currentName = u.state.current;
1135      // exit
1136      if($elm.length === 0){ return false; }
1137      // setting
1138      switch(u.dir[1]){
1139        case 'timetable':
1140          $nav1.addClass(currentName);
1141          break;
1142        case 'route_map':
1143          $nav2.addClass(currentName);
1144          break;
1145        case 'service':
1146          $nav3.addClass(currentName);
1147          break;
1148        case 'towntopics':
1149          $nav4.addClass(currentName);
1150          break;
1151        case 'feature':
1152          $nav5.addClass(currentName);
1153          break;
1154        case 'faq':
1155          if(u.dir[2] === 'lost'){
1156            $nav6.addClass(currentName);
1157          }
1158          break;
1159        default: break;
1160      }
1161    },
1162/**
1163     * @method menuControl
1164     * - メニュー制御
1165     */
1166    menuControl: function(config){
1167      // options
1168      var c = $.extend({
1169        factorElement: '.js-menu',
1170        pcTriggerElement: '.js-megadrop_trigger',
1171        pcMenuElement: '.js-megadrop_menu',
1172        spNavi: '.js-menu-sp',
1173        spTriggerElement: '.js-dropdown_trigger',
1174        spMenuElement: '.js-dropdown_menu',
1175        spMenuContainer: '.js-dropdown_menu_container',
1176        spToggleTriggerElement: '.js-dropdown_toggle_trigger',
1177        spTogglePanelElement: '.js-dropdown_toggle_panel',
1178        spMenuLabel: '.js-dropdown_trigger_label',
1179        cloneElement1: '.js-menu_clone_1',
1180        cloneElement2: '.js-menu_clone_2',
1181        cloneElement3: '.js-menu_clone_3',
1182        openText: 'メニュー',
1183        closeText: '閉じる'
1184      }, config);
1185      // vars
1186      var $body = $('body'),
1187          $elm = $(c.factorElement),
1188          $cloneElm1,
1189          $cloneElm2,
1190          $cloneElm3,
1191          pcTrigger = c.pcTriggerElement,
1192          pcMenu = c.pcMenuElement,
1193          $spNavi = $(c.spNavi),
1194          spTrigger = c.spTriggerElement,
1195          spMenu = c.spMenuElement,
1196          spMenuContainer = c.spMenuContainer,
1197          spTglBtn,
1198          spTglPanel,
1199          $spMenuLabel = $(c.spMenuLabel),
1200          openText = c.openText,
1201          closeText = c.closeText,
1202          activeName = u.state.active,
1203          activeMenuName = 'is-active-menu',
1204          setPos = 0,
1205          fadeSpeed = 200,
1206          slideSpeed = 200,
1207          overlayName = 'megadrop-overlay',
1208          $overlay;
1209      // exit
1210      if($elm.length === 0){ return false; }
1211      // setting:複製
1212      $cloneElm1 = $(c.cloneElement1).clone().appendTo($(spMenuContainer));
1213      $cloneElm2 = $(c.cloneElement2).clone().appendTo($(spMenuContainer));
1214      $cloneElm3 = $(c.cloneElement3).clone().appendTo($(spMenuContainer));
1215      spTglBtn = $cloneElm1.find(c.spToggleTriggerElement);
1216      spTglPanel = $cloneElm1.find(c.spTogglePanelElement);
1217      // setting:ニュースリンク出力
1218      $(spMenu).hide();
1219
1220      $overlay = $('<div class="' + overlayName + '"></div>').appendTo($body).hide();
1221
1222      var closeMegadrop = function() {
1223        $(pcTrigger).removeClass(activeName);
1224        $(pcMenu).stop().fadeOut(fadeSpeed);
1225        $overlay.stop().fadeOut(fadeSpeed);
1226      };
1227
1228      // control:PCメニュー(メガドロップ)オンマウス制御
1229      $(pcTrigger).on('click', function(){
1230        if(!u.isRangeSP()){
1231          var self = $(this),
1232              targetMenu = self.next(pcMenu);
1233          if(!self.hasClass(activeName)){
1234            $(pcTrigger).removeClass(activeName);
1235            $(pcMenu).hide();
1236            self.addClass(activeName);
1237            targetMenu.stop().fadeIn(fadeSpeed);
1238            $overlay.stop().fadeIn(fadeSpeed);
1239          } else {
1240            closeMegadrop();
1241          }
1242          return false;
1243        }
1244      });
1245
1246      $overlay.on('click', function(){
1247        closeMegadrop();
1248      });
1249
1250      // control:SPナビ 表示制御
1251      var scrollNavi = function(){
1252        if(u.isRangeSP()){
1253          var docH = document.body.clientHeight,
1254              winH = window.innerHeight,
1255              dispY = 100;
1256          if(docH < winH + dispY){
1257            $spNavi.addClass(activeName);
1258          } else {
1259            u.$win.on('scroll', function(){
1260              var $this = $(this),
1261                  scrollY = $this.scrollTop();
1262              if(scrollY > dispY){
1263                $spNavi.addClass(activeName);
1264              } else {
1265                if(!$body.hasClass(activeMenuName) && !$body.hasClass('is-active-search')){
1266                  $spNavi.removeClass(activeName);
1267                }
1268              }
1269            });
1270          }
1271        } else {
1272          $spNavi.removeClass(activeName);
1273        }
1274      };
1275      u.$win.on('load', function(){
1276        scrollNavi();
1277      });
1278      u.isWindowSizeWatch(scrollNavi);
1279      // control:SPメニュー(ドロップダウン)クリック制御
1280      $(spTrigger).on('click', function(){
1281        if(u.isRangeSP()){
1282          var self = $(this);
1283          if(!self.hasClass(activeName)){
1284            setPos = u.$win.scrollTop();
1285            $body.addClass(activeMenuName).css('top', -setPos);
1286            self.addClass(activeName);
1287            $spMenuLabel.text(closeText);
1288            $(spMenu).stop().fadeIn(fadeSpeed);
1289          } else {
1290            $body.removeClass(activeMenuName).css('top', 'auto');
1291            self.removeClass(activeName);
1292            $spMenuLabel.text(openText);
1293            $(spMenu).stop().fadeOut(fadeSpeed);
1294            u.$win.scrollTop(setPos);
1295          }
1296          return false;
1297        }
1298      });
1299      // control:SPメニュー(ドロップダウン)内開閉制御
1300      $(spTglBtn).on('click', function(){
1301        if(u.isRangeSP()){
1302          var self = $(this),
1303              parent = self.parent(),
1304              targetPanel = parent.find(spTglPanel);
1305          if(!self.hasClass(activeName)){
1306            self.addClass(activeName);
1307            targetPanel.stop().slideDown(slideSpeed);
1308          } else {
1309            self.removeClass(activeName);
1310            targetPanel.stop().slideUp(slideSpeed);
1311          }
1312          return false;
1313        }
1314      });
1315    },
1316    /**
1317     * @method searchControl
1318     * - 検索窓制御
1319     */
1320    searchControl: function(config){
1321      // options
1322      var c = $.extend({
1323        factorElement: '.js-search',
1324        triggerElement: '.js-search_trigger',
1325        inputElement: '.js-search_input',
1326        closeElement: '.js-search_close'
1327      }, config);
1328      // vars
1329      var $body = $('body'),
1330          $headerBody = $('#headerBody'),
1331          $elm = $(c.factorElement),
1332          $close = $(c.closeElement),
1333          $overlay,
1334          searchTrigger = c.triggerElement,
1335          searchInput = c.inputElement,
1336          activeName = u.state.active,
1337          activeSearchName = 'is-active-search',
1338          overlayName = 'search-overlay',
1339          setPos = 0,
1340          fadeSpeed = 200;
1341      // exit
1342      if($elm.length === 0){ return false; }
1343      // setting:初期設定
1344      $elm.hide();
1345      $overlay = $('<div class="' + overlayName + '"></div>').appendTo($headerBody);
1346      // function:閉じる制御
1347      var closeSearch = function(){
1348        $body.removeClass(activeSearchName);
1349        $(searchTrigger).removeClass(activeName);
1350        $elm.stop().fadeOut(fadeSpeed);
1351        $overlay.stop().fadeOut(fadeSpeed);
1352        $body.css('top', 'auto');
1353        u.$win.scrollTop(setPos);
1354      };
1355      // control:検索窓にフォーカスが当たっている状態で[Enter]キーを押した際、「空」の場合はサブミットしない
1356      $(searchInput).on('keypress', function(e){
1357        var self = $(this);
1358        if(e.which && e.which === 13 || e.keyCode && e.keyCode === 13){
1359          if(self.val() === ''){
1360            return false;
1361          }
1362        }
1363      });
1364      // control:表示制御
1365      $(searchTrigger).on('click', function(){
1366        var self = $(this);
1367        if(!self.hasClass(activeName)){
1368          setPos = u.$win.scrollTop();
1369          $body.css('top', -setPos);
1370          $body.addClass(activeSearchName);
1371          $overlay.stop().fadeIn(fadeSpeed);
1372          self.addClass(activeName);
1373          $elm.stop().fadeIn(fadeSpeed);
1374        } else {
1375          closeSearch();
1376        }
1377      });
1378      // control:閉じる制御
1379      $close.on('click', function(){
1380        closeSearch();
1381      });
1382      $overlay.on('click', function(){
1383        closeSearch();
1384      });
1385    },
1386    /**
1387     * @method langControl
1388     * - 多言語窓制御
1389     */
1390    langControl: function(config){
1391      // options
1392      var c = $.extend({
1393        factorElement: '.js-lang',
1394        triggerElement: '.js-lang_trigger',
1395        targetElement: '.js-lang_detail',
1396        closeElement: '.js-lang_close'
1397      }, config);
1398      // vars
1399      var $body = $('body'),
1400          $headerBody = $('#headerBody'),
1401          $elm = $(c.factorElement),
1402          $target = $(c.targetElement),
1403          $close = $(c.closeElement),
1404          $overlay,
1405          langTrigger = c.triggerElement,
1406          activeName = u.state.active,
1407          activeLangName = 'is-active-lang',
1408          overlayName = 'lang-overlay',
1409          setPos = 0,
1410          slideSpeed = 200,
1411          fadeSpeed = 200;
1412      // exit
1413      if($elm.length === 0){ return false; }
1414      // setting:初期設定
1415      $target.hide();
1416      $overlay = $('<div class="' + overlayName + '"></div>').appendTo($headerBody);
1417      // function:閉じる制御
1418      var closeSearch = function(){
1419        $body.removeClass(activeLangName);
1420        $(langTrigger).removeClass(activeName);
1421        $overlay.stop().fadeOut(fadeSpeed);
1422        if(u.isRangeSP()){
1423          $target.stop().fadeOut(fadeSpeed);
1424          $body.css('top', 'auto');
1425          u.$win.scrollTop(setPos);
1426        } else {
1427          $target.stop().slideUp(slideSpeed);
1428        }
1429      };
1430      // control:表示制御
1431      $(langTrigger).on('click', function(){
1432        if(!$(langTrigger).hasClass(activeName)){
1433          if(u.isRangeSP()){
1434            setPos = u.$win.scrollTop();
1435            $body.css('top', -setPos);
1436            $target.stop().fadeIn(fadeSpeed);
1437          } else {
1438            $target.stop().slideDown(slideSpeed);
1439          }
1440          $body.addClass(activeLangName);
1441          $overlay.stop().fadeIn(fadeSpeed);
1442          $(langTrigger).addClass(activeName);
1443        } else {
1444          closeSearch();
1445        }
1446      });
1447      // control:閉じる制御
1448      $close.on('click', function(){
1449        closeSearch();
1450      });
1451      $overlay.on('click', function(){
1452        closeSearch();
1453      });
1454    },
1455    /**
1456     * @method popup
1457     * - ポップアップ
1458     */
1459    popup: function(config){
1460      // options
1461      var c = $.extend({
1462        factorElement: '.js-popup',
1463        popupWidth: 1000,
1464        popupHeight: 700
1465      }, config);
1466      // vars
1467      var $elm = $(c.factorElement),
1468          popupW = c.popupWidth,
1469          popupH = c.popupHeight;
1470      // exit
1471      if($elm.length === 0){ return false; }
1472      // control
1473      $elm.each(function(){
1474        var self = $(this),
1475            name = 'POPUP',
1476            width = popupW,
1477            height = popupH,
1478            left = 0,
1479            top = 0,
1480            parameters,
1481            centeringFlag = true;
1482        // ポップアップを天地左右中央に配置する場合
1483        if(centeringFlag){
1484          left = (screen.width - width) / 2;
1485          top = (screen.height - height) / 2;
1486        }
1487        // パラメータ設定
1488        parameters = 'width=' + width + ',height=' + height + ',menubar=no,toolbar=no,location=yes,status=yes,scrollbars=yes,resizable=yes,left=' + left + ',screenX=' + left + ',top=' + top + ',screenY=' + top;
1489        // クリック制御
1490        self.on('click', function(){
1491          if(!u.isRangeSP()){
1492            window.open(this.href, name, parameters);
1493            return false;
1494          } else {
1495            return true;
1496          }
1497        });
1498      });
1499    },
1500    /**
1501     * @method rollover
1502     * - ロールオーバー
1503     */
1504    rollover: function(config){
1505      // options
1506      var c = $.extend({
1507        factorElement: '.js-rollover',
1508        onSuffix: '_on'
1509      }, config);
1510      // vars
1511      var $elm = $(c.factorElement),
1512          suffix = c.onSuffix;
1513      // exit
1514      if($elm.length === 0 || !u.isDesktop()){ return false; }
1515      // function
1516      var src = {
1517        over: function($elm){return $elm.attr('src').replace(/^(.+)(\.[a-z]+)$/, '$1' + suffix + '$2');},
1518        out: function($elm){return $elm.attr('src').replace(new RegExp('^(.+)' + suffix + '(\.[a-z]+)$' ), '$1$2');},
1519        preload: function($elm){return $elm.attr('src').replace(/^(.+)(\.[a-z]+)$/, '$1' + suffix + '$2');}
1520      };
1521      // control
1522      $elm
1523        .hover(function(){
1524          $(this).attr('src', src.over($(this)));
1525        }, function(){
1526          $(this).attr('src', src.out($(this)));
1527        })
1528        .each(function(){
1529          $('<img>').attr('src', src.preload($(this)));
1530        });
1531    },
1532    /**
1533     * @method newCheck
1534     * - NEW判定
1535     */
1536    newCheck: function(config){
1537      // options
1538      var c = $.extend({
1539        factorElement: '.js-new-check',
1540        date: 'data-new-unpublished',
1541        newFlag: 'data-new-flag'
1542      }, config);
1543      // vars
1544      var $elm = $(c.factorElement),
1545          date = c.date,
1546          flag = c.newFlag,
1547          newName = u.state.new;
1548      // exit
1549      if($elm.length === 0){ return false; }
1550      // setting
1551      $elm.each(function(){
1552        var $self = $(this),
1553            self_date = $self.attr(date),
1554            self_flag = $self.attr(flag),
1555            d = new Date();
1556        if(self_flag === 'T'){
1557          if(self_date === '' || self_date === undefined){
1558            $self.addClass(newName);
1559          }
1560          // 期限
1561          d.setFullYear(self_date.substring(0,4));
1562          d.setMonth(self_date.substring(4,6) - 1);
1563          d.setDate(self_date.substring(6,8));
1564          if(d > new Date()){
1565            $self.addClass(newName);
1566          }
1567        }
1568      });
1569    },
1570    /**
1571     * @method modalControl
1572     * - モーダル制御
1573     * @requires jquery.colorbox.js
1574     */
1575    modalControl: function(config){
1576      // options
1577      var c = $.extend({
1578        factorPrefix: 'js-modal-',
1579        modalPhotoElement: '.js-modal-photo',
1580        modalInlineElement: '.js-modal-inline',
1581        modalAjaxElement: '.js-modal-ajax',
1582        modalIframeElement: '.js-modal-iframe',
1583        modalYoutubeElement: '.js-modal-youtube',
1584        customizeTriggerElement: ''  // カスタマイズ用(例:「.js-modal-xxxxx」)
1585      }, config);
1586      // vars
1587      var $elm = $('[class*=' + c.factorPrefix + ']'),
1588          $photoTrigger = $(c.modalPhotoElement),
1589          $inlineTrigger = $(c.modalInlineElement),
1590          $ajaxTrigger = $(c.modalAjaxElement),
1591          $iframeTrigger = $(c.modalIframeElement),
1592          $youtubeTrigger = $(c.modalYoutubeElement),
1593          baseW_pc = 1000,
1594          baseH_pc = false,
1595          baseW_sp = '90%',
1596          baseH_sp = window.innerHeight*0.9,
1597          opacity = 0.7,
1598          photoOption = { className: c.modalPhotoElement.split('js-')[1], width: u.isRangePC() ? baseW_pc : baseW_sp, height: 'auto', maxWidth: '100%', maxHeight: '100%', opacity: opacity },
1599          inlineOption = { className: c.modalInlineElement.split('js-')[1], inline: true, width: u.isRangePC() ? baseW_pc : baseW_sp, height: u.isRangePC() ? baseH_pc : baseH_sp, maxWidth: '100%', maxHeight: '100%', opacity: opacity },
1600          ajaxOption = { className: c.modalAjaxElement.split('js-')[1], width: u.isRangePC() ? baseW_pc : baseW_sp, height: u.isRangePC() ? baseH_pc : baseH_sp, maxWidth: '100%', maxHeight: '100%', opacity: opacity },
1601          iframeOption = { className: c.modalIframeElement.split('js-')[1], iframe: true, width: u.isRangePC() ? baseW_pc : baseW_sp, height: u.isRangePC() ? 500 : baseH_sp, maxWidth: '100%', maxHeight: '100%', opacity: opacity },
1602          youtubeOption = { className: c.modalYoutubeElement.split('js-')[1], iframe: true, width: u.isRangePC() ? baseW_pc : baseW_sp, height: u.isRangePC() ? baseW_pc*0.5625 : window.innerWidth*0.9*0.5625, maxWidth: '100%', maxHeight: '100%', opacity: opacity      };
1603      // カスタマイズ用を使用する場合、以下のコメントアウトを外す
1604      /*
1605      var $customizeTrigger = $(c.customizeTriggerElement),
1606          prefix = c.factorPrefix,
1607          // カスタマイズ用オプションは以下の体裁で追加
1608          customizeOption = {
1609            'xxxxx': {  // ←「.js-modal-xxxxx」の「xxxxx」をkeyとして設定
1610              className: '',
1611              width: '',
1612              height: ''
1613            },
1614          };
1615      */
1616      // exit
1617      if($elm.length === 0){ return false; }
1618      // init
1619      $photoTrigger.colorbox(photoOption);
1620      $inlineTrigger.colorbox(inlineOption);
1621      $ajaxTrigger.colorbox(ajaxOption);
1622      $iframeTrigger.colorbox(iframeOption);
1623      $youtubeTrigger.colorbox(youtubeOption);
1624      // カスタマイズ用を使用する場合、以下のコメントアウトを外す
1625      /*
1626      if($customizeTrigger.length){
1627        var key = c.customizeTriggerElement.split(prefix)[1];
1628        $('.' + prefix + key).colorbox(customizeOption[key]);
1629      }
1630      */
1631    },
1632    /**
1633     * @method updateControl
1634     * - ページリロード
1635     */
1636    updateControl: function(config){
1637      // options
1638      var c = $.extend({
1639        factorElement: '.js-update-trigger'
1640      }, config);
1641      // vars
1642      var $elm = $(c.factorElement);
1643      // exit
1644      if($elm.length === 0){ return false; }
1645      // control
1646      $elm.off('click.reload');
1647      $elm.on('click.reload', function(){
1648        location.reload(true);
1649      });
1650    },
1651    /**
1652     * @method sliderControl
1653     * - スライダー制御
1654     * @requires slick.js
1655     */
1656    sliderControl: function(config){
1657      // options
1658      var c = $.extend({
1659        factorPrefix: 'js-slider-',
1660        vueWrapFactor: '.js-vueSlider',
1661        sliderNames: ['hero', 'banner', 'banner2', 'banner3', 'gallery'],  // スライダーパターン(例:「.js-slider-xxxxx」を追加する場合、['hero', 'banner', 'xxxxx']を指定。もしくは別でメソッドを呼び出して実行する。)
1662        vueSliderNames: ['banner-vue', 'banner2-vue', 'banner3-vue']  // Vueスライダーパターン
1663      }, config);
1664      // vars
1665      var $elm = $('[class*=' + c.factorPrefix + ']'),
1666          prefix = c.factorPrefix,
1667          sliders = c.sliderNames,
1668          vueSliders = c.vueSliderNames,
1669          slickInitName = 'slick-initialized',
1670          bp1 = u.breakPoint1 + 1,
1671          readyName = u.state.ready;
1672      // exit
1673      if($elm.length === 0){ return false; }
1674      // settings
1675      var settings = {
1676        'hero': {
1677          arrows: false,
1678          dots: true,
1679          infinite: true,
1680          autoplay: true,
1681          autoplaySpeed: 4000,
1682          speed: 1000,
1683          slidesToShow: 1,
1684          slidesToScroll: 1,
1685          responsive: [
1686            {
1687              breakpoint: bp1,
1688              settings: {
1689                speed: 500
1690              }
1691            }
1692          ]
1693        },
1694        'banner': {
1695          arrows: true,
1696          dots: false,
1697          infinite: true,
1698          autoplay: false,
1699          speed: 500,
1700          slidesToShow: 3,
1701          slidesToScroll: 1,
1702          lazyLoad: 'ondemand',
1703        },
1704        'banner2': {
1705          arrows: true,
1706          dots: false,
1707          infinite: true,
1708          autoplay: false,
1709          speed: 500,
1710          slidesToShow: 3,
1711          slidesToScroll: 1,
1712          lazyLoad: 'ondemand',
1713          responsive: [
1714            {
1715              breakpoint: bp1,
1716              settings: {
1717                arrows: false,
1718                centerMode: true,
1719                centerPadding: '20%',
1720                slidesToShow: 1,
1721                speed: 500
1722              }
1723            }
1724          ]
1725        },
1726        'banner3': {
1727          arrows: true,
1728          dots: false,
1729          infinite: true,
1730          speed: 500,
1731          slidesToShow: 4,
1732          slidesToScroll: 1,
1733          lazyLoad: 'ondemand',
1734          responsive: [
1735            {
1736              breakpoint: bp1,
1737              settings: {
1738                arrows: false,
1739                centerMode: true,
1740                centerPadding: '25%',
1741                slidesToShow: 1,
1742                speed: 500
1743              }
1744            }
1745          ]
1746        },
1747        'gallery': {
1748          fade: true,
1749          arrows: false,
1750          dots: true,
1751          customPaging: function(slick,index) {
1752            var targetImage = slick.$slides.eq(index).find('img').attr('src');
1753            return '<img src="' + targetImage + '" alt="">';
1754          },
1755          infinite: true,
1756          autoplay: false,
1757          speed: 500,
1758          slidesToShow: 1,
1759          slidesToScroll: 1
1760        }
1761      };
1762      // function PC:3枚以上でスライダー体裁 SP:スライダー体裁なし
1763      var bannerInit = function(_slider){
1764        if(!u.isRangeSP()){
1765          if(!_slider.hasClass(slickInitName)){
1766            _slider.slick(settings.banner);
1767          }
1768        } else {
1769          if(_slider.hasClass(slickInitName)){
1770            _slider.slick('unslick');
1771          }
1772        }
1773      };
1774      // function スライダーリサイズ:bannerInit
1775      var bannerDeviceCheck = function(_slider){
1776        u.isWindowSizeWatch(function(){
1777          bannerInit(_slider);
1778        });
1779      };
1780      // init:配列slidersに設定した名前ごとにスライダー実行
1781      for(var i=0; i<sliders.length; i++){
1782        var slider = $('.' + prefix + sliders[i]);
1783        if(slider.length !== 0){
1784          switch(sliders[i]){
1785            case 'hero':
1786              if(!slider.hasClass(slickInitName)){
1787                slider.slick(settings.hero);
1788              }
1789              break;
1790            case 'banner':
1791              bannerInit(slider);
1792              bannerDeviceCheck(slider);
1793              break;
1794            case 'banner2':
1795              if(!slider.hasClass(slickInitName)){
1796                slider.slick(settings.banner2);
1797              }
1798              break;
1799            case 'banner3':
1800              if(!slider.hasClass(slickInitName)){
1801                slider.slick(settings.banner3);
1802              }
1803              break;
1804            case 'gallery':
1805              if(!slider.hasClass(slickInitName)){
1806                slider.slick(settings.gallery);
1807              }
1808              break;
1809            // カスタマイズ用オプションは以下の体裁で追加
1810            /*
1811            case 'xxxxx':
1812              slider.slick(settings.xxxxx);
1813              break;
1814            */
1815            default:
1816              break;
1817          }
1818        }
1819      }
1820      // init:配列vueSlidersに設定した名前ごとにスライダー実行
1821      for(var j=0; j<vueSliders.length; j++){
1822        var vueSlider = $('.' + prefix + vueSliders[j] + '.' + readyName);
1823        if(vueSlider.length !== 0){
1824          switch(vueSliders[j]){
1825            case 'banner-vue':
1826              bannerInit(vueSlider);
1827              bannerDeviceCheck(vueSlider);
1828              break;
1829            case 'banner2-vue':
1830              if(!vueSlider.hasClass(slickInitName)){
1831                vueSlider.slick(settings.banner2);
1832              }
1833              break;
1834            case 'banner3-vue':
1835              if(!vueSlider.hasClass(slickInitName)){
1836                vueSlider.slick(settings.banner3);
1837              }
1838              break;
1839            // カスタマイズ用オプションは以下の体裁で追加
1840            /*
1841            case 'xxxxx':
1842              slider.slick(settings.xxxxx);
1843              break;
1844            */
1845            default:
1846              break;
1847          }
1848        }
1849      }
1850    },
1851    /**
1852     * @method rwdImageMaps
1853     * - マップのレスポンシブ対応
1854     * @requires jquery.rwdImageMaps.js
1855     */
1856    rwdImageMaps: function(config){
1857      // options
1858      var c = $.extend({
1859        factorElement: '.js-rwdImageMaps'
1860      }, config);
1861      // vars
1862      var $elm = $(c.factorElement);
1863      // exit
1864      if($elm.length === 0){ return false; }
1865      // setting:初期値設定
1866      $elm.each(function(){
1867        var self = $(this);
1868        self.rwdImageMaps();
1869      });
1870    },
1871    /**
1872     * @method vueRenderingControl
1873     * - Vue出力
1874     */
1875    vueRenderingControl: function(config){
1876      var c = $.extend({
1877        factorElement: '.js-vueRendering',
1878        jsonData: 'data-json',
1879      }, config);
1880      // vars
1881      var $elm = $(c.factorElement),
1882          jsonData = c.jsonData;
1883      // exit
1884      if ($elm.length === 0) { return false; }
1885      // setting
1886      $elm.each(function () {
1887        const { createApp } = Vue;
1888        var $self = $(this),
1889            elmID = $self.attr('id'),
1890            jsonPath = $self.attr(jsonData);
1891        // mixin
1892        const mixin = {
1893          data() {
1894            return {
1895              error: 0, //エラー状態
1896              result: {} //取得結果格納用
1897            };
1898          },
1899          methods: {
1900            getData() {
1901              const _this = this;
1902              const getJson = $.ajax({
1903                url: _this.url,
1904                type: 'GET',
1905                dataType: 'json',
1906                timeout: 30000
1907              });
1908              $.when(getJson).done(function (data) {
1909                //結果をresultに格納、各種状態管理用の変数を完了ステータスに変更
1910                _this.error = 0;
1911                _this.result = data;
1912              })
1913              .fail(function () {
1914                //通信エラー時の再試行。
1915                //再試行回数が指定数に達した場合は状態管理用の変数を更新しAjaxを停止
1916                if (_this.error <= 5) {
1917                  _this.error++;
1918                  _this.getData();
1919                } else {
1920                  $self.hide();
1921                  _this.error = true;
1922                }
1923              });
1924            }
1925          },
1926          created() {
1927            this.getData();
1928          },
1929          updated() {
1930            COMMON.module.newCheck();
1931            COMMON.module.updateControl();
1932            COMMON.module.heightCompare();
1933          }
1934        };
1935        const app = createApp({
1936          mixins: [mixin],
1937          data() {
1938            return {
1939              url: jsonPath
1940            };
1941          }
1942        });
1943        app.mount('#' + elmID);
1944      });
1945    },
1946    /**
1947     * @method vueSliderControl
1948     * - スライダーVue出力
1949     * @requires slick.js
1950     */
1951    vueSliderControl: function(config){
1952      var c = $.extend({
1953        factorElement: '.js-vueSlider',
1954        sliderPrefix: 'js-slider-',
1955        jsonData: 'data-json',
1956        stationNumData: 'data-station-number',
1957        randomData: 'data-random'
1958      }, config);
1959      // vars
1960      var $elm = $(c.factorElement),
1961          sliderPrefix = c.sliderPrefix,
1962          jsonData = c.jsonData,
1963          stationNumData = c.stationNumData,
1964          randomData = c.randomData,
1965          readyName = u.state.ready;
1966      // exit
1967      if($elm.length === 0){ return false; }
1968      // setting
1969      $elm.each(function(){
1970        const { createApp } = Vue;
1971        var $self = $(this),
1972            elmID = $self.attr('id'),
1973            jsonPath = $self.attr(jsonData),
1974            outputData,
1975            stationData = $self.attr(stationNumData),
1976            randomFlag = $self.attr(randomData);
1977        //function 項目の表示・非表示
1978        var stationDisplay = function(_data){
1979          var displayArray = [];
1980          if(_data.length !== 0 && _data[0].station_display !== undefined){
1981            for (var i=0; i<_data.length; i++){
1982              var displayFlag = _data[i].station_display;
1983              if(displayFlag === 'T'){
1984                displayArray.push(_data[i]);
1985              }
1986            }
1987            outputData = displayArray;
1988          }
1989        };
1990        //function jsonをランダム表示
1991        var randomArray = function(_data){
1992          if(_data.length !== 0 && randomFlag === 'T'){
1993            for (var i=_data.length-1; i>=0; i--) {
1994              var rand = Math.floor(Math.random()*(i+1)),
1995                  tmp = _data[i];
1996              _data[i] = _data[rand];
1997              _data[rand] = tmp;
1998            }
1999          }
2000        };
2001        //function 駅名を配列化
2002        var createStationColumn = function(_data){
2003          if(_data.length !== 0 && _data[0].station !== undefined){
2004            for (var i=0; i<_data.length; i++){
2005              var station = _data[i].station,
2006                  stationArray = station.split(',');
2007              _data[i].station = stationArray;
2008            }
2009          }
2010        };
2011        //function 駅番号でデータをソート
2012        var stationSort = function(_data){
2013          if(_data.length !== 0 && stationData !== 'all' && stationData !== '' && stationData !== undefined){
2014            stationData = stationData.replace('TX', '');
2015            var stationSortData = [];
2016            for (var i=0; i<_data.length; i++){
2017              var stationNum = _data[i].station_number.replace('TX', ''),
2018                  stationNumArray = stationNum.split(',');
2019              for (var j=0; j<stationNumArray.length; j++){
2020                if(stationNumArray[j] === stationData){
2021                  stationSortData.push(_data[i]);
2022                  break;
2023                } else {
2024                  continue;
2025                }
2026              }
2027            }
2028            outputData = stationSortData;
2029          }
2030        };
2031        //mixin
2032        var mixin = {
2033          data() {
2034            return {
2035              error: 0, //エラー状態
2036              result: {} //取得結果格納用
2037            };
2038          },
2039          methods: {
2040            getData(){
2041              var _this = this,
2042                  getJson = $.ajax({
2043                    url: _this.url,
2044                    type: 'GET',
2045                    dataType: 'json',
2046                    timeout : 30000
2047                  });
2048              $.when(getJson).done(function(data){
2049                if(data.length === 0){
2050                  _this.result = [];
2051                  return false;
2052                }
2053                //結果をresultに格納、各種状態管理用の変数を完了ステータスに変更
2054                _this.error = 0;
2055                outputData = data;
2056                stationDisplay(outputData);
2057                randomArray(outputData);
2058                createStationColumn(outputData);
2059                stationSort(outputData);
2060                _this.result = outputData;
2061              })
2062              .fail(function(){
2063                //通信エラー時の再試行。
2064                //再試行回数が指定数に達した場合は状態管理用の変数を更新しAjaxを停止
2065                if(_this.error <= 5){
2066                  _this.error++;
2067                  _this.getData();
2068                }else{
2069                  _this.error = true;
2070                }
2071              });
2072            }
2073          },
2074          created(){
2075            this.getData();
2076          },
2077          updated(){
2078            this.$nextTick(function(){
2079              $('#' + elmID).find('[class*="' + sliderPrefix + '"]').addClass(readyName);
2080              COMMON.module.newCheck();
2081              COMMON.module.sliderControl();
2082              COMMON.module.heightCompare();
2083            });
2084          }
2085        };
2086        const app = createApp({
2087          mixins: [mixin],
2088          data() {
2089            return {
2090              url: jsonPath
2091            };
2092          }
2093        });
2094        app.mount('#' + elmID);
2095      });
2096    }
2097  };
2098}();
2099
2100
2101/**
2102 * @execution
2103 */
2104$(function(){
2105  'use strict';
2106  // onReady
2107  COMMON.module.initialize();
2108});
2109
2110$(window).on('load', function(){
2111  'use strict';
2112  // onLoad
2113  COMMON.module.equalHeight(true, true);
2114  COMMON.module.swapImg();
2115  COMMON.module.modalControl();
2116  COMMON.module.heightCompare();
2117});

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.