nfu-nfuosa/assets/javascripts/app.js

2944 lines
112 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;(function($, win, undefined) {
// ECMAScript 5 嚴格模式
'use strict';
$(function() {
var $signLanguageBox = $('.orbit-bar-search-sign-language');
var $headerNav = $('.header-nav');
var $target = $('.header-nav [accesskey="U"], .header-nav [accesskey="W"]');
// 移除 color: inherit !important
$target.each(function() {
$(this)[0].style.removeProperty('color');
});
function handleNavMove() {
var windowWidth = window.innerWidth;
if (windowWidth > 768) {
if ($signLanguageBox.length && $signLanguageBox.find('[accesskey="U"], [accesskey="W"]').length === 0) {
$signLanguageBox.prepend($target);
}
} else {
if ($headerNav.length && $headerNav.find('[accesskey="U"], [accesskey="W"]').length === 0) {
$headerNav.append($target);
}
}
}
handleNavMove();
$(window).on('resize', function() {
handleNavMove();
});
});
//header fixed在上方
function initdata1() {
if ( $('.homebanner').length != 0) {
$('.layout-header').css('height', '');
var scrollTop = $(window).scrollTop();
var scrollBottom = $('html').height() - $(window).height() - $('.layout-header').height();
if (scrollTop>5 && scrollBottom>0) { /* 要滑動到選單的距離 */
if (parseInt($('.index-layout-content').css('margin-top'))==0){
}
$('.outdropdowns').addClass('navFixed'); /* 幫選單加上固定效果 */
} else {
if ($('.homebanner').html().trim() == "") {
$('.outdropdowns').removeClass('navFixed');
}else{
$('.outdropdowns').removeClass('navFixed'); /* 移除選單固定效果 */
}
}
}
}
// 初始函數: 把所有的程式碼都包在init裡面方便在之後的jQuery ready 函數裡一次呼叫
function init() {
// 快取一些常用的變數
var doc = document;
var lang = doc.documentElement.lang;
var pageModule = doc.body.getAttribute('data-module');
var resizeTimer = -1;
// 把所有的函數都包在orbit這個物件裡並按模組做簡單的分類
var orbit = {
// 工具函數,裡面包含可以重覆使用的函數
utils: {
// 字數限制函數, 因為系統預設沒有所以使用JS來做
// els = 元素, maxLen = 限制長度
truncateText: function(els, maxLen) {
var els = doc.querySelectorAll(els);
var newTitle = '';
var i = -1;
var elsLen = els.length;
for (i = 0; i < elsLen; i++) {
if (els[i].firstChild !== null) {
if (els[i].firstChild.length > maxLen) {
newTitle = els[i].firstChild.textContent;
els[i].textContent = newTitle.substring(0, maxLen) + '...';
}
}
}
}
},
// 外掛,所有的外掛都可以放到這個物件裡
// plugins: {
// // 自適應圖片裁切Ray的外掛
// bullEye: function() {
// $('.bullseye').bullseye({
// fadeEffect: false
// });
// }
// },
member: {
// 欄位相同高度,小心這個函數沒有計算到圖片高度,所以可能要搭配 jQuery load函數使用或是之後使用更好的方式例如 CSS3 flexbox
equalHeight: function(el) {
var bigbrother = -1;
var $el = $(el);
$el.each(function(i) {
bigbrother = bigbrother > $el.eq(i).height() ? bigbrother : $el.eq(i).height();
});
$el.height(bigbrother);
},
// 把沒有完成資料的表格列藏起來, 因為後台不管有沒有資料都會輸出項目,所以需要在前台藏起來…
removeEmptyRow: function() {
// index 頁面項目
$('.i-member-profile-item .i-member-value').each(function() {
if ($(this).text().trim() === '' || $(this).text().trim() === ':') {
$(this).parent().addClass('hide');
}
});
// show 頁面項目
$('.show-member .member-data th, .show-member .member-data td').each(function() {
if ($(this).text().trim() === '') {
$(this).parent('tr').addClass('hide');
}
});
},
},
archives: {
// 把沒有文字內容的標題藏起來因為就算是標題裡沒有文字系統仍然會輸出這樣會造成一些多餘的CSS margins, paddings或許之後也可以使用 CSS3 :empty selector 處理
// el = 要移除的元素
removeEmptyTitle: function(el) {
var $el = $(el);
var $els = $el.children();
$.each($els, function(i, val) {
if ($els.eq(i).text().trim() === '') {
$els.eq(i).addClass('hide');
}
});
$.each($el, function(i, val) {
if ($el.eq(i).children('.hide').length >= 2) {
$el.eq(i).addClass('hide');
}
});
},
// bootstarp panel 功能擴充因為原本的功能不支援多個panel
extendPanel: function() {
var len = $('.i-archive .panel-title').length;
var i = -1;
if (len > 0) {
// 新增數字到要對應的panel按鈕id及href上面
for (i = 0; i < len; i++) {
$('.panel-title:eq(' + i + ') .collapsed').attr('href', '#collapse' + i);
$('.panel-collapse:eq(' + i + ')').attr('id', 'collapse' + i);
}
}
}
},
adBanner: {
// 讓AD banner 的圖片可以點選,因為系統預設輸出的圖片是沒有連結的
// els = 要可以點選的元素(需要配合有data-link這個參數及data-targe才能使用)
addLinkOnADBanner: function(els) {
$.each(els, function() {
if ($(this).data('link') !== '' && !$(this).hasClass('youtube')) {
$(this).on('click', function() {
var target = $(this).data('target');
var link = $(this).data('link');
// 設定頁面打開的方式記得要加上data-target在HTML裡面
if (target === '_blank') {
window.open(link, target);
} else {
window.location.href = link;
}
}).addClass('cursor'); // cursor類別樣式定義在CSS裡面
}
});
},
},
// 移除行動版下拉選單
removeDropdown: function() {
var $nav = $('#main-nav');
$nav
.find('.menu-drop')
.remove();
$nav
.find('.opened')
.removeClass('opened');
},
// 網站次選單設定如果次選單有第三層就新增下拉選單的圖示及加上bootstrap class
// els = 選單元素
sitemenuDropdown: function(els) {
var els = doc.querySelectorAll('.sitemenu-list.level-2');
var len = els.length;
var i = -1;
var caret = null;
for (i = 0; i < len; i++) {
if (els[i].children.length) {
caret = doc.createElement('span');
caret.className = 'sitemenu-dropdown-toggle fa fa-caret-down';
caret.setAttribute('data-toggle', 'dropdown');
els[i].parentNode.insertBefore(caret, els[i]);
els[i].className += ' dropdown-menu';
}
}
},
// 回到頁面最頂端動態產生DOM
// txt = 按鈕的文字, speed = 捲動時的速度
goBackTop: function(txt, speed) {
var top = document.createElement('div');
top.className = 'go-back-top no-print';
top.textContent = txt || 'top';
doc.body.appendChild(top);
// 判斷是否顯示按鈕
$(window).scroll(function() {
if ($(this).scrollTop() !== 0) {
$('.go-back-top').fadeIn();
} else {
$('.go-back-top').fadeOut();
}
});
// 捲動效果
$('.go-back-top').on('click', function() {
$('body, html').animate({
scrollTop: 0
}, speed || 300);
return false;
});
},
// Multi-column layout, passing ID or class string as parameters and a
// Bootstrap col class for full width, eg: col-md-12
setColumn: function(leftCol, rightCol, columnCls) {
var $leftCol = $(leftCol);
var $rightCol = $(rightCol);
var columnCls = columnCls || 'col-sm-12';
if ($leftCol.length && $rightCol.length) {
$.each([$leftCol, $rightCol], function() {
if ($(this).is(':empty')) {
$(this)
.addClass('empty-column')
.siblings()
.removeClass(function(index, css) {
return (css.match(/(^|\s)col-\S+/g) || []).join(' ');
})
.addClass(columnCls);
}
});
}
},
MobileMenu: function() {
var $menu = $('[data-menu-level="0"]');
$menu.find('ul[data-menu-level="1"]').parent().addClass('mobile-menu1');
$menu.find('ul[data-menu-level="2"]').parent().addClass('mobile-menu2');
var $caret1 = $('<span class="menu-drop"><i class="dropdown-toggle-icon level-1 fa fa-chevron-down"></i></span>');
var $caret2 = $('<span class="menu-drop"><i class="dropdown-toggle-icon level-2 fa fa-chevron-down"></i></span>');
// 如果有第二層選單新增對應的類別到parent元素上
$('.nav-level-1')
.parent('li')
.addClass('has-dropdown level-1');
// 檢查是否已經有dropdown-toggle-icon這個元素才不會在resize事件中重覆新增
if ($('.has-dropdown.level-1 .menu-drop').length < 1) {
$('.mobile-menu1').append($caret1);
// 如果有第三層選單新增對應的類別到parent元素上
$('.nav-level-2')
.parent('li')
.addClass('has-dropdown level-2');
$caret2.appendTo('.has-dropdown.level-2');
}
},
ClickMenuHandler: function() {
// 處理主選單切換(漢堡 icon
$(document).on('click', '.navbar-toggle', function (e) {
e.preventDefault();
// 確保 .navbar-toggle 放到 .modules-menu 後面
$('.mobile-menu').each(function () {
var $menu = $(this);
if ($menu.find('.modules-menu').length && !$menu.find('.modules-menu + .navbar-toggle').length) {
$menu.find('.modules-menu').after($menu.find('.navbar-toggle'));
}
});
$('.mobile-menu').toggleClass('active');
$('body').toggleClass('noscroll');
$('.mobile-menu .navbar-toggle').removeClass('collapsed');
// 關閉所有下拉選單
$('.mobile-menu1 > ul, .mobile-menu2 > ul').slideUp(500);
$('.mobile-menu1 > .menu-drop, .mobile-menu2 > .menu-drop').removeClass('opened');
// 無障礙:聚焦第一個互動元素
if ($('.mobile-menu').hasClass('active')) {
setTimeout(function () {
$('.modules-menu').find('input, button, select, textarea, a').first().focus();
}, 100);
}
});
$('.mobile-menu1 > .menu-drop').click(function(){
var $that = $(this);
var opencheck1 = $that.hasClass('opened');
if ( opencheck1 == 0 ) {
$('.mobile-menu1 > ul').not($that.siblings('ul')).slideUp(500);
$('.mobile-menu1 > .menu-drop').not($that).removeClass('opened');
$('.mobile-menu2 > ul').slideUp(500);
$('.mobile-menu2 > .menu-drop').removeClass('opened');
$that.siblings('ul').slideDown(500);
$that.addClass('opened');
} else if (opencheck1 == 1) {
$that.siblings('ul').slideUp(500);
$('.mobile-menu2 > ul').slideUp(500);
$('.mobile-menu2 > .menu-drop').removeClass('opened');
$that.removeClass('opened');
}
})
$('.mobile-menu2 > .menu-drop').click(function(){
var $that = $(this);
var opencheck2 = $that.hasClass('opened');
if ( opencheck2 == 0 ) {
$('.mobile-menu2 > ul').not($that.siblings('ul')).slideUp(500);
$('.mobile-menu2 > .menu-drop').not($that).removeClass('opened');
$that.siblings('ul').slideDown(500);
$that.addClass('opened');
} else if (opencheck2 == 1) {
$that.siblings('ul').slideUp(500);
$that.removeClass('opened');
}
})
}
};
// 把orbit物件加到window物件裡面並改名為ORBITFRONT來減少名稱衝突的機會
win.ORBITFRONT = orbit;
// 在switch裡測試頁面模組後執行對應的函數
switch (pageModule) {
case 'home':
break;
case 'member':
orbit.member.removeEmptyRow();
break;
case 'archive':
orbit.archives.removeEmptyTitle('.i-archive__category-item');
orbit.archives.extendPanel();
break;
case 'gallery':
orbit.utils.truncateText('.show-description', 15);
break;
default:
break;
}
// 在所有的頁面(包含首頁)執行下面這幾個函數
initdata1();
orbit.sitemenuDropdown();
orbit.goBackTop('top', 800);
// orbit.plugins.bullEye();
orbit.setColumn('.left-column', '.right-column');
// 自適應網頁使用當網頁載入時如果視窗寬度小於769就執行orbit.nav.setDropdown函數
if ($(window).width() < 769) {
// orbit.nav.setDropdown();
orbit.MobileMenu();
$('.mobile-menu').append($('.modules-menu'));
$('.header-buttom').appendTo($('.modules-menu'));
orbit.ClickMenuHandler();
}
// 自適應網頁使用當使用者改變瀏覽器寬度時呼叫orbit.nav.setDropdown函數
$(window).resize(function() {
if ($(window).width() < 769) {
if (resizeTimer) clearTimeout(resizeTimer);
resizeTimer = setTimeout(function() {
// if ( $('.modules-menu i').length == 0 ) {
// orbit.MobileMenu();
// }
if( $('.mobile-menu .modules-menu').length == 0 ) {
$('.mobile-menu').append($('.modules-menu'));
$('.header-buttom').appendTo($('.modules-menu'));
orbit.MobileMenu();
orbit.ClickMenuHandler();
// $('.navbar-toggle').bind('click', orbit.ClickMenuHandler);
// $('.navbar-toggle').bind(orbit.ClickMenuHandler());
}
},500 )} else {
resizeTimer = setTimeout(function(){
if( $('.mobile-menu .modules-menu').length > 0 ) {
$('.layout-header .outdropdowns .dropdowns').append($('.modules-menu'));
$('.dropdowns').append($('.header-buttom'));
}
orbit.removeDropdown();
}, 500);
}
});
// if($(window).width()<769){
// $('.header-buttom').appendTo($('.modules-menu'));
// }else{
// $('.header-buttom').appendTo($('.dropdowns'));
// }
function forFreeGo() {
setTimeout(function() {
$('h1, h2, h3, h4, h5, h6').each(function() {
var $heading = $(this);
// 檢查是否為空 (去除空白後)
if ($.trim($heading.text()) === '' && $heading.children().length === 0) {
$heading.remove();
}
});
}, 500);
//zoom
$(function () {
$('.fnav a').each(function () {
const $a = $(this);
// 若已經有可見文字(非 icon直接通過
const visibleText = $a.clone()
.children('.icon, i, svg, .caret')
.remove()
.end()
.text()
.trim();
if (visibleText.length > 0) return;
// 取得可用標籤文字(優先順序)
let label =
$a.attr('aria-label') ||
$a.attr('title') ||
$a.find('i[title]').attr('title') ||
'';
label = $.trim(label);
// 若真的完全沒有,就給一個保底(避免空字串違規)
if (!label) {
label = '功能按鈕';
}
// aria-label 一定要有
$a.attr('aria-label', label);
// icon 對螢幕閱讀器隱藏
$a.find('i, svg').attr('aria-hidden', 'true');
// 若沒有隱藏文字才補
if ($a.find('.sr-only, .visually-hidden').length === 0) {
$a.append(`<span class="sr-only">${label}</span>`);
}
});
});
//播放驗證碼語音
$(function () {
$('.ask-question')
.find('.controls button.fas.fa-volume-up')
.each(function () {
const $btn = $(this);
// 已經補過就不重複處理
if ($btn.attr('aria-label')) return;
$btn.attr({
'aria-label': '播放驗證碼語音',
'aria-controls': 'captcha_audio',
'role': 'button'
});
});
});
//刪除td的id
$('td[id]').removeAttr('id');
//刪除空的title
$('[class*="title"]').each(function () {
const $el = $(this);
// 取純文字(忽略 HTML tag、空白、換行
const text = $.trim($el.text());
if (text === '') {
$el.remove();
}
});
//表單legend
$("fieldset").each(function () {
const $fieldset = $(this);
const hasLegend = $fieldset.children("legend").length > 0;
if (!hasLegend) {
// 嘗試抓最上層的群組標題,例如 "Apply"
const headingText = $fieldset.find(".form-group:first").text().trim() || "表單填寫";
// 插入 legend 為第一個元素
$fieldset.prepend(`<legend>${headingText}</legend>`);
}
});
// 處理「上一頁」按鈕
$(".cmdBackward").each(function () {
$(this)
.attr("title", "上一頁")
.attr("aria-label", "上一頁");
if ($(this).find(".sr-only").length === 0) {
$(this).append('<span class="sr-only">上一頁</span>');
}
$(this).find("i").attr("aria-hidden", "true");
$(this).find(".icon").attr("aria-hidden", "true");
});
// 處理「下一頁」按鈕
$(".cmdForward").each(function () {
$(this)
.attr("title", "下一頁")
.attr("aria-label", "下一頁");
if ($(this).find(".sr-only").length === 0) {
$(this).append('<span class="sr-only">下一頁</span>');
}
$(this).find("i").attr("aria-hidden", "true");
$(this).find(".icon").attr("aria-hidden", "true");
});
$('.pagination li.active a').attr('aria-current', 'page');
$('path').each(function () {
$(this)
.attr('aria-hidden', 'true')
.attr('focusable', 'false')
.attr('tabindex', '-1');
});
$('.controlplay a[role="radio"]').on('click', function () {
// 取消所有的 aria-checked 並還原文字
$('.controlplay a[role="radio"]').attr('aria-checked', 'false');
$('.controlplay a[role="radio"] span').each(function () {
var text = $(this).text().replace('(已選取)', '');
$(this).text(text);
});
// 設定目前被點擊的按鈕為已選取
$(this).attr('aria-checked', 'true');
var selectedText = $(this).text().trim();
$(this).find('span').text(selectedText + '(已選取)');
});
// 遍历所有的 .s-annc__tag-wrap 元素
$('.s-annc__tag-wrap').each(function() {
// 遍历 .s-annc__tag-wrap 下的每个 a 元素
$(this).find('a').each(function() {
// 如果 .s-annc__tag 元素为空或没有内容
if ($(this).find('.s-annc__tag').is(':empty')) {
// 移除该 a 元素
$(this).remove();
}
});
});
$('.w-ba-banner__caption li button').each(function (index) {
const $slide = $('.w-ba-banner__slide').eq(index);
const title = $slide.attr('data-cycle-title')?.trim();
if (title) {
const fullText = title + '的pager';
$(this).attr('aria-label', fullText);
$(this).attr('title', fullText);
}
});
// 當 focus 到 menu link 時,顯示對應 ul
$('.sitemenu-item > a').on('focus', function () {
$(this).siblings('ul').addClass('show');
});
// 當 focus 離開最後一個子選單 link 時,移除 .show
$('.sitemenu-item').each(function () {
const $submenuLinks = $(this).find('ul a');
if ($submenuLinks.length > 0) {
$submenuLinks.last().on('blur', function () {
// 當最後一個子項 blur 時關閉 ul
$(this).closest('ul').removeClass('show');
});
} else {
// 若沒有子項,當主選單項 blur 也隱藏
$(this).find('> a').on('blur', function () {
$(this).siblings('ul').removeClass('show');
});
}
});
if (document.documentElement.lang === 'zh_tw') {
document.documentElement.lang = 'zh-Hant';
}
//tab鍵按下
$(document).on('keydown', function(e) {
if (e.key === "Tab" || e.keyCode === 9) {
$('.header-nav, .dropdowns').css('display', 'block');
}
});
function handleHover() {
// 先統一移除舊事件,避免重複綁定
$('li').off('mouseenter mouseleave focusin focusout');
if ($(window).width() > 769) {
// 1. 處理滑鼠 Hover
$('li').hover(
function() { $(this).children('ul').addClass('show'); },
function() { $(this).children('ul').removeClass('show'); }
);
// 2. 處理鍵盤 Tab 聚焦 (關鍵修正)
$('li').on('focusin', function() {
// 當焦點進入 li 或其子元素時,顯示選單
$(this).children('ul').addClass('show');
});
$('li').on('focusout', function() {
var $this = $(this);
// 延遲偵測焦點是否真的「離開」了這個 li 區塊
setTimeout(function() {
// 如果新的焦點不在當前這個 li 裡面,才移除 show
if ($this.find(':focus').length === 0) {
$this.children('ul').removeClass('show');
}
}, 10);
});
}
}
// 初始化與 Resize 監聽保持不變
handleHover();
$(window).on('resize', function() {
handleHover();
});
//刪除空的h1
$('h1').each(function() {
if ($(this).text().trim() === '') {
$(this).remove();
}
});
//refresh_btn加上aria-label
$('#refresh_btn').each(function() {
var $this = $(this);
// 如果 button 尚未有 aria-label則新增
if (!$this.attr('aria-label')) {
$this.attr('aria-label', '重新整理');
}
});
//無障礙會員表格刪除沒有顯示的th
$('.i-member-tr-head').each(function() {
if ($(this).css('display') === 'none') {
$(this).remove();
}
});
//無障礙公告a是空的
$('.w-annc__subtitle').each(function () {
var $this = $(this);
var $link = $this.find('a');
// 檢查 a 是否存在,且去除空白後是否為空字串
if ($link.length && $link.text().trim() === '') {
$this.remove(); // 移除外層 .w-annc__subtitle
}
});
//無障礙單位轉換
$(function() {
$('style:contains("font-size")').each(function() {
let css = $(this).html();
css = css.replace(/font-size\s*:\s*([\d.]+)px\s*;?/gi, (_, px) =>
`font-size: ${(parseFloat(px) / 16).toFixed(3)}em;`
);
$(this).html(css);
});
});
$("[style*='font-size']").each(function() {
var fontSize = $(this).css("font-size");
if (fontSize.includes("px")) {
var pxValue = parseFloat(fontSize); // 取得數值
var emValue = pxValue / 16; // 假設 1em = 16px
$(this).css("font-size", emValue + "em");
}
});
$("[style*='font-size']").each(function() {
var fontSize = $(this).css("font-size");
if (fontSize.includes("pt")) {
var ptValue = parseFloat(fontSize); // 取得數值
var emValue = ptValue / 12; // 1em = 12pt一般轉換標準
$(this).css("font-size", emValue + "em");
}
});
$("[style*='font-size']").each(function() {
var styleAttr = $(this).attr("style"); // 取得原始 style 屬性字串
var match = styleAttr.match(/font-size\s*:\s*(\d+(?:\.\d+)?)pt/i);
if (match) {
var ptValue = parseFloat(match[1]);
var emValue = ptValue / 12;
// 替換 style 屬性字串中的 pt 為 em
var newStyle = styleAttr.replace(/font-size\s*:\s*\d+(?:\.\d+)?pt/i, `font-size: ${emValue}em`);
$(this).attr("style", newStyle);
}
});
//表格scope
$("table").each(function() {
$(this).find("tr").each(function(rowIndex) {
$(this).find("th").each(function(colIndex) {
if (rowIndex === 0) {
// 第一列的 th適用於該欄
$(this).attr("scope", "col");
} else if (colIndex === 0) {
// 其他列的第一個 th適用於該行
$(this).attr("scope", "row");
}
});
});
});
$(".banner-pager button").addClass('banner-pagerbtn');
$(".banner-pager button").attr("type","button");
$(".banner-pager button").append('<span style="display: none;">下一張</span>');
$("button").attr("role", "button");
$("select").attr("title","選擇類別");
$(".jarallax-video-audio").attr("role", "button");
$('button').each(function() {
var $this = $(this);
if (!$this.attr('title') || $this.attr('title').trim() === '') {
$this.attr('title', '按鈕');
}
});
function removeEmptyTitles() {
// 定義所有需要檢查的 class
const targetClasses = [
'.w-annc__widget-title',
'.widget-title',
'.show-title',
'.event-annc-title',
'.annc-title',
'.sitemenu-title',
'.widget-link__widget-title'
];
// 將陣列轉換為 jQuery 選擇器字串
const selector = targetClasses.join(', ');
$(selector).each(function() {
// 使用 $.trim 移除空格、換行符號
// 然後檢查裡面是否完全沒有文字
const textContent = $.trim($(this).text());
if (textContent === "") {
// 如果沒有文字,則將整個元素刪除
$(this).remove();
}
});
}
// 執行 function
$(document).ready(function() {
removeEmptyTitles();
});
// $(".w-annc__img-wrap a").each(function () {
// var $this = $(this);
// // 確保 <a> 內沒有文字節點 (避免重複添加)
// if ($this.text().trim() === "") {
// $this.append('<span class="sr-only">公告圖片</span>');
// }
// });
$(".widget-link__widget-title").each(function () {
if ($(this).text().trim() === "") {
$(this).append('<span class="sr-only">公告標題</span>');
}
});
$(".sitemenu-title").each(function () {
if ($(this).text().trim() === "") {
$(this).append('<span class="sr-only">次選單</span>');
}
});
$(".annc-title").each(function () {
if ($(this).text().trim() === "") {
$(this).append('<span class="sr-only">內頁公告標題</span>');
}
});
$(".event-annc-title").each(function () {
if ($(this).text().trim() === "") {
$(this).append('<span class="sr-only">內頁活動公告標題</span>');
}
});
$(".show-title").each(function () {
if ($(this).text().trim() === "") {
$(this).append('<span class="sr-only">內頁活動公告標題</span>');
}
});
$(".w-annc__widget-title").each(function () {
if ($(this).text().trim() === "") {
$(this).append('<span class="sr-only">公告標題</span>');
}
});
$(".widget-title").each(function () {
if ($(this).text().trim() === "") {
$(this).append('<span class="sr-only">網路資源標題</span>');
}
});
$(".widget-title").each(function () {
if ($(this).text().trim() === "") {
$(this).append('<span class="sr-only">網路資源標題</span>');
}
});
$('input').each(function() {
var $this = $(this);
if (!$this.attr('title') || $this.attr('title').trim() === '') {
$this.attr('title', '網內搜尋');
}
});
$('.rucaptcha-image').each(function() {
var $button = $(this).next('button'); // 取得緊接在 .rucaptcha-image 之後的 button
if ($button.length && !$button.attr('aria-label')) {
$button.attr('aria-label', '播放驗證碼語音');
}
});
// img無障礙
$(function() {
/**
* 圖片無障礙 AA 級補強 (人工檢測優化版)
*/
function fixImageAccessibility() {
$('img').each(function() {
var $img = $(this);
var $parentA = $img.closest('a'); // 取得父層連結
var currentAlt = ($img.attr('alt') || '').trim();
var currentTitle = ($img.attr('title') || '').trim();
// 判定該連結是否「僅靠圖片傳達目的」(連結內無文字)
var isLinkImage = $parentA.length > 0 && $parentA.text().replace(/\u00a0/g, '').trim() === "";
// --- 1. 處理「裝飾性圖片」標註 ---
if (currentAlt === "announcement image" || currentAlt === "裝飾圖片" || currentTitle === "裝飾圖片" || currentAlt === "這是一張圖片" || currentTitle === "這是一張圖片") {
$img.attr('alt', '');
$img.removeAttr('title');
return;
}
// --- 2. 解決【alt 與 title 相同】的問題 ---
if (currentAlt !== '' && currentAlt === currentTitle) {
$img.removeAttr('title');
currentTitle = '';
}
// --- 3. 處理「缺失 alt」或「空的 alt」補強邏輯 ---
// 修改點若是具有連結用途的圖片alt 不可為空
if (currentAlt === '') {
let finalAlt = "";
// A. 優先嘗試從父層 (<a>) 的 title 抓取
var parentATitle = $parentA.attr('title');
// B. 嘗試抓取同區域內的標題文字
var nearbyTitle = $parentA.find('h1, h2, h3, h4, h5, h6').first().text().trim();
if (parentATitle && parentATitle.trim() !== '') {
// 移除 title 內的視窗提示字眼,只取純文字作為 alt
finalAlt = parentATitle.replace(/\(在本視窗開啟\)|\(在新視窗開啟\)/g, '').trim();
} else if (nearbyTitle !== '') {
finalAlt = nearbyTitle;
} else if (isLinkImage) {
// 如果是連結圖片且都抓不到文字,給予預設值「連結」避免檢測失敗
finalAlt = "連結";
}
$img.attr('alt', finalAlt);
// --- 4. 二次清理 ---
if (currentTitle !== '' && currentTitle === finalAlt) {
$img.removeAttr('title');
}
}
});
}
setTimeout(fixImageAccessibility, 500);
});
// 有連結目的之所有a標籤的無障礙處理
$(function() {
// Bootstrap 會把原始 title 搬到 data-bs-original-title先還原回來
$('a[data-bs-original-title]').each(function() {
var $a = $(this);
var originalTitle = $a.attr('data-bs-original-title');
if (originalTitle && originalTitle.trim() !== '') {
$a.attr('title', originalTitle);
}
});
/**
* 全站無障礙 AA 級補強 (整合 HM1240400C 與 HM1240401C 規範)
*/
function fixAccessibilityAll() {
// --- 0. 環境與語言偵測 ---
//1200ms 後執行(確保所有其他 function 執行完畢後才處理)
//Part 1修正語言選單按鈕
//Part 2掃描所有 <a>
//├─ 排除 navbar-brand、javascript: 連結
//├─ 空連結 → 隱藏
//├─ 文字是路徑/空 → 補隱藏 span
//├─ 圖片+文字共存 → 圖片 alt 清空
//├─ 無 title → 自動產出 title
//├─ 有 title 但與連結文字或圖片 alt 重複 → 只保留開窗提示
//├─ 有 title 出現空括號 () → 清除並補上正確開窗提示
//└─ 移除 aria-label
var urlParams = new URLSearchParams(window.location.search);
var isEditMode = urlParams.get('editmode') === 'on';
var pageLang = $('html').attr('lang') || 'zh-Hant';
var isEn = pageLang.toLowerCase().startsWith('en');
var i18n = {
langBtn: isEn ? 'Open language menu in this window' : '在本視窗開啟語言選單',
newWin: isEn ? 'Open in new window' : '在新視窗開啟',
selfWin: isEn ? 'Open in this window' : '在本視窗開啟',
link: isEn ? 'Link' : '連結',
openImg: isEn ? 'Open image' : '開啟圖片內容',
sort: isEn ? 'Sort' : '排序'
};
// --- Part 1: 語言選單修正 ---
var $langBtn = $('#languagebutton');
if ($langBtn.length > 0) {
$langBtn.attr('title', i18n.langBtn);
$langBtn.removeAttr('aria-label');
}
// --- Part 2: 全站連結與圖片邏輯處理 ---
$('a').each(function() {
var $a = $(this);
// 【條件 1排除特定 class】
if ($a.hasClass('navbar-brand')) {
return;
}
var href = ($a.attr('href') || '').toLowerCase();
if (!href || href.startsWith('javascript:')) return;
// --- 關鍵修正:先偵測是否有原始 title ---
var rawTitleAttr = $a.attr('title');
var hasOriginalTitle = (typeof rawTitleAttr !== 'undefined' && rawTitleAttr !== false && rawTitleAttr.trim() !== "");
// 清理 &nbsp; 與 空白
var linkText = $a.text().replace(/\u00a0/g, '').trim();
var $img = $a.find('img');
var $icons = $a.find('i, svg');
var currentTitle = ($a.attr('title') || '').trim();
// ✅ 在 D 區塊清空 alt 之前,先記錄圖片原始 alt
var imgAltOriginal = $img.length > 0 ? ($img.attr('alt') || '').trim() : '';
// --- 【修正 1隱藏空連結】 ---
if (!isEditMode && linkText === "" && $img.length === 0 && $icons.length === 0) {
$a.hide();
return;
}
// --- 【修正 2文字語意防禦】 ---
if ((linkText === "" || linkText.startsWith('/') || linkText.includes('?')) && $img.length === 0 && $icons.length === 0) {
var accessibleText = i18n.link;
if (href.includes('sort')) {
accessibleText = i18n.sort;
}
var $span = $a.find('span');
if ($span.length > 0) {
$span.text(accessibleText);
} else {
$a.append('<span>' + accessibleText + '</span>');
$span = $a.find('span').last();
}
$span.css({
'display': 'inline-block', 'position': 'absolute', 'width': '1px', 'height': '1px',
'padding': '0', 'margin': '-1px', 'overflow': 'hidden', 'clip': 'rect(0, 0, 0, 0)',
'white-space': 'nowrap', 'border': '0'
});
linkText = accessibleText;
}
// A. 視窗動作規範
var isNewWindow = ($a.attr('target') === '_blank');
var windowTask = isNewWindow ? i18n.newWin : i18n.selfWin;
// B. 偵測檔案類型
var fileExt = "";
var fileMatches = href.match(/\.(pdf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odp|zip|rar|jpg|png|csv)$/);
if (fileMatches) {
fileExt = fileMatches[1].toLowerCase();
}
// C. 智慧修正標題判斷
var hasBadSymbol = currentTitle.includes('()') ||
currentTitle.includes('Open in new window') ||
currentTitle.includes('/uploads/');
if (currentTitle.startsWith('/') || currentTitle.includes('?')) {
currentTitle = "";
}
// D. 處理【HM1240400C】圖片與文字毗鄰時替代文字只能有一份
if (($img.length > 0 || $icons.length > 0) && linkText !== "") {
if ($img.length > 0) {
$img.attr('alt', '');
}
var $hiddenSpans = $a.find('span').filter(function() {
return $(this).css('display') === 'none' || $(this).attr('style')?.includes('display: none');
});
if ($hiddenSpans.length > 0) {
$hiddenSpans.each(function() {
var $span = $(this);
if ($span.text().includes('/uploads/')) {
$span.text(i18n.openImg);
}
$span.css({
'display': 'inline-block',
'position': 'absolute',
'width': '1px',
'height': '1px',
'padding': '0',
'margin': '-1px',
'overflow': 'hidden',
'clip': 'rect(0, 0, 0, 0)',
'white-space': 'nowrap',
'border': '0'
});
});
}
}
// E. 重新計算標題 (關鍵邏輯:若 hasOriginalTitle 為真,則不進入此區塊)
if (!hasOriginalTitle) {
if (linkText === "" && $img.length > 0) {
var rawAlt = ($img.attr('alt') || '').trim();
var forbidden = ['這是一張圖片', '圖片', 'image', 'photo', '圖', ''];
var imgAlt = forbidden.some(function(txt) { return rawAlt.toLowerCase() === txt; })
? ($a.attr('aria-label') || i18n.link) : rawAlt;
var fileInfo = fileExt ? '[' + fileExt.toUpperCase() + '] ' : '';
$a.attr('title', (fileInfo + imgAlt + " " + windowTask).trim());
$img.attr('alt', imgAlt);
}
else if (linkText !== "") {
if (fileExt !== "" || hasBadSymbol || currentTitle === "" || currentTitle.includes('/uploads/')) {
if (fileExt !== "") {
$a.attr('title', linkText + " ." + fileExt + " " + windowTask);
} else {
$a.attr('title', windowTask);
}
}
}
}
// ✅ 符合 HM1240404Etitle 不應與連結文字或圖片 alt 重複
if (hasOriginalTitle && currentTitle !== "") {
var titleWithoutWindow = currentTitle
.replace('(在本視窗開啟)', '')
.replace('(在新視窗開啟)', '')
.replace('Open in this window', '')
.replace('Open in new window', '')
.replace('另開新視窗前往', '')
.replace('另開新視窗', '')
.trim();
// ✅ title 去掉開窗字串後,若與連結文字或圖片原始 alt 相同,則只保留開窗提示
if (
(titleWithoutWindow === linkText && linkText !== i18n.link) ||
(imgAltOriginal !== '' && titleWithoutWindow === imgAltOriginal)
) {
$a.attr('title', windowTask);
}
// ✅ 最終清理:若 title 出現空括號 () 則移除並補上正確開窗提示
var finalTitle = ($a.attr('title') || '').trim();
if (finalTitle.includes('()')) {
finalTitle = finalTitle.replace(/\(\)/g, '').trim();
$a.attr('title', finalTitle + ' ' + windowTask);
}
}
// F. 最終清理:移除冗餘 label避免螢幕閱讀器唸兩次
$a.removeAttr('aria-label');
});
// ✅ G. 補強特定連結(須在迴圈外,因為 javascript: 連結被迴圈跳過)
$('.btn-o a').each(function() {
var $a = $(this);
if (!$a.attr('target')) {
$a.attr('target', '_blank');
$a.attr('rel', 'noopener noreferrer');
}
$a.attr('title', isEn ? 'Share to X Open in new window' : '分享至 X 在新視窗開啟');
});
$('.print-button a').each(function() {
var $a = $(this);
if (!$a.attr('title') || $a.attr('title').trim().toLowerCase() === 'print') {
$a.attr('title', isEn ? 'Print this page' : '列印此頁');
}
});
$('a.i-archive__file-name').each(function () {
var $a = $(this);
var isNewWindow = ($a.attr('target') === '_blank');
$a.attr('title', isNewWindow ? i18n.newWin : i18n.selfWin);
});
}
// ✅ 延遲 800ms 確保所有其他 function 執行完畢後才處理
setTimeout(function() {
fixAccessibilityAll();
}, 800);
});
$(function() {
function smartFixIcons() {
var isEn = $('html').attr('lang') === 'en';
var labels = {
calendar : isEn ? 'Date: ' : '日期:',
user : isEn ? 'Author: ' : '發布者:',
tag : isEn ? 'Tag: ' : '標籤:',
clock : isEn ? 'Time: ' : '時間:',
location : isEn ? 'Location: ' : '地點:',
phone : isEn ? 'Phone: ' : '電話:',
envelope : isEn ? 'Email: ' : '信箱:',
folder : isEn ? 'Category: ' : '分類:',
eye : isEn ? 'Views: ' : '瀏覽次數:',
download : isEn ? 'Download: ' : '下載檔案:',
search : isEn ? 'Search' : '搜尋',
bars : isEn ? 'Menu' : '選單',
print : isEn ? 'Print this page' : '列印此頁',
share : isEn ? 'Share' : '分享至社群',
close : isEn ? 'Close window' : '關閉視窗',
closePopup : isEn ? 'Close announcement' : '關閉公告視窗',
closeGallery: isEn ? 'Close gallery' : '關閉相簿',
toggleDesc : isEn ? 'Show or hide image description' : '顯示或隱藏圖片說明',
themeSwitch : isEn ? 'Switch gallery theme': '切換相簿主題',
showOriginal: isEn ? 'Show original image' : '顯示原始圖片'
};
$('i').each(function() {
var $icon = $(this);
var $parent = $icon.parent();
// 1. 所有圖示先對螢幕閱讀器隱藏
$icon.attr('aria-hidden', 'true');
// 特判:.close-screen-btn 內的圖示,移除無關的 sr-only 並設正確 aria-label
if ($parent.hasClass('close-screen-btn')) {
$parent.find('.sr-only').remove();
$parent.attr('aria-label', labels.closePopup);
if ($icon.next('.sr-only').length === 0) {
$icon.after('<span class="sr-only">' + labels.closePopup + '</span>');
}
return;
}
// 特判:.gallery-close 內的圖示,移除錯誤的 sr-only 並補正確說明
if ($parent.closest('.gallery-close').length > 0) {
$parent.closest('.gallery-close').find('.sr-only').remove();
$parent.closest('.gallery-close').attr('aria-label', labels.closeGallery);
$parent.closest('.gallery-close').attr('role', 'button');
$parent.closest('.gallery-close').attr('tabindex', '0');
if ($icon.next('.sr-only').length === 0) {
$icon.after('<span class="sr-only">' + labels.closeGallery + '</span>');
}
return;
}
// 特判:.gallery-toggle-desc 補說明
if ($parent.closest('.gallery-toggle-desc').length > 0) {
var $toggleBtn = $parent.closest('.gallery-toggle-desc');
if (!$toggleBtn.attr('aria-label')) {
$toggleBtn.attr('aria-label', labels.toggleDesc);
$toggleBtn.attr('role', 'button');
$toggleBtn.attr('tabindex', '0');
}
if ($icon.next('.sr-only').length === 0) {
$icon.after('<span class="sr-only">' + labels.toggleDesc + '</span>');
}
return;
}
// 特判:.gallery-theme-switch 補說明
if ($parent.closest('.gallery-theme-switch').length > 0) {
var $themeBtn = $parent.closest('.gallery-theme-switch');
if (!$themeBtn.attr('aria-label')) {
$themeBtn.attr('aria-label', labels.themeSwitch);
$themeBtn.attr('role', 'button');
$themeBtn.attr('tabindex', '0');
}
if ($icon.next('.sr-only').length === 0) {
$icon.after('<span class="sr-only">' + labels.themeSwitch + '</span>');
}
return;
}
// 2. 已有 aria-label 或 sr-only 就不重複處理
if ($icon.attr('aria-label') || $icon.next('.sr-only').length > 0 || $parent.find('.sr-only').length > 0) {
return;
}
var cls = ($icon.attr('class') || '').toLowerCase();
var labelText = '';
// --- 策略 A常見資訊型圖示 ---
if (cls.includes('calendar')) labelText = labels.calendar;
else if (cls.includes('user') || cls.includes('male')) labelText = labels.user;
else if (cls.includes('tag')) labelText = labels.tag;
else if (cls.includes('clock') || cls.includes('time')) labelText = labels.clock;
else if (cls.includes('map-marker') || cls.includes('location')) labelText = labels.location;
else if (cls.includes('phone')) labelText = labels.phone;
else if (cls.includes('envelope') || cls.includes('mail')) labelText = labels.envelope;
else if (cls.includes('folder')) labelText = labels.folder;
else if (cls.includes('eye')) labelText = labels.eye;
else if (cls.includes('download')) labelText = labels.download;
// --- 策略 B功能性按鈕 ---
var $container = $icon.closest('a, button');
if ($container.length > 0 && $container.text().trim() === '') {
var btnTitle = $container.attr('title');
if (btnTitle) labelText = btnTitle;
else if (cls.includes('search')) labelText = labels.search;
else if (cls.includes('bars') || cls.includes('navicon')) labelText = labels.bars;
else if (cls.includes('print')) labelText = labels.print;
else if (cls.includes('share')) labelText = labels.share;
else if (cls.includes('close') || cls.includes('times')) labelText = labels.close;
else if (cls.includes('image') || cls.includes('photo')) labelText = labels.showOriginal;
}
// --- 3. 執行補強 ---
if (labelText !== '') {
$icon.after('<span class="sr-only">' + labelText + '</span>');
}
});
}
setTimeout(smartFixIcons, 500);
});
// 刪除banner-slide的空連結和空連結目標
for(var i=0;i<$('.w-ba-banner__slide a').length;i++){
if($('.w-ba-banner__slide a').eq(i).attr('href')=="")
$('.w-ba-banner__slide a').eq(i).removeAttr('href');
if($('.w-ba-banner__slide a').eq(i).attr('target') == "")
$('.w-ba-banner__slide a').eq(i).removeAttr('target');
};
// 幫無標題之iframe加上title
for(var i=0;i<$('iframe').length;i++)
if($('iframe').eq(i).attr('title')=="" || $('iframe').eq(i).attr('title')== undefined ){
if($('iframe').eq(i).attr('src').search('facebook') != -1 )
$('iframe').eq(i).attr('title','facebook');
else if($('iframe').eq(i).attr('src').search('google') != -1 )
$('iframe').eq(i).attr('title','google');
else if($('iframe').eq(i).attr('src').search('youtube') != -1 )
$('iframe').eq(i).attr('title','youtube');
else if($('iframe').eq(i).attr('src').search('twitframe') != -1 )
$('iframe').eq(i).attr('title','twitter');
else
$('iframe').eq(i).attr('title','unknown');
};
//button是空的就加上內容
$('button').each(function() {
var $this = $(this);
var titleText = $this.attr('title') || '';
// 檢查 button 是否是空的(沒有可見文字或子元素)
if ($this.text().trim() === '' && !$this.children().length && titleText) {
// 新增隱藏的 span內容為 title
$this.append('<span class="sr-only">' + titleText + '</span>');
}
});
// 刪除空的檔案室
var archievelen = $('dd a.i-archive-files-item').length;
for(i=archievelen-1;i>=0;i--)
if($('dd a.i-archive-files-item').eq(i).html().trim()=="")
$('dd a.i-archive-files-item').eq(i).parent('dd').remove();
// 刪除具有空連結欄位的橫列
for(var i = 0;i < $('*[data-list] tr td a').length ; i++)
if($('*[data-list] tr td a').eq(i).html().trim()=="")
$('*[data-list] tr td a').eq(i).parent('td').parent('tr').remove();
// tab按鍵選到menu,會顯示下層的menu(為了符合無障礙)
$('.nav-level-0>li>a').focus(function(e) {
e.stopPropagation();
$(this).parent().focus();
if ($(this).parent().find('.nav-level-1').hasClass('show')) {
// 已有 show不處理
} else {
$('.nav-level-1').removeClass('show');
$('.nav-level-0>li>.menu-drop').removeClass('opened'); // 先清除其他的 opened
$(this).parent().find('.nav-level-1').addClass('show');
$(this).parent().find('.menu-drop').addClass('opened'); // 加上 opened
}
});
$('.nav-level-0>li').on('focusout', function(e) {
var $li = $(this);
setTimeout(function() {
if ($li.find(':focus').length === 0) {
$li.find('.nav-level-1').removeClass('show');
$li.find('.menu-drop').removeClass('opened'); // 移除 opened
}
}, 50);
});
$('.nav-level-1>li>a').focus(function(e) {
e.stopPropagation();
if ($(this).parent().find('.nav-level-2').hasClass('show')) {
// 已有 show不處理
} else {
$('.nav-level-2').removeClass('show');
$('.nav-level-1>li>.menu-drop').removeClass('opened'); // 先清除其他的 opened
$(this).parent().find('.nav-level-2').addClass('show');
$(this).parent().find('.menu-drop').addClass('opened'); // 加上 opened
}
});
$('.nav-level-1>li').on('focusout', function(e) {
var $li = $(this);
setTimeout(function() {
if ($li.find(':focus').length === 0) {
$li.find('.nav-level-2').removeClass('show');
$li.find('.menu-drop').removeClass('opened'); // 移除 opened
}
}, 50);
});
$('.controlplay a[role="radio"]').on('click', function () {
// 取消所有的 aria-checked 並還原文字
$('.controlplay a[role="radio"]').attr('aria-checked', 'false');
$('.controlplay a[role="radio"] span').each(function () {
var text = $(this).text().replace('(已選取)', '');
$(this).text(text);
});
// 設定目前被點擊的按鈕為已選取
$(this).attr('aria-checked', 'true');
var selectedText = $(this).text().trim();
$(this).find('span').text(selectedText + '(已選取)');
});
$(function() {
/**
* jPlayer 控制項無障礙標籤補強
* 1. 修正重複且無意義的 title="按鈕"
* 2. 解決鍵盤焦點無法進入隱藏介面的問題
*/
function fixJPlayerAccessibility() {
var $playerContainer = $('#jp_container_video_file');
// --- A. 修正按鈕標題 (解決語義問題) ---
$playerContainer.find('button').each(function() {
var $btn = $(this);
var cls = $btn.attr('class') || '';
var newTitle = '';
// 根據 class 判斷功能
if (cls.includes('jp-video-play-icon')) newTitle = '播放影片';
else if (cls.includes('jp-play')) newTitle = '播放';
else if (cls.includes('jp-stop')) newTitle = '停止';
else if (cls.includes('jp-mute')) newTitle = '靜音';
else if (cls.includes('jp-volume-max')) newTitle = '最大音量';
else if (cls.includes('jp-repeat')) newTitle = '重複播放';
else if (cls.includes('jp-full-screen')) newTitle = '全螢幕';
if (newTitle !== '') {
// 修正 title 為具體語義
$btn.attr('title', newTitle);
// 同時補上 aria-label 確保螢幕閱讀器讀取
$btn.attr('aria-label', newTitle);
}
});
// --- B. 鍵盤焦點互動修正 (解決 GN1210101E) ---
// 當鍵盤 Tab 進入按鈕時,強制讓 UI 介面顯現,否則使用者看不到焦點在哪
$playerContainer.on('focusin', 'button', function() {
$playerContainer.removeClass('hide-ui');
});
// --- C. CSS 強制補強 (解決 display:none 無法獲取焦點問題) ---
// 這是必要的,因為 CSS 若設 display:none鍵盤永遠進不去
$("<style>")
.prop("type", "text/css")
.html(`
.jp-video.hide-ui .jp-gui {
display: block !important;
opacity: 0;
transition: opacity 0.2s;
}
/* 當按鈕獲得焦點,或是滑鼠移入,強制顯示介面 */
.jp-video.hide-ui:focus-within .jp-gui,
.jp-video.hide-ui:hover .jp-gui {
opacity: 1;
}
/* 增加明顯的焦點框,讓鍵盤使用者知道現在在哪 */
.jp-video button:focus {
outline: 3px solid #005aff !important;
outline-offset: 2px;
}
`)
.appendTo("head");
}
// 執行補強(設定延遲確保 jPlayer 已生成 DOM
setTimeout(fixJPlayerAccessibility, 500);
});
// 移除 .navbar-brand 內部 display:none 元素的補強
function removeHiddenElementsInsideBrand() {
// 選取 .navbar-brand 內部所有隱藏的元素
$('.navbar-brand *').filter(function() {
// 同時判定 inline style 與 CSS class 造成的 display: none
return $(this).css('display') === 'none';
}).remove(); // 徹底從 DOM 中移除該標籤,避免無障礙檢測工具誤判
}
// 使用 setTimeout 確保內容渲染後執行
// 建議設定 500~800 毫秒,避開大部分動態載入的時間差
setTimeout(function() {
removeHiddenElementsInsideBrand();
}, 600);
//修正 Alt+M 定位點位置
$(function() {
var $accessKeyM = $('#accesskey_menu');
var $navbarHeader = $('.navbar-brand');
var $modulesMenu = $('.modules-menu');
function fixAccessKeyM() {
var windowWidth = $(window).width();
if (windowWidth > 769) {
// 大螢幕:移到 .navbar-brand 前面
if ($navbarHeader.length > 0) {
$accessKeyM.insertBefore($navbarHeader);
$accessKeyM.css({
'display' : 'inline-block',
'position' : 'relative',
'float' : 'left',
});
}
} else {
// 小螢幕:移回 .modules-menu 第一個位置
if ($modulesMenu.length > 0) {
$accessKeyM.prependTo($modulesMenu);
$accessKeyM.css({
'display' : '',
'position' : '',
'float' : '',
'left' : '',
});
}
}
}
// 初始執行
setTimeout(fixAccessKeyM, 500);
// resize 監聽,加 debounce 避免頻繁觸發
var resizeTimer;
$(window).on('resize', function() {
clearTimeout(resizeTimer);
resizeTimer = setTimeout(fixAccessKeyM, 150);
});
});
//導覽選單子選單無障礙狀態修正 (支援多層級)
function fixNavMenuA11y() {
const $navItems = $('#main-nav li');
$navItems.each(function() {
const $li = $(this);
const $toggle = $li.children('a');
const $subMenu = $li.children('ul');
// 判斷是否有子選單
if ($subMenu.length > 0) {
// 1. 初始化屬性
// aria-haspopup="true" 表示有點擊後彈出選單的功能
// aria-expanded="false" 預設為摺疊
$toggle.attr({
'aria-haspopup': 'true',
'aria-expanded': 'false'
});
// 如果 href 是 javascript:void(0);,建議補上 role="button" 讓語音讀出它是按鈕
if ($toggle.attr('href').indexOf('javascript') !== -1) {
$toggle.attr('role', 'button');
}
// 2. 焦點移入事件 (Focus)
$toggle.on('focus', function() {
// 這裡假設你的選單是用 CSS 或其他 JS 控制顯示,
// 當焦點進入時,將狀態改為 true
$(this).attr('aria-expanded', 'true');
// 如果需要透過 JS 強制顯示選單可在此加上:$subMenu.addClass('show'); (視你的 CSS 而定)
});
// 3. 處理失焦事件 (Focusout)
// 使用 focusout 並檢查焦點是否移出了整個 li 區塊
$li.on('focusout', function(e) {
// 使用 setTimeout 確保能抓到下一個獲焦元素
setTimeout(function() {
if (!$li.is(':focus-within')) {
$toggle.attr('aria-expanded', 'false');
// 如果有 class 控制顯示:$subMenu.removeClass('show');
}
}, 50);
});
}
});
}
// 執行修正
fixNavMenuA11y();
//修正無超連結目的之連結
$(function() {
/**
* 針對所有 href="#" 的連結改為 javascript:void(0);
* 避免使用者點擊後頁面跳回頂端,造成操作困擾
*/
function fixEmptyHref() {
$('a[href="#"]').each(function() {
// 將 href 修改為不觸發跳轉的 void 腳本
$(this).attr('href', 'javascript:void(0);');
$(this).attr('role', 'button');
});
}
// 延遲執行,確保動態產生的選單也能被補強
setTimeout(fixEmptyHref, 500);
});
//公告頁籤無障礙
$(function() {
function fixTabLinearOrder() {
var $targetAnnc = $('.w-annc').filter(function() {
return $(this).find('.tab_nav').length > 0;
});
if ($targetAnnc.length === 0) return;
var $tabs = $targetAnnc.find('.filter_tab');
var $anncList = $targetAnnc.find('.w-annc__list');
// 智慧判斷:偵測 filter_tab 用哪個屬性來分類
// 優先用 data-tags若有值否則用 data-category
function getTabKey($tab) {
var tags = $tab.data('tags');
if (tags && tags !== '') return { attr: 'data-tags', value: tags };
var category = $tab.data('category');
if (category && category !== '') return { attr: 'data-category', value: category };
return null;
}
// 根據 key 找對應的可見 w-annc__item
function getVisibleItems($scope, key) {
if (!key) return $();
return $scope.find('.w-annc__item[' + key.attr + '="' + key.value + '"]:visible');
}
// 根據 w-annc__item 反查對應的 filter_tab
function getTabFromItem($item, $scope) {
var tags = $item.data('tags');
if (tags && tags !== '') {
var $tab = $scope.find('.filter_tab[data-tags="' + tags + '"]');
if ($tab.length) return $tab;
}
var category = $item.data('category');
if (category && category !== '') {
var $tab = $scope.find('.filter_tab[data-category="' + category + '"]');
if ($tab.length) return $tab;
}
return $();
}
$tabs.on('keydown', function(e) {
var $scope = $(this).closest('.w-annc');
var key = getTabKey($(this));
// 順向 Tab頁籤 -> 對應內容第一個連結
if (e.which === 9 && !e.shiftKey) {
var $visibleItems = getVisibleItems($scope, key);
if ($visibleItems.length > 0) {
var $firstLink = $visibleItems.find('a').first();
if ($firstLink.length > 0) {
e.preventDefault();
$firstLink.focus();
}
}
}
// 反向 Shift+Tab頁籤 -> 上一個頁籤的內容最後一個連結
if (e.which === 9 && e.shiftKey) {
var $prevTab = $(this).prev('.filter_tab');
if ($prevTab.length > 0) {
var prevKey = getTabKey($prevTab);
$prevTab.click();
var $prevItems = getVisibleItems($scope, prevKey);
var $lastLink = $prevItems.find('a').last();
if ($lastLink.length > 0) {
e.preventDefault();
$lastLink.focus();
}
}
}
// Enter / Space切換頁籤並移焦點到內容第一個連結
if (e.which === 13 || e.which === 32) {
e.preventDefault();
$(this).click();
var $visibleItems = getVisibleItems($scope, key);
var $firstLink = $visibleItems.find('a').first();
if ($firstLink.length > 0) {
setTimeout(function() { $firstLink.focus(); }, 50);
}
}
});
// 反向遊走:內容 -> 對應標籤Tab 到最後一個連結跳下一個頁籤
$anncList.on('keydown', '.w-annc__item a', function(e) {
var $currentLink = $(this);
var $currentItem = $currentLink.closest('.w-annc__item');
var $scope = $currentLink.closest('.w-annc');
// 找出當前 item 對應的 filter_tab
var $currentTab = getTabFromItem($currentItem, $scope);
if (!$currentTab.length) return;
// 找出同類別的所有可見 item
var key = getTabKey($currentTab);
var $visibleItems = getVisibleItems($scope, key);
// Shift+Tab若是第一個連結跳回對應頁籤
if (e.which === 9 && e.shiftKey) {
if ($currentLink.is($visibleItems.find('a').first())) {
e.preventDefault();
$currentTab.focus();
}
}
// Tab若是最後一個連結跳到下一個頁籤並切換
if (e.which === 9 && !e.shiftKey) {
if ($currentLink.is($visibleItems.find('a').last())) {
var $nextTab = $currentTab.next('.filter_tab');
if ($nextTab.length > 0) {
e.preventDefault();
$nextTab.focus();
$nextTab.click();
}
}
}
});
}
setTimeout(fixTabLinearOrder, 500);
});
//頁籤無障礙
$(function () {
function fixTabAccessibility() {
// 各自獨立處理每組 .tab_nav避免多組時跨區塊操作問題
$('.tab_nav').each(function() {
var $tabNav = $(this);
var $tabs = $tabNav.find('li');
// --- 1. 初始化結構語意 ---
$tabNav.attr('role', 'tablist');
$tabs.each(function () {
var $this = $(this);
var isActive = $this.hasClass('active');
$this.attr({
'role': 'tab',
'aria-selected': isActive ? 'true' : 'false',
'tabindex': isActive ? '0' : '-1'
});
var tabName = $this.text().trim();
$this.attr('title', '切換至 ' + tabName);
});
// --- 2. 點擊事件:更新 aria-selected 與 tabindex ---
$tabs.on('click', function () {
var $clickedTab = $(this);
$tabs.attr('aria-selected', 'false').attr('tabindex', '-1');
$clickedTab.attr('aria-selected', 'true').attr('tabindex', '0');
});
// --- 3. 鍵盤操作補強 ---
$tabs.on('keydown', function (e) {
var $current = $(this);
var currentIndex = $tabs.index($current);
var lastIndex = $tabs.length - 1;
var $target = null;
switch (e.which) {
case 13: // Enter
case 32: // Space
e.preventDefault();
$current.trigger('click');
break;
case 37: // ← 左方向鍵:移到前一個頁籤
case 38: // ↑ 上方向鍵
e.preventDefault();
$target = currentIndex > 0
? $tabs.eq(currentIndex - 1)
: $tabs.eq(lastIndex);
break;
case 39: // → 右方向鍵:移到下一個頁籤
case 40: // ↓ 下方向鍵
e.preventDefault();
$target = currentIndex < lastIndex
? $tabs.eq(currentIndex + 1)
: $tabs.eq(0);
break;
case 36: // Home跳到第一個頁籤
e.preventDefault();
$target = $tabs.eq(0);
break;
case 35: // End跳到最後一個頁籤
e.preventDefault();
$target = $tabs.eq(lastIndex);
break;
}
// 移動焦點並觸發點擊切換
if ($target && $target.length) {
$tabs.attr('tabindex', '-1');
$target.attr('tabindex', '0').focus().trigger('click');
}
});
});
}
setTimeout(fixTabAccessibility, 500);
});
//移除 accesskey="W" 之後的 | 符號
$(function() {
function removeSeparatorAfterAccesskeyW() {
$('a[accesskey="W"]').each(function() {
// 取得 a 標籤相鄰的下一個 DOM 節點
var nextNode = this.nextSibling;
// 檢查節點是否存在、是否為文字節點 (nodeType 3),且是否包含 '|'
if (nextNode && nextNode.nodeType === 3) {
var textValue = nextNode.nodeValue;
if (textValue.includes('|')) {
// 將 '|' 替換為空字串並更新節點值
nextNode.nodeValue = textValue.replace('|', '');
}
}
});
}
// 執行處理
removeSeparatorAfterAccesskeyW();
});
if ($('#language-li').is(':empty') || $('#language-li').html().trim() === '') {
$('#language-li').remove();
};
$('.header-nav').each(function() {
const cleaned = $(this).text().replace(/[\s|]/g, '');
if (cleaned === '') {
$(this).remove();
}
});
}
forFreeGo();
//header banner setting
if ( location.href.search('editmode=on') != -1 ) {
$('.header-banner').css('z-index','2');
} else {
$('.header-banner').css({
'position': 'relative',
'top': '0',
'z-index': '-2',
});
};
// //公告頁籤
// function annc_widget_nav() {
// $('.tab_nav').nextAll().addClass('tab_content');
// $('.tab_content').css("display","none");
// $('.tab_content').eq(0).css('display', 'block');
// var num = $('.tab_nav li').length;
// $('.tab_content').eq(num).css('display', 'block');
// $('.tab_content').eq(num).nextAll().css('display', 'block');
// $('.tab_nav li').off('click').on('click',function() {
// $('.tab_nav li').removeClass('active');
// $(this).addClass('active');
// var fa = $(this).index();
// $('.tab_content').attr('style','');
// $('.tab_content').css("display","none");
// $('.tab_content').eq(fa).css('display','block');
// var num = $('.tab_nav li').length;
// $('.tab_content').eq(num).css('display', 'block');
// $('.tab_content').eq(num).nextAll().css('display', 'block');
// });
// var url = window.location.search;
// if (url == "?editmode=on") {
// $('.tab_content').css({'position': 'relative','display':'block'});
// }
// }
// annc_widget_nav();
//切換語言停留在同一頁
if(window.location.pathname!="/")
$("#en").attr("href",window.location.pathname.replace("zh_tw","en"))
//檔案室 下載檔案 hover 彈出備註訊息
$('[data-toggle="tooltip"]').tooltip()
//下載檔案格式dot pdf分色
$(".i-archive .label.label-primary").each(function() {
var downloadType = $(this).text();
$(this).addClass(downloadType);
})
//檔案室模組 Widget 手風琴
function extendPanelWidget() {
var len = $('.panel-title').length;
var i = -1;
if (len > 0) {
// 新增數字到要對應的panel按鈕id及href上面
for (i = 0; i < len; i++) {
$('.panel-title:eq(' + i + ') .collapsed').attr('href', '#collapse' + i);
$('.panel-collapse:eq(' + i + ')').attr('id', 'collapse' + i);
}
}
}
extendPanelWidget();
// member show tab scroll
$('.nav-pills').scrollingTabs({
scrollToTabEdge: true,
enableSwiping: true,
leftArrowContent: [
'<div class="scrtabs-tab-scroll-arrow custom-scroll-arrow"><i class="fa fa-caret-left" aria-hidden="true"></i>',
'</div>'
].join(''),
rightArrowContent: [
'<div class="scrtabs-tab-scroll-arrow custom-scroll-arrow"><i class="fa fa-caret-right" aria-hidden="true"></i>',
'</div>'
].join('')
});
}
$(document).ready(function () {
// 處理所有 .fnav-item 裡的 <a>
$(".fnav-item a").each(function () {
const $a = $(this);
// 如果內部已經有 .sr-only就略過
if ($a.find(".sr-only").length > 0) return;
// 嘗試從 title 擷取語意文字
let label = $a.attr("title") || "";
// 如果還是空字串,再嘗試用 i 的 title
if (!label.trim()) {
const iconTitle = $a.find("i").attr("title");
if (iconTitle) label = iconTitle;
}
// 如果真的都沒有語意,預設一個 generic label也可加入 warning log
if (!label.trim()) {
label = "操作按鈕";
}
// 加上 title 和 aria-label
$a.attr("title", label).attr("aria-label", label);
// 加上 sr-only 輔助文字
$a.append(`<span class="sr-only">${label}</span>`);
// 確保 icon 不被閱讀器讀取
$a.find("i").attr("aria-hidden", "true");
$a.find(".icon").attr("aria-hidden", "true");
});
});
//video js
$(document).ready(function () {
if ($(".main-content .video_detail").length > 0) {
$('.videopagenone').css("display","none");
$('.videopage').css('display', 'block');
$('.sitemenu').css("display","none");
$('span img[alt="HD"]').parent().hide();
$('span img[alt="觀看人數"]').remove();
$(".video_detail .view_info span").each(function () {
var text = $(this).text().trim(); // 取得 <span> 裡的文字,去掉前後空格
var number = text.replace(/\D/g, ""); // 只保留數字部分
if (number) {
$(this).text(`・觀看次數:${number}`); // 更新內容格式
}
});
$(".movie_desc").before('<div class="movietitle"><h4>影片內容</h4></div>');
$(".movie_desc").each(function () {
var decodedHtml = $("<div/>").html($(this).text()).html(); // 轉換轉義的 HTML
$(this).html(decodedHtml); // 設置為真正的 HTML
});
$(".video_group_time").each(function () {
var $this = $(this);
// 找到對應的 <q>,並移動到 .video_group_time 內部
var $q = $this.closest(".imglst_desc").find(".movie_desc q");
if ($q.length) {
$this.append($q.clone()); // 將 <q> 複製並添加到 .video_group_time
$q.remove(); // 移除 .movie_desc 裡的 <q>
}
// 移動 .view_info 到 .video_group_time 的內部
$this.append($this.siblings(".view_info"));
// 取得內容並移除 "SystemAdmin | " 前綴
var text = $this.text().trim();
var newText = text.replace(/^.*\|\s*/, ""); // 移除 "SystemAdmin | "
$this.text(newText); // 更新內容
$(this).insertBefore($(this).closest(".imglst_desc").siblings("h3"));
});
$(".main-content").css({
"max-width": "920px",
"margin": "auto"
});
$(".video_box_wrap").css("padding-bottom", "56%");
$(".video_detail .video_yt_box").insertBefore(".video_detail .video_group_time");
};
function getYouTubeThumbnail() {
var $ytThumb = $(".ytp-cued-thumbnail-overlay-image");
if ($ytThumb.length) {
var imageUrl = $ytThumb.css("background-image");
// 檢查背景圖格式url("https://...")
var urlMatch = imageUrl.match(/url\(["']?(.*?)["']?\)/);
var extractedUrl = urlMatch ? urlMatch[1] : null;
if (extractedUrl) {
// console.log("成功獲取縮圖:", extractedUrl);
$(".background").css("background-image", `url("${extractedUrl}")`);
} else {
// console.log("背景圖格式不對,改用影片 ID 生成縮圖");
setThumbnailFromVideoId();
}
} else {
// console.log("找不到 .ytp-cued-thumbnail-overlay-image改用影片 ID 生成縮圖");
setThumbnailFromVideoId();
}
}
function setThumbnailFromVideoId() {
var $iframe = $("iframe[src*='youtube.com/embed']");
if ($iframe.length) {
var src = $iframe.attr("src");
var videoIdMatch = src.match(/youtube\.com\/embed\/([^?]+)/);
var videoId = videoIdMatch ? videoIdMatch[1] : null;
if (videoId) {
var fallbackImageUrl = `https://img.youtube.com/vi/${videoId}/maxresdefault.jpg`;
// console.log("透過影片 ID 取得縮圖:", fallbackImageUrl);
$(".background").css("background-image", `url("${fallbackImageUrl}")`);
}
}
}
// 嘗試多次加載
var interval = setInterval(function () {
if ($(".ytp-cued-thumbnail-overlay-image").length || $("iframe[src*='youtube.com/embed']").length) {
getYouTubeThumbnail();
clearInterval(interval);
}
}, 1000);
//改變日期格式
$(".video_group_time").each(function () {
var $this = $(this);
var originalText = $this.text().trim();
// 把 YYYY-MM-DD 轉換成 M月D日
var formattedText = originalText.replace(/(\d{4})-(\d{2})-(\d{2})/g, function (match, year, month, day) {
return parseInt(month, 10) + "月" + parseInt(day, 10) + "日";
});
// 找到對應的 <q>,並複製
var $q = $this.closest(".video_data").find(".video_desc q").clone();
// 更新內容並加上 <q>
$this.html(formattedText).append($q);
});
});
//rucaptcha-image
$(document).ready(function () {
$('.rucaptcha-image').removeAttr('onload');
// 檢查是否已插入過
if (!$('#captcha_audio').length) {
const audioButton = $(`
<button
title="播放驗證碼語音"
type="button"
onclick="document.getElementById('captcha_audio').play();"
class="fas fa-volume-up"
aria-label="播放驗證碼語音"
role="button"
style="font-size: 1.5em; color: #333; cursor: pointer; border: 2px solid #333; padding: 0.2em;">
<span class="sr-only">播放驗證碼語音</span>
</button>
`);
const audio = $('<audio id="captcha_audio" src="/rucaptcha/?format=wav&amp;locale=zh_tw"></audio>');
$('.rucaptcha-image').after(audioButton, audio);
}
});
//萬用表格searchbtn2
$(document).ready(function () {
$('.searchbtn2').click(function (event) {
event.preventDefault(); // 防止預設行為
$(".searchbox").slideToggle(300, function () {
updateAriaExpanded();
});
$(this).closest('.ken-click').toggleClass('ken-click2');
});
let triggeredByFocus = false;
function updateAriaExpanded() {
const isVisible = $(".searchbox").is(":visible");
$(".searchbtn2").attr("aria-expanded", isVisible ? "true" : "false");
}
// 預設 aria-expanded 為 false
$(".searchbtn2").attr("aria-expanded", "false");
});
//強制保持全站search展開
$(document).ready(function () {
//search移位
function moveSearchIfWide() {
if ($('.input-search').is(':focus')) return;
if ($(window).width() > 769) {
// 如果已經在正確位置就不動
if (!$('.modules-menu-level-0 .searchclass').length) {
$('.searchclass').appendTo('.header-nav');
}
} else {
if (!$('.navbar-header .searchclass').length) {
$('.navbar-brand').after($('.searchclass'));
}
}
}
$(document).ready(moveSearchIfWide);
$(window).on('resize', moveSearchIfWide);
const $searchBox = $('.search-box');
const $input = $searchBox.find('.input-search');
const $btn = $('.btn-search');
// 點擊 btn 時:若未展開則展開,展開後才可送出
$btn.on('click', function (e) {
if (!$searchBox.hasClass('searching')) {
e.preventDefault(); // 第一次點擊不送出
// 延遲讓 Android 不會立即 blur
setTimeout(() => {
$searchBox.addClass('searching');
$input[0].focus(); // 用 DOM 方式較穩
}, 100);
} else if (!$input.val().trim()) {
// 沒有輸入值 → 不送出focus 回去
e.preventDefault();
$input[0].focus();
}
// 有輸入值就正常送出
});
// 點外面收起(無字才收)
$(document).on('click touchstart', function (e) {
if (
!$searchBox.is(e.target) &&
$searchBox.has(e.target).length === 0 &&
!$input.val().trim()
) {
$searchBox.removeClass('searching');
}
});
// focus 時延遲加 .searching避免 Android 被打斷
$input.on('focus', function () {
setTimeout(() => {
$searchBox.addClass('searching');
}, 50);
});
// blur 時延遲移除 .searching避免太早發生
$input.on('blur', function () {
setTimeout(() => {
if (!$input.val().trim()) {
$searchBox.removeClass('searching');
}
}, 150);
});
});
// 當文件物件模型(DOM)載入後執行init函數
$(document).ready(function() {
//常用到的js
// $('.').after($('.'));
// $('.').before($('.'));
// $('.').append($('.'));
// if($('.show-announcement').hasClass('show-announcement')) {
// $('.').css('', '');
// }
$(function() {
var $headerNav = $('.header-nav');
$headerNav.contents().each(function() {
if (this.nodeType === 3 && this.nodeValue.trim() === '|') {
$(this).remove();
}
});
});
if($('.s-annc').length){
$(".carousel_images h4").remove();
$('.carousel_images').addClass('carousel_images2');
$(".carousel_images .w-ba-banner").next("div").find(".button-mid").remove();
$(".s-annc__post-wrap").next("hr").remove();
// $(".carousel_images").insertAfter(".s-annc__meta-wrap");
$('.breadcrumb-wrap').css('display', 'block');
// $(".main-content").css({
// "max-width": "920px",
// "margin": "auto"
// });
}
$('.s-annc__tag-wrap ').after($('.s-annc__post-orbithashtags'));
$('.i-member-pic-wrap a').removeAttr('target');
function markCheckStatusButton() {
$('.ask-question').each(function () {
var $prev = $(this).prev(); // 取得前一個元素
// 如果前一個元素是 <a> 且 class 包含 "btn"
if ($prev.is('a') && $prev.hasClass('btn')) {
$prev.addClass('CheckStatus'); // 加上 class
}
});
};
markCheckStatusButton();
// 綁定滑動事件
$(".cycle-slideshow").swipe({
swipeLeft: function () {
$(this).cycle("next");
},
swipeRight: function () {
$(this).cycle("prev");
},
threshold: 50, // 滑動靈敏度(數值越小越敏感)
});
$('#check_history_form input[type="submit"][value="Check History"]').addClass('CheckHistory');
$(".mybooking").append('<i class="fa-solid fa-circle-user"></i>');
//內頁dattpp移位
$('.i-annc__page-title').after($('.sitemenu-wrap2'));
$('.i-archive-title').after($('.sitemenu-wrap2'));
$('.page-module-title').after($('.sitemenu-wrap2'));
$('.box-social-share').before($('.sitemenu-wrap3'));
$('.box-social-share').before($('.sitemenu-wrap3'));
$('.box-social-share').before($('.sitemenu-wrap3'));
// $(".member-data2-tr").before($(".show-member .table-striped > tbody > tr:nth-of-type(4)"));
// $(".nav-pills").before($(".show-member .table-striped > tbody > tr:last-child"));
//檔案室手風琴
$('.panel-title>.collapsed').click(function(){
$(this).find('.fa').toggleClass("fa-chevron-down");
$(this).find('.fa').toggleClass("fa-chevron-up");
});
//背景widget設定
if ( location.href.search('editmode=on') != -1 ) {
$('.background').css('z-index','2');
$('.background').css('position','relative');
} else {
$('.background').css('z-index','-1');
$('.background').css('position','fixed');
};
//公告類別顏色
// $(".w-annc .w-annc__category-wrap").each(function() {
// var SaveCategory = $(this).find(".w-annc__category").text();
// $(this).addClass(SaveCategory);
// })
// $(".w-annc__item ").each(function() {
// var SaveCategory2 = $(this).find(".w-annc__category").text();
// $(this).addClass(SaveCategory2);
// })
$(".i-annc__item .i-annc__category-wrap").each(function() {
var SaveCategory = $(this).find(".i-annc__category").text();
$(this).addClass(SaveCategory);
})
$(".i-annc__item ").each(function() {
var SaveCategory2 = $(this).find(".i-annc__category").text();
$(this).addClass(SaveCategory2);
})
//預約
if ($(window).width() > 821) {
$('.form-horizontal').append($('.cancelbooking'));
$(".hire-ken-click").click(function(){
// $(".searchbox").slideToggle(300);
$('.form-horizontal').toggleClass('hire-ken-click2');
$('.col-lg-5').toggleClass('shadowblock');
$(".cancelbooking").click(function(){
$('.form-horizontal').removeClass('hire-ken-click2');
$('.col-lg-5').removeClass('shadowblock');
});
});
}
//navrwd移到選單
if ($(window).width() <769) {
$('.navbar-brand').after($('.header-nav'));
}else{
$('.navbar-header').after($('.header-nav'));
};
$('.sitemenu-vertical .sitemenu-dropdown-toggle').click(function(){
$('.sitemenu-vertical .dropdown-menu').slideToggle();
$(".sitemenu-vertical .sitemenu-dropdown-toggle").toggleClass("fa-caret-down");
$(".sitemenu-vertical .sitemenu-dropdown-toggle").toggleClass("fa-caret-up");
});
//頁尾選單開合
$('.btn-fatfooter').click(function(){
$('.fatfooter').slideToggle();
$(".btn-fatfooter .fa-chevron-down").toggleClass("rotate");
});
$(".menu-toggle").on('click', function() {
$(this).toggleClass("on");
$('.menu-section').toggleClass("on");
$("nav ul").toggleClass('hidden');
});
$('.morebken').click(function(){
$('.list-unstyled>li:nth-child(n+5)').slideToggle();
$(".morebken .fa-chevron-down").toggleClass("rotate");
$(".openmorebken").toggleClass("closemorebken");
});
//RWD 自動縮放headerbannner
function headerH() {
if ($(window).width() < 769) {
const navH = $('.layout-header .navbar-header').outerHeight();
$('.header-banner').css('height', navH );
}
}
headerH();
//downIcon
$(".downIcon").click(function () {
var move_to_target = function (stop) {
var theTop;
if (stop) {
// $(".kenjohn").addClass('navFixed');
if ($('.layout-content2.topcontent').length != 0 && $('.layout-content2.topcontent').offset().top < 400) {
$('.layout-content2').css('margin-top', $('.kenjohn').height() - $('#orbit-bar').height());
}
if (parseInt($('.layout-content2').css('margin-top') == 0)) {
theTop = $('.layout-content2.topcontent').offset().top - $(".kenjohn").position().top - 95;
} else {
theTop = $('.layout-content2.topcontent').offset().top - $(".kenjohn").position().top - $(".kenjohn").height() - 95;
}
} else {
theTop = 5;
}
// console.log(theTop);
$("html, body").animate({
scrollTop: theTop
}, {
duration: 400, easing: "swing", complete: function () {
// console.log('finish');
if (!stop) {
move_to_target(true);
}
}
});
}
move_to_target(false);
return false;
});
$(window).resize(function() {
if ($(window).width() <769) {
$('.navbar-brand').after($('.header-nav'));
}else{
$('.navbar-header').after($('.header-nav'));
};
if ($(window).width() > 821) {
$('.form-horizontal').append($('.cancelbooking'));
$(".hire-ken-click").click(function(){
// $(".searchbox").slideToggle(300);
$('.form-horizontal').toggleClass('hire-ken-click2');
$('.col-lg-5').toggleClass('shadowblock');
$(".cancelbooking").click(function(){
$('.form-horizontal').removeClass('hire-ken-click2');
$('.col-lg-5').removeClass('shadowblock');
});
});
}
headerH();
})
$(window).scroll(function() {
initdata1();
});
// $(window).scroll(function() {
// if ($(this).scrollTop() > 100) { /* 要滑動到選單的距離 */
// $('.outdropdowns').addClass('navFixed'); /* 幫選單加上固定效果 */
// } else {
// $('.outdropdowns').removeClass('navFixed'); /* 移除選單固定效果 */
// }
// });
// $('.navbar-brand h2').replaceWith(function() {
// return $("<h1>", {
// class: this.className,
// html: $(this).html()
// });
// });
$('#search'). attr('title', '另開新視窗');
$(window).scroll(function () {
var windowTop = $(window).scrollTop();
var windowBottom = windowTop + $(window).innerHeight();
function handleAnimationOnce(selector, animationClass, offsetRatio = 0.5) {
$(selector).each(function () {
var elementTop = $(this).offset().top;
var elementHeight = $(this).height();
var triggerPoint = elementTop + elementHeight * offsetRatio;
if (
triggerPoint >= windowTop &&
triggerPoint <= windowBottom &&
!$(this).hasClass(animationClass)
) {
$(this).addClass(animationClass);
}
});
}
handleAnimationOnce('.hide0', 'animationvisible', 0.1);
handleAnimationOnce('.hide1', 'animationvisible1', 0.5);
handleAnimationOnce('.hide2', 'animationvisible2', 0.5);
handleAnimationOnce('.hide3', 'animationvisible3', 0.5);
handleAnimationOnce('.rotate0', 'animationrotate0', 0.5);
handleAnimationOnce('.zoomin', 'animationvisible5', 0.5);
});
init();
});
// 1. OrbitBar 基礎與搜尋選單邏輯
$(document).ready(function() {
const isEn = document.documentElement.lang === 'en';
const $orbitLabel = $('label[for="open-orbit-nav"]');
const $searchArea = $('.orbit-bar-search-sign-language');
const $firstInput = $('#q'); // 搜尋框通常是選單內第一個獲焦元素
// 初始化屬性
if (isEn) {
$orbitLabel.attr({ title: 'Site search and language menu', 'aria-label': 'Site search and language menu' });
} else {
$orbitLabel.attr({ title: '全站搜尋及語言切換選單', 'aria-label': '全站搜尋及語言切換選單' });
}
$orbitLabel.attr({ 'role': 'button', 'aria-haspopup': 'true', 'aria-expanded': 'false', 'tabindex': '0' });
// --- 【修正重點 1】處理 Label 的焦點與按鍵行為 ---
$orbitLabel.on('focusin', function(e) {
var relatedTarget = e.relatedTarget;
// 如果是從選單內部退回來的 (Shift+Tab)
if (relatedTarget && ($searchArea.find(relatedTarget).length > 0)) {
$searchArea.removeClass('show');
$(this).attr('aria-expanded', 'false');
} else {
// 正向進入
$searchArea.addClass('show');
$(this).attr('aria-expanded', 'true');
}
});
// 強制偵測:在 Label 上按下 Shift+Tab 代表要離開這整塊,立即收合
$orbitLabel.on('keydown', function(e) {
if (e.shiftKey && e.keyCode === 9) { // Shift + Tab
$searchArea.removeClass('show');
$searchArea.find('ul').removeClass('show');
$(this).attr('aria-expanded', 'false');
}
});
// --- 【修正重點 2】處理選單內第一個元素的 Shift+Tab ---
$firstInput.on('keydown', function(e) {
if (e.shiftKey && e.keyCode === 9) { // 在第一個輸入框按 Shift + Tab
// 讓它自然回到 LabelLabel 的 focusin 會接手處理收合
// 這裡不做額外動作,交給上面的 focusin 邏輯
}
});
// --- 【修正重點 3】處理離開大區塊往後 Tab的狀態清除 ---
$searchArea.on('focusout', function() {
var $thisArea = $(this);
setTimeout(function() {
if (!$thisArea.is(':focus-within') && !$(document.activeElement).is($orbitLabel)) {
$thisArea.removeClass('show');
$thisArea.find('ul').removeClass('show');
$orbitLabel.attr('aria-expanded', 'false');
$('#languagebutton').attr('aria-expanded', 'false');
}
}, 150);
});
// 點擊行為
$orbitLabel.on('click', function() {
var isOpen = $searchArea.hasClass('show');
$searchArea.toggleClass('show', !isOpen);
$(this).attr('aria-expanded', !isOpen);
});
// RWD 位置搬移
function moveSearch() {
if ($(window).width() < 767) {
$searchArea.insertAfter('label[for="open-orbit-nav"]');
} else {
$searchArea.appendTo('.orbit-bar-inner');
}
}
moveSearch();
$(window).resize(moveSearch);
});
// 2. 語言按鈕與手機版選單補強
$(function() {
function fixLanguageA11y() {
var isEn = document.documentElement.lang === 'en';
var correctTitle = isEn ? 'Open language menu' : '在本視窗開啟語言選單';
var $desktopBtn = $('#languagebutton');
var $langLi = $('#language-li');
var $langUl = $('#language-li ul');
// =============================================
// ✅ 新增 GN1210101E繁體中文 li 補上可聚焦 <a>
// 桌面版 + 手機版都處理
// =============================================
var $activeLis = $langUl.find('li.active')
.add($('#language-li-ul').find('li.active'));
$activeLis.each(function() {
var $li = $(this);
if ($li.find('a, button').length === 0) {
var activeText = $li.text().trim();
$li.html(
'<a href="javascript:;" ' +
'aria-current="true" ' +
'title="' + (isEn ? 'Current language' : '目前語言') + '" ' +
'tabindex="0">' +
activeText +
'</a>'
);
}
});
// =============================================
// Desktop 語言按鈕
// =============================================
if ($desktopBtn.length > 0) {
$desktopBtn.attr({
'aria-expanded': 'false',
'role': 'button',
'aria-haspopup': 'true',
'title': correctTitle
});
$desktopBtn.removeAttr('aria-label');
function openLangMenu() {
$langUl.addClass('show');
$desktopBtn.attr('aria-expanded', 'true');
$('.orbit-bar-search-sign-language').addClass('show');
}
function closeLangMenu() {
$langUl.removeClass('show');
$desktopBtn.attr('aria-expanded', 'false');
}
// 原有focus 展開
$desktopBtn.on('focus', function() {
openLangMenu();
});
// ✅ 新增 GN1210100EEnter / Space 切換、Escape 收合
$desktopBtn.on('keydown', function(e) {
if (e.which === 13 || e.which === 32) {
e.preventDefault();
$langUl.hasClass('show') ? closeLangMenu() : openLangMenu();
}
if (e.which === 27) {
closeLangMenu();
$desktopBtn.focus();
}
});
// 原有click 切換
$desktopBtn.on('click', function(e) {
e.preventDefault();
$langUl.hasClass('show') ? closeLangMenu() : openLangMenu();
});
// ✅ 新增:選單內 Escape 跳回按鈕
$langUl.find('a').on('keydown', function(e) {
if (e.which === 27) {
e.preventDefault();
closeLangMenu();
$desktopBtn.focus();
}
});
// 原有:焦點離開整個 language-li 時收合
$langLi.on('focusout', function() {
var $container = $(this);
setTimeout(function() {
if (!$container.is(':focus-within')) {
closeLangMenu();
}
}, 150);
});
}
// =============================================
// 手機版選單補強(原有邏輯完整保留)
// =============================================
var $mobileBtn = $('.mobile-button');
if ($mobileBtn.length > 0) {
$mobileBtn.attr({ 'role': 'button', 'tabindex': '0', 'aria-haspopup': 'true', 'aria-expanded': 'false' });
$mobileBtn.on('focus', function() {
$(this).closest('li').find('ul').addClass('show');
$(this).attr('aria-expanded', 'true');
});
$mobileBtn.on('keydown', function(e) {
if (e.which === 13 || e.which === 32) {
e.preventDefault();
var $ul = $(this).closest('li').find('ul');
$ul.toggleClass('show');
$(this).attr('aria-expanded', $ul.hasClass('show') ? 'true' : 'false');
}
});
$('#language-li-ul').on('focusout', function() {
var $container = $(this);
setTimeout(function() {
if (!$container.is(':focus-within')) {
$container.find('ul').removeClass('show');
$mobileBtn.attr('aria-expanded', 'false');
}
}, 150);
});
}
// =============================================
// 原有MutationObserver 強制鎖定 title
// =============================================
var target = document.getElementById('languagebutton');
if (target) {
var observer = new MutationObserver(function() {
if (target.getAttribute('title') !== correctTitle) {
target.setAttribute('title', correctTitle);
}
});
observer.observe(target, { attributes: true, attributeFilter: ['title'] });
}
}
setTimeout(fixLanguageA11y, 600);
});
// rwd左上選單無障礙
$(function() {
/**
* 修正:當焦點離開整個區塊(含語言選單最後一項)時,關閉大選單
*/
function fixSearchMenuFocusOut() {
var $searchArea = $('.orbit-bar-search-sign-language');
var $orbitLabel = $('label[for="open-orbit-nav"]');
var $langBtn = $('#languagebutton');
// 使用 focusout 監聽整個搜尋/語言區域
$searchArea.on('focusout', function(e) {
// 關鍵:使用 setTimeout 讓 document.activeElement 抓到下一個獲焦元素
setTimeout(function() {
// 如果目前的焦點不在 $searchArea 裡面,也不是回到觸發的 $orbitLabel 上
if (!$searchArea.is(':focus-within') && !$(document.activeElement).is($orbitLabel)) {
// 1. 移除大區塊顯示
$searchArea.removeClass('show');
// 2. 移除子層語言選單顯示
$searchArea.find('ul').removeClass('show');
// 3. 狀態重置為「折疊」供語音報讀
$orbitLabel.attr('aria-expanded', 'false');
$langBtn.attr('aria-expanded', 'false');
}
}, 50);
});
// 桌面版 Language 按鈕特殊處理:焦點移入時
$langBtn.on('focus', function() {
// 確保父層搜尋區塊是顯示的 (針對從別處直接 tab 過來的情況)
$searchArea.addClass('show');
$(this).attr('aria-expanded', 'true');
});
// 針對手機版 mobile-button (span) 同理處理
$('.mobile-button').on('focusout', function() {
var $mobileParent = $('#language-li-ul');
setTimeout(function() {
if (!$mobileParent.is(':focus-within')) {
$mobileParent.find('ul').removeClass('show');
$('.mobile-button').attr('aria-expanded', 'false');
}
}, 50);
});
}
setTimeout(fixSearchMenuFocusOut, 600);
});
//萬用表格查詢按鈕翻中英
$(document).ready(function () {
const lang = $('html').attr('lang');
if (lang === 'en') {
$('.searchbtn2').each(function () {
$(this).attr('title', 'Search'); // 修改 tooltip
$(this).html('<i class="fa-solid fa-magnifying-glass"></i> Search'); // 修改按鈕文字
});
} else if (lang === 'zh_tw') {
$('.searchbtn2').each(function () {
$(this).attr('title', '查詢');
$(this).html('<i class="fa-solid fa-magnifying-glass"></i>查詢');
});
}
});
$(document).ready(function () {
$('.controlplay a[role="radio"]').on('click', function () {
// 取消所有的 aria-checked 並還原文字
$('.controlplay a[role="radio"]').attr('aria-checked', 'false');
$('.controlplay a[role="radio"] span').each(function () {
var text = $(this).text().replace('(已選取)', '');
$(this).text(text);
});
// 設定目前被點擊的按鈕為已選取
$(this).attr('aria-checked', 'true');
var selectedText = $(this).text().trim();
$(this).find('span').text(selectedText + '(已選取)');
});
});
//member轉換a
$(document).ready(function () {
$('.member-data-value-5 a').each(function () {
$(this).replaceWith($(this).contents()); // 把<a>替換成它裡面的內容
});
$('.member-data-value-3 a').each(function () {
$(this).replaceWith($(this).contents()); // 把<a>替換成它裡面的內容
});
$('.member-data-value-3 a').has('i').each(function() {
$(this).replaceWith($(this).contents());
});
$('.member-data-value-2 a').has('i').each(function() {
$(this).replaceWith($(this).contents());
});
});
//title change en color
$(document).ready(function(){
const selectors = `
.unity-title span,
.title span,
.sitemenu-title span,
.index-link .index-title span,
.widget-link .widget-title span,
.i-annc__page-title span,
.universal-table-index h3 span,
.search-widget h3 span,
.projects-index h3 span,
.index-member-8 .i-member-status-title span,
.index-member-7 .i-member-status-title span,
.index-member-5 .i-member-status-title span,
.index-member-4 .i-member-status-title span,
.index-member-3 .i-member-status-title span,
.index-member-2 .i-member-status-title span,
.index-member-1 .i-member__status-title span,
.show-gallery .show-title span,
.index-gallery .index-title span,
.widget-gallery .widget-title span,
.index-faqs .index-title span,
.layout-content .widget-faqs.widget1 .widget-title span,
.i-archive-title span,
.w-archive .widget-title span,
.w-archive .w-archive__widget-title span,
.s-annc .s-annc__show-title span,
.i-annc .i-annc__widget-title span,
.i-annc .i-annc__page-title span,
.w-annc .w-annc__widget-title span,
.page-module-title span
`;
$(selectors).contents().each(function(){
if (this.nodeType === 3) { // 只處理文字節點
let text = this.nodeValue;
if (/[A-Za-z]/.test(text)) {
// 把英文部分包起來
let newHtml = text.replace(/([A-Za-z]+)/g, '<div class="en">$1</div>');
$(this).replaceWith(newHtml);
}
}
});
});
// //選單樣式2
// $(document).ready(function() {
// "use strict";
// $(".menu > ul > li").hover(function(e) {
// if ($(window).width() > 943) {
// $(this).children("ul").stop(true, false).fadeToggle(150);
// e.preventDefault();
// }
// });
// $('.modules-menu-level-1').css('left','-'+$('.outdropdowns .dropdowns').offset().left+'px');
// });
// $(document).resize(function() {
// $('.modules-menu-level-1').css('left','-'+$('.outdropdowns .dropdowns').offset().left+'px');
// if ($(window).width() < 769){
// $('.modules-menu-level-1').css('left','')
// }
// });
$(window).load(function(){
$("iframe[src*='google']").attr('title','googleOauth');
});
//隱藏Hashtags
$(document).ready(function () {
$('.universal-table-show .table-title').each(function () {
var $titleTd = $(this);
var titleText = $titleTd.text().trim();
var $nextTd = $titleTd.next('td');
if (titleText === 'Hashtags' && $nextTd.length > 0 && $nextTd.text().trim() === '') {
$titleTd.closest('tr').hide();
}
});
});
$(document).ready(function () {
$('.universal-table-index .theadsearch tr th').each(function (index) {
const $th = $(this);
const title = $th.find('.universal-th-text').text().trim();
// 找到 Hashtags 欄
if (title === 'Hashtags') {
let allEmpty = true;
// 走訪 tbody 的每一列檢查對應欄位是否都為空
$('.universal-table-index tbody tr').each(function () {
const $td = $(this).find('td').eq(index);
if ($td.text().trim() !== '') {
allEmpty = false;
return false; // 提前跳出 each
}
});
if (allEmpty) {
// 隱藏 thead 裡對應的 th
$th.hide();
// 隱藏 tbody 所有對應的 td 欄位
$('.universal-table-index tbody tr').each(function () {
$(this).find('td').eq(index).hide();
});
}
}
});
});
$(document).ready(function () {
setTimeout(function () {
$('iframe.twitter-share-button, iframe.twitter-tweet-button').each(function () {
$(this).attr('title', '分享至 X 在新視窗開啟');
});
}, 1500);
});
//orbitbarlogo無障礙
$(function() {
var $logo = $('.orbit-bar-logo');
var $inner = $logo.contents().not('p');
var $span = $('<span>').addClass('orbit-bar-logo').append($inner);
$logo.replaceWith($span);
});
//orbitbar登入無障礙
$(function() {
var $loginWindow = $('.login-window');
var $checkbox = $('#open-orbit-login');
// login-window 顯示時,焦點移到 label.close
$checkbox.on('change', function() {
if ($(this).is(':checked')) {
setTimeout(function() {
$('.login-window .login-header label.close').focus();
}, 50);
}
});
// login-window 失去焦點時,關閉並還原焦點
$loginWindow.on('focusout', function() {
var $thisWindow = $(this);
setTimeout(function() {
// document.hasFocus() 為 false 代表焦點移到瀏覽器外(開發者工具、右鍵選單等),不關閉
if (!document.hasFocus()) return;
if (!$thisWindow.is(':focus-within') && $checkbox.is(':checked')) {
$(".orbit-bar-logo").one("focusin", function() {
if (window.orbit_login_button) {
window.orbit_login_button.focus();
}
});
$checkbox.click();
}
}, 500);
});
});
//gallery層級問題
$(function() {
var target = document.getElementById('gallery-theater-stage');
if (!target) return;
var observer = new MutationObserver(function() {
var display = target.style.display;
if (display === 'block') {
$('.verticalhome').css('z-index', '2000');
} else if (display === 'none') {
$('.verticalhome').css('z-index', 'auto');
}
});
observer.observe(target, {
attributes : true,
attributeFilter: ['style']
});
});
$(document).ready(function() {
function removeFakeLinks() {
$('a.fake_link').remove();
}
// 初始執行一次
removeFakeLinks();
// Shift+Tab 時也執行
$(document).on('keydown', function(e) {
if (e.key === 'Tab' && e.shiftKey) {
removeFakeLinks();
}
});
// MutationObserver 監聽 DOM 變化fake_link 一出現就移除
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
mutation.addedNodes.forEach(function(node) {
// 直接是 fake_link
if ($(node).is('a.fake_link')) {
$(node).remove();
}
// 或其子元素內含 fake_link
if ($(node).find) {
$(node).find('a.fake_link').remove();
}
});
});
});
observer.observe(document.body, {
childList: true,
subtree: true
});
});
// 執行 member等高計算目前改用flexbox故mark掉 by ika 20160105
// $(window).load(function() {
// if ($('.index-member-3').length && $(window).width() > 992) {
// ORBITFRONT.member.equalHeight('.i-member-item-inner');
// }
// });
}(jQuery, window));