var web_root="/";(function ($) { /** 統一高度用的PLUGIN */ $.fn.extend({ imgLoaded: function( callback ) { var i, c = true, t = this, l = t.length; for ( i = 0; i < l; i++ ) { if (this.tagName === "IMG") { c = (c && this.complete && this.height !== 0); } } if (c) { if (typeof callback === "function") { callback(); } } else { setTimeout(function(){ $(t).imgLoaded( callback ); }, 200); } }, sameHeight: function(opt){ var options = $.extend({ item : '.item', overWidth: 0 }, opt ); return this.each(function(){ var $this = $(this), $win = $(window), $item = $this.find(options.item), _init = $this.data('init'), _tempW = 0, overWidth = options.overWidth, setWidth = function(){ var _maxH = 0, _ww = $win.width(); if( _tempW != _ww ) { _tempW = _ww; $item.css({ height:''}); if(_ww > overWidth ){ if($item.find('img').length){ $item.find('img').imgLoaded(function(){ $item.each(function(){ var _h = $(this).outerHeight(); if( _h > _maxH ) _maxH = _h; }).css({height: _maxH + 'px'}); }) }else { $item.each(function(){ var _h = $(this).outerHeight(); if( _h > _maxH ) _maxH = _h; }).css({height: _maxH + 'px'}); } } } }, bindEvent = function(){ $win.on('resize.setH', setWidth).on('load', function(){ $win.trigger('resize.setH'); }) }; if(!_init) { $this.data('init', true); bindEvent(); } }) } }); $.fn.addNavStyle = function () { return this.each(function () { var $self = $(this), $nav = $self.find('li'), $hasNode = $nav.filter(':has(ul), :has(.sub-nav)'); $hasNode.addClass('has-nav'); $nav.each(function (n) { var $this = $(this); if($this.is('.on')) $this.data('currentOn', true); }); }) }, $(function () { var _root = typeof(web_root) == 'undefined' ? '' : web_root; var $win = $(window), $body = $('body'), $container = $('#container'), $header = $('#header'), $banner = $('.banner'), $navBtn = $('#nav-btn, #nav-btn2'), $mainNavWrap = $('#main-nav'), $mobileNavWrap = $mainNavWrap.find('.mobile-nav'), $subNav = $mainNavWrap.find('.sub-nav'), $mobileSide = $header.find('.mobile-side'), $serachBtn = $('#search-btn'), $searchWrap = $('#search-wrap'), $dynNode = $('.dyn-node'), $dynNodeWrap = $('.dyn-node-wrap'), $footer = $('#footer'), $ftNav = $('.footer-nav'), $maskBg = $('#mask-bg'), $goTop = $('#go-top'), $btnBack = $(''), $infoNav = $('.info-nav'), $cate = $('.cate-wrap .cate'), $datePicker = $('.datepicker'), tempW = 0, brokenWidth = 992, setmainNavWrapHeight = function() { if($win.width() >= 992){ $mobileSide.css({'height': ''}); }else{ $mobileSide.css({'height': ($win.height() - $header.find('.hd-s1').outerHeight()) + 'px'}); } }, moveNode = function() { $dynNode.each(function(){ var $this = $(this), nodeName = this.getAttribute('data-node-name'), resize_width = this.getAttribute('data-resize') != null ? this.getAttribute('data-resize') : brokenWidth, _parentAttr = tempW >= resize_width ? 'data-pc-child': 'data-mb-child', _init = $this.parent()[0].getAttribute(_parentAttr) == nodeName; if(!_init) { $dynNodeWrap.filter(function(){ return this.getAttribute(_parentAttr) == nodeName; }).append($this); } }); }, openNav = function () { closeSearch(); $body.addClass('lock'); //$navBtn.addClass('on'); $mobileSide.addClass('on'); $maskBg.addClass('on'); }, closeNav = function () { $mobileSide.removeClass('on'); $mainNavWrap.find('.nav-wrap').removeAttr('data-lv'); $mainNavWrap.find('.has-nav').removeClass('switch').filter(function(){return $(this).data('open')== true; }).addClass('on'); $navBtn.removeClass('on'); $maskBg.removeClass('on'); $body.removeClass('lock'); }, switchNav = function(p0){ $mainNavWrap.find('.nav-wrap').removeAttr('data-lv'); $(p0).addClass('on switch').siblings().removeClass('on switch'); }, checkNavBtn = function (p0) { var _NavOn = $navBtn.hasClass('on'); if (p0 >= 992 && _NavOn) closeNav(); } openSearch = function () { closeNav(); $body.addClass('lock'); $serachBtn.addClass('on'); $searchWrap.addClass('on'); $maskBg.addClass('on'); }, closeSearch = function () { $serachBtn.removeClass('on'); $searchWrap.removeClass('on'); $maskBg.removeClass(); $body.removeClass('lock'); }, checkSearchBtn = function (p0) { var _NavOn = $serachBtn.hasClass('on'); if (p0 >= 992 && _NavOn) closeSearch(); } checkGoTop = function (p0) { if (p0 < $footer.offset().top) { $goTop.removeClass('end'); } else { $goTop.addClass('end'); } }; //加入主要導覽列樣式 $mainNavWrap.addNavStyle(); //行動版選單鈕(主導覽開合) if($navBtn.length){ $navBtn.on('click', function (e) { e.preventDefault(); var $this = $(this), elemId = $this.attr('href') === '#second-nav' ? $this.attr('href') : '#primary-nav', isOpen = !$navBtn.filter('.on').length && $this.not('.on'), isSwitch = $navBtn.filter('.on').length && !$(elemId).is('.on, .switch'), isClose = $this.is('.on') && $(elemId).is('.on, .switch'); if(isOpen){ $this.addClass('on'); $(elemId).addClass('on'); openNav(); setmainNavWrapHeight(); }else if(isSwitch){ $navBtn.removeClass('on'); $this.addClass('on'); switchNav(elemId); }else if(isClose) { closeNav(); } }); } //行動版搜尋鈕(搜尋區開合) if($serachBtn.length){ $serachBtn.on('click', function(e){ e.preventDefault(); var isOpen = $(this).hasClass('on'); isOpen ? closeSearch() : openSearch(); }); } //主要導覽列開合 if ($mainNavWrap.length) { const $navWrap = $mainNavWrap.find('.nav-wrap'); // 點擊主選單項目進入子選單 $mainNavWrap.on('click', '.has-nav > a', function (e) { const _w = $win.width(); const $this = $(this); const $parent = $this.parent(); const $sub = $this.next('.sub-nav'); if (_w < 992 && $sub.length) { e.preventDefault(); const lv = $sub.hasClass('lv2') ? '2' : '1'; $navWrap.attr('data-lv', lv); $parent.addClass('switch'); $mobileNavWrap.addClass('on'); // 若沒有 .btn-back,就插入 if (!$sub.find('.btn-back').length) { const $btnBack = $(''); $sub.prepend($btnBack); } $sub.find('.btn-back').first()[0].focus({ preventScroll: true }); } }); // 點擊返回按鈕 $mainNavWrap.on('click', '.btn-back', function (e) { e.preventDefault(); const $sub = $(this).closest('.sub-nav'); const isLv2 = $sub.hasClass('lv2'); const $parent = $sub.closest('.switch'); $parent.removeClass('switch'); // 根據層級調整 data-lv if (isLv2) { $navWrap.attr('data-lv', '1'); } else { $navWrap.removeAttr('data-lv'); } $parent.children('a')[0]?.focus({ preventScroll: true }); }); // 鍵盤操作:主選單 tab 到最後關閉 $mainNavWrap.on('keydown', function (e) { if (e.key !== 'Tab') return; const focusables = $navWrap.find('a, button').filter(':visible'); const first = focusables.first()[0]; const last = focusables.last()[0]; if (!e.shiftKey && document.activeElement === last) { // tab 出最後一個元素時關閉選單 closeNav(); } }); // 鍵盤操作:子選單 tab 到底 / 頭時回上一層 $mainNavWrap.on('keydown', '.sub-nav', function (e) { if (e.key !== 'Tab') return; const _w = $win.width(); // 讀取目前視窗寬度 if (_w >= 992) { // 桌機版不阻止 tab 行為,放行 return; } const $sub = $(this); const isLv2 = $sub.hasClass('lv2'); const focusables = $sub.find('a, button').filter(':visible'); const first = focusables.first()[0]; const last = focusables.last()[0]; // tab 到最後,或 shift+tab 到最前,回上一層 if ((!e.shiftKey && document.activeElement === last) || (e.shiftKey && document.activeElement === first)) { e.preventDefault(); // 阻止預設 tab const $parent = $sub.closest('.switch'); $parent.removeClass('switch'); if (isLv2) { $navWrap.attr('data-lv', '1'); } else { $navWrap.removeAttr('data-lv'); $mobileNavWrap.removeClass('on'); } $parent.children('a')[0]?.focus({ preventScroll: true }); } }); // 針對有焦點的 a 加 switch,並移除兄弟的 switch $mainNavWrap.on('focusin', '.has-nav > a', function() { const _w = $win.width(); if (_w < 992) return; // 手機版不加 switch // 手機也加,但你已有手機版控制開關,不用特別判斷 const $li = $(this).closest('.has-nav'); $li.addClass('switch').siblings('.has-nav').removeClass('switch'); }); // 當整個 mainNavWrap 裡沒有任何子元素獲得焦點,移除所有 switch $mainNavWrap.on('focusout', function(e) { // 因為 focusout 事件是逐層冒泡,這裡使用 setTimeout 確保真正離開 setTimeout(() => { if (!$mainNavWrap.find(':focus').length) { $mainNavWrap.find('.has-nav.switch').removeClass('switch'); } }, 0); }); } //頁尾導覽列開合 if($ftNav.length) { $ftNav.find('.footer-title').on('click', function (e) { if ($win.width() < 992) { e.preventDefault(); const $li = $(this).parent(); const isOpen = $li.hasClass('on'); $li.toggleClass('on'); $(this).attr('aria-expanded', !isOpen); } }); function updateFooterTabindex() { $ftNav.find('.footer-title').attr('tabindex', $win.width() < 992 ? '0' : '-1'); } updateFooterTabindex(); $win.on('resize', updateFooterTabindex); } //畫面大小變更時樣式重新設定 $win.on('resize', function () { var _w = $win.width(); if(tempW != _w && $mainNavWrap.length) { setmainNavWrapHeight(); //setNavNode(_w); checkNavBtn(_w); checkSearchBtn(_w); } if(tempW != _w) { tempW = _w; moveNode(); } }).trigger('resize'); //行動版遮罩點選時關閉已開啟之主要導覽列及搜尋區塊 $maskBg.on('click',function(){ closeNav(); closeSearch(); }); //回頂端事件 $goTop.on('click', function (e) { e.preventDefault(); $('html, body').stop().animate({ scrollTop: 0 }, 300); }); $win.on('scroll', function () { var _scroll = $win.scrollTop(), _winH = $win.height(), _top = $header.outerHeight(); $goTop[_scroll > _top ? 'addClass' : 'removeClass']('block'); checkGoTop(_winH + _scroll); }).trigger('scroll'); $win.on('load', function(){ $(this).trigger('resize').trigger('scroll'); }).trigger('resize'); //單元選單手機下拉樣式開合 if($infoNav.length){ $infoNav.find('.label').on('click', function(e){ e.preventDefault(); var $this = $(this); $this.parent().toggleClass('on'); }) $infoNav.find('li:has(.sub-nav) > a').on('click', function (e) { e.preventDefault(); const $link = $(this); const $li = $link.parent(); const isExpanded = $li.hasClass('on'); // 切換 .on 類別 $li.toggleClass('on').siblings().removeClass('on'); // aria-expanded 切換 $infoNav.find('li:has(.sub-nav) > a').attr('aria-expanded', 'false'); $link.attr('aria-expanded', String(!isExpanded)); }); const $current = $infoNav.find('li.on > a'); if ($current.length && $current[0].focus) { try { $current[0].focus({ preventScroll: true }); } catch (e) { const scrollTop = $(window).scrollTop(); $current.focus(); $(window).scrollTop(scrollTop); } } $infoNav.on('keydown', function (e) { if (e.key !== 'Tab') return; const focusables = $infoNav.find('a, button').filter(':visible'); const first = focusables.first()[0]; const last = focusables.last()[0]; if (!e.shiftKey && document.activeElement === last) { // Tab 鍵離開最後一個 focusable 元素時,關閉選單 $infoNav.removeClass('on'); } }); } //類別選單下拉樣式開合 if($cate.length){ $cate.find('.label-title').on('click', function(e){ e.preventDefault(); var $this = $(this); $this.parent().toggleClass('on').siblings().removeClass('on'); }); $win.on('click', function(e){ if(!$(e.target).closest('.cate').length) $cate.removeClass('on'); }) // 焦點移出時關閉(適用鍵盤 Tab) $cate.on('focusout', function (e) { setTimeout(function () { if (!$(document.activeElement).closest('.cate').length) { $cate.removeClass('on'); } }, 10); }); } //日期套件 if($datePicker.length){ $.getScript(_root + 'inc/js/jquery-ui-1.11.0/jquery-ui.min.js', function(){ $datePicker.datepicker({ dateFormat: 'yy-mm-dd' }); }) } }); })(jQuery);