This commit is contained in:
ken 2026-04-22 16:11:14 +08:00
parent 7ae3e05c24
commit b69db30a4e
2 changed files with 441 additions and 283 deletions

View File

@ -789,38 +789,37 @@
// 延遲執行確保圖片與動態內容已渲染
setTimeout(fixImageAccessibility, 500);
});
function removeEmptyTitles() {
// 定義所有需要檢查的 class
const targetClasses = [
'.w-annc__widget-title',
'.widget-title',
'.show-title',
'.event-annc-title',
'.annc-title',
'.sitemenu-title',
'.widget-link__widget-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(', ');
// 將陣列轉換為 jQuery 選擇器字串
const selector = targetClasses.join(', ');
$(selector).each(function() {
// 使用 $.trim 移除空格、換行符號
// 然後檢查裡面是否完全沒有文字
const textContent = $.trim($(this).text());
$(selector).each(function() {
// 使用 $.trim 移除空格、換行符號
// 然後檢查裡面是否完全沒有文字
const textContent = $.trim($(this).text());
if (textContent === "") {
// 如果沒有文字,則將整個元素刪除
$(this).remove();
console.log('已移除空標題元素:', this.className);
}
});
}
if (textContent === "") {
// 如果沒有文字,則將整個元素刪除
$(this).remove();
}
});
}
// 執行 function
$(document).ready(function() {
removeEmptyTitles();
});
// 執行 function
$(document).ready(function() {
removeEmptyTitles();
});
$(".w-annc__img-wrap a").each(function () {
var $this = $(this);
// 確保 <a> 內沒有文字節點 (避免重複添加)
@ -880,105 +879,99 @@ $(document).ready(function() {
$button.attr('aria-label', '播放驗證碼語音');
}
});
//有連結目的之所有a標籤加上aria-label和title
$(function() {
/**
* 無障礙 AA 級補強最終整合版 (人工檢測完全合格)
* 1. 修正語言選單Tab 到達時顯示在本視窗開啟語言選單
* 2. 智慧 Title 策略
* - 長文字僅保留動作提示 (: (在本視窗開啟))避免重複讀取
* - 短文字/標籤組合 [文字內容] + [動作提示]增強目的識別
* 3. 圖文並存處理符合 HM1240402E當有文字時圖片 alt 設為空值
* 4. 清理無效描述攔截這是一張圖片等不合格內容
*/
function fixAccessibilityAll() {
// --- Part 1: 語言選單修正 (Language Button) ---
var $langBtn = $('#languagebutton');
if ($langBtn.length > 0) {
$langBtn.attr('title', '在本視窗開啟語言選單');
$langBtn.removeAttr('aria-label');
//有連結目的之所有a標籤的無障礙處理
$(function() {
/**
* 全站無障礙 AA 級補強 (多語系偵測版)
* 支援功能語系自動偵測HM1240404E 修正檔案預知類型圖片替代文字
*/
function fixAccessibilityAll() {
// 1. 偵測目前頁面語系 (優先抓取 html lang若無則預設為 zh-Hant)
var pageLang = $('html').attr('lang') || 'zh-Hant';
var isEn = pageLang.toLowerCase().startsWith('en');
// 2. 定義語系對應字典
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' : '連結'
};
// --- 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);
var href = ($a.attr('href') || '').toLowerCase();
if (!href || href.startsWith('javascript:')) return;
var linkText = $a.text().replace(/\u00a0/g, '').trim();
var $img = $a.find('img');
var currentTitle = ($a.attr('title') || '').trim();
// 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. 智慧修正與標題補充 (解決 HM1240404E 不明符號問題)
// 檢查是否包含括號 () 或 中英文的另開視窗關鍵字
var hasBadSymbol = currentTitle.includes('()') ||
currentTitle.includes('另開新視窗') ||
currentTitle.includes('Open in new window');
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 + windowTask).trim());
$img.attr('alt', imgAlt);
}
else if (linkText !== "") {
// 【有文字連結】
if (fileExt !== "" || hasBadSymbol || currentTitle === "") {
var isTag = $a.hasClass('label') || $a.hasClass('tag') || $a.find('[class*="tag"]').length > 0;
if (fileExt !== "") {
// 檔案下載:連結文字 + .副檔名 + 動作 (語系化)
$a.attr('title', linkText + " ." + fileExt + " " + windowTask);
} else if (linkText.length <= 6 || isTag) {
// 短文字:補充完整語意
$a.attr('title', linkText + " " + windowTask);
} else {
// 長文字:僅動作提示
$a.attr('title', windowTask);
}
}
}
// D. 最終清理
$a.removeAttr('aria-label');
if (linkText !== "" && $img.length > 0) { $img.attr('alt', ''); }
});
}
// --- Part 2: 全站連結補強 (Links) ---
$('a').each(function() {
var $a = $(this);
var href = $a.attr('href');
// 基礎攔截
if (!href || href.startsWith('javascript:')) return;
// 1. 獲取內容資訊
var linkText = $a.text().replace(/\u00a0/g, '').trim();
var $img = $a.find('img');
var rawAlt = ($img.length > 0) ? ($img.attr('alt') || '').trim() : '';
var forbiddenTexts = ['這是一張圖片', '圖片', 'image', 'photo', '圖示'];
var imgAlt = forbiddenTexts.includes(rawAlt) ? '' : rawAlt;
var hasSrOnly = $a.find('.sr-only').length > 0 && $a.find('.sr-only').text().trim().length > 0;
var srOnlyText = hasSrOnly ? $a.find('.sr-only').text().trim() : '';
// 2. 移除空連結
if (linkText === '' && $img.length === 0 && !hasSrOnly && !($a.attr('aria-label'))) {
$a.remove();
return;
}
// 3. 準備視窗提示
let windowTask = ($a.attr('target') === '_blank') ? '(在新視窗開啟)' : '(在本視窗開啟)';
// 4. 核心邏輯判定
// 【情況 A純圖片連結 (無文字)】
if (linkText === "" && !hasSrOnly) {
if (imgAlt !== "") {
// 名字讓圖片 alt 說title 只放動作提示 (避免重複)
$a.attr('title', windowTask);
$img.attr('alt', imgAlt);
} else {
let fallback = $a.attr('aria-label') || '連結';
$a.attr('title', (fallback + ' ' + windowTask).trim());
$img.attr('alt', fallback);
}
}
// 【情況 B有文字連結】
else {
/**
* 智慧 Title 判斷
* 1. 如果是標籤 (Class label tag) 或文字很短 (<= 6 )
* -> Title 顯示[文字內容] (動作提示)
* 2. 如果是長文章標題或一般長連結
* -> Title 僅顯示(動作提示) 以避免重複朗讀
*/
var isTag = $a.hasClass('label') || $a.hasClass('tag') || $a.find('[class*="tag"]').length > 0 || $a.find('[class*="label"]').length > 0;
if (linkText.length <= 6 || isTag) {
// 短文字或標籤:補全語意
$a.attr('title', linkText + " " + windowTask);
} else {
// 長文字:精簡語意
$a.attr('title', windowTask);
}
// 符合規範:圖文並存時,圖片 alt 應為空值
// if ($img.length > 0) {
// $img.attr('alt', '');
// }
}
// 5. 最終清理
$a.removeAttr('aria-label');
$a.removeAttr('alt'); // a 標籤不應有 alt
if ($img.length > 0 && forbiddenTexts.includes($img.attr('alt'))) {
$img.attr('alt', '');
}
});
}
// 延遲執行
setTimeout(fixAccessibilityAll, 500);
});
setTimeout(function() {
fixAccessibilityAll();
}, 600);
});
// if (location.href.search('editmode=on') === -1) {
// // 1. 處理圖片 alt 重複問題 (保持原邏輯但優化)
@ -1205,6 +1198,154 @@ $(function() {
// 執行 function
removeHiddenElementsInsideBrand();
//修正 Alt+M 定位點位置
$(function() {
function fixAccessKeyM() {
var $accessKeyM = $('#accesskey_menu');
var $navbarHeader = $('.navbar-header');
if ($accessKeyM.length > 0 && $navbarHeader.length > 0) {
$accessKeyM.insertBefore($navbarHeader);
$accessKeyM.css({
'display': 'inline-block',
'position': 'relative',
'float': 'left', // 靠左對齊
});
// $accessKeyM.attr('title', '中央內容區塊導覽列 (Alt+M)');
}
}
setTimeout(fixAccessKeyM, 500);
});
//公告頁籤無障礙
$(function() {
function fixTabLinearOrder() {
var $tabs = $('.filter_tab');
var $anncList = $('.w-annc__list');
// --- 1. 順向遊走:標籤 -> 對應內容 ---
$tabs.on('keydown', function(e) {
// 當在標籤按下 Tab (排除 Shift+Tab)
if (e.which === 9 && !e.shiftKey) {
var category = $(this).data('category');
var $visibleItems = $('.w-annc__item[data-category="' + category + '"]:visible');
// 如果目前選中的標籤內容有連結,跳轉到內容的第一個連結
if ($visibleItems.length > 0) {
var $firstLink = $visibleItems.find('a').first();
if ($firstLink.length > 0) {
e.preventDefault();
$firstLink.focus();
}
}
}
// 處理標籤的 Enter/Space 切換
if (e.which === 13 || e.which === 32) {
e.preventDefault();
$(this).click();
}
});
// --- 2. 反向遊走:內容 -> 對應標籤 ---
$anncList.on('keydown', '.w-annc__item a', function(e) {
var $currentLink = $(this);
var $currentItem = $currentLink.closest('.w-annc__item');
var category = $currentItem.data('category');
var $visibleItems = $('.w-annc__item[data-category="' + category + '"]:visible');
// 如果是目前內容的第一個連結,按下 Shift+Tab 應回到對應標籤
if (e.which === 9 && e.shiftKey) {
if ($currentLink.is($visibleItems.find('a').first())) {
e.preventDefault();
$('.filter_tab[data-category="' + category + '"]').focus();
}
}
// 如果是目前內容的最後一個連結,按下 Tab 應跳往「下一個標籤」
if (e.which === 9 && !e.shiftKey) {
if ($currentLink.is($visibleItems.find('a').last())) {
var $nextTab = $('.filter_tab[data-category="' + category + '"]').next('.filter_tab');
if ($nextTab.length > 0) {
e.preventDefault();
$nextTab.focus();
$nextTab.click(); // 自動切換分頁內容,符合視覺直覺
}
}
}
});
// --- 3. 反向遊走:標籤 -> 上一個標籤的內容最後一個連結 ---
$tabs.on('keydown', function(e) {
if (e.which === 9 && e.shiftKey) {
var $prevTab = $(this).prev('.filter_tab');
if ($prevTab.length > 0) {
var prevCategory = $prevTab.data('category');
// 先切換到上一個分頁
$prevTab.click();
// 找出上一個分頁最後一個可見連結
var $prevItems = $('.w-annc__item[data-category="' + prevCategory + '"]:visible');
var $lastLink = $prevItems.find('a').last();
if ($lastLink.length > 0) {
e.preventDefault();
$lastLink.focus();
}
}
}
});
}
fixTabLinearOrder();
});
//導覽選單子選單無障礙狀態修正 (支援多層級)
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();
}
forFreeGo();
@ -1863,118 +2004,188 @@ $(function() {
init();
});
//orbitbar無障礙js
$(document).ready(function() {
const isEnglish = document.documentElement.lang === 'en';
if (isEnglish) {
$('.navbar-toggle').attr({
title: 'menu',
'aria-label': 'menu'
});
$('label[for="open-orbit-nav"]').attr({
title: 'Site search and language menu',
'aria-label': 'Site search and language menu'
});
$('.mobile-button').attr({
title: 'Language menu',
'aria-label': 'Language menu'
});
} else {
$('label[for="open-orbit-nav"]').attr({
title: '全站収尋及語言切換選單',
'aria-label': '全站収尋及語言切換選單'
});
$('.mobile-button').attr({
title: '語言切換選單',
'aria-label': '語言切換選單'
});
}
// 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'); // 搜尋框通常是選單內第一個獲焦元素
$('label[for="open-orbit-login"]').removeAttr('tabindex');
$('#orbit-bar').find('li').each(function() {
var $li = $(this);
// 初始化屬性
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' });
// 如果 <li> 中没有 <a> 元素,则为 <li> 设置 tabindex="0"
if ($li.children('a').length === 0) {
$li.attr('tabindex', '0');
} else {
// 如果 <li> 中有 <a> 元素,则确保 <a> 有 tabindex="0"
$li.find('a').attr('tabindex', '0');
// 确保 <li> 不影响焦点管理,移除 <li> 的 tabindex
$li.removeAttr('tabindex');
// 如果 <li> 被聚焦,自动跳转到 <a> 元素
$li.on('focus', function() {
$(this).find('a').focus();
});
}
});
$('label[for="open-orbit-nav"]').attr('tabindex', '0');
// 当屏幕宽度小于 768px 时,将 .orbit-bar-search-sign-language 移动到 <label for="open-orbit-nav"> 后面
function moveSearchSignLanguage() {
if ($(window).width() < 767) {
$('.orbit-bar-search-sign-language').insertAfter('label[for="open-orbit-nav"]');
// --- 【修正重點 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 {
// 屏幕宽度大于等于 768px 时,恢复原位置
$('.orbit-bar-search-sign-language').appendTo('.orbit-bar-inner');
// 正向進入
$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');
}
}
moveSearchSignLanguage();
$(window).resize(function() {
moveSearchSignLanguage();
});
// 当 <label for="open-orbit-nav"> 被选中时,显示 .orbit-bar-search-sign-language
$('label[for="open-orbit-nav"]').on('focus', function() {
$('.orbit-bar-search-sign-language').addClass('show');
})
$('#languagebutton').on('focus', function() {
$('#language-li ul').addClass('show');
});
moveSearch();
$(window).resize(moveSearch);
});
// 监听 #language 元素被 Tab 键选中时
$('#language-li-ul li').on('focus', function() {
// 给 #language 内部的 ul 元素添加 show 类
$(this).find('ul').addClass('show');
});
$('#language-li-ul li ul > li:last-child>a').on('blur', function() {
$('#language-li-ul li ul').removeClass('show');
});
$('.orbit-bar-title a').on('focus', function() {
$('#language-li-ul li ul').removeClass('show');
});
$('#language-li').on('focus', function() {
// 给 #language 内部的 ul 元素添加 show 类
$(this).find('ul').addClass('show');
});
$('#language-li ul > li:last-child>a').on('blur', function() {
$('#language-li ul').removeClass('show');
$('.orbit-bar-search-sign-language').removeClass('show');
});
$('label[for="open-orbit-login"]').on('blur', function() {
$('.orbit-bar-search-sign-language').removeClass('show');
});
$('#gotocenter').on('focus', function() {
// 当 #gotocenter 被选中时,移除 .orbit-bar-search-sign-language 上的 show 类
$('.orbit-bar-search-sign-language').removeClass('show');
});
$('label[for="open-orbit-nav"]').on('click', function() {
// 切換 .orbit-bar-search-sign-language 的 .show 類別
$('.orbit-bar-search-sign-language').removeClass('show');
});
$('li[tabindex="0"]').each(function () {
const $li = $(this);
if ($li.find('input').length > 0) {
$li.removeAttr('tabindex');
// 2. 語言按鈕與手機版選單補強
$(function() {
function fixLanguageA11y() {
var $desktopBtn = $('#languagebutton');
if ($desktopBtn.length > 0) {
$desktopBtn.attr({ 'aria-expanded': 'false', 'role': 'button', 'aria-haspopup': 'true' });
$desktopBtn.on('focus', function() {
$(this).closest('#language-li').find('ul').addClass('show');
$(this).attr('aria-expanded', 'true');
$('.orbit-bar-search-sign-language').addClass('show');
});
}
});
});
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);
});
}
// 強制鎖定 Title
var target = document.getElementById('languagebutton');
if (target) {
var isEn = document.documentElement.lang === 'en';
var correctTitle = isEn ? 'Open language menu' : '在本視窗開啟語言選單';
var observer = new MutationObserver(function() {
if (target.getAttribute('title') !== correctTitle) target.setAttribute('title', correctTitle);
});
observer.observe(target, { attributes: true });
}
}
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');
@ -2203,60 +2414,7 @@ $(document).ready(function() {
// 執行修復功能
fixVideoPosterAlt();
});
//導覽選單與語言按鈕無障礙補強 (人工檢測完全合格版)
$(function() {
/**
* 語言按鈕無障礙補強 (MutationObserver 鎖定版)
* 目的防止導覽套件在 Focus/Click 時將 Title 抽換為按下關閉語言選單
*/
function forceFixLanguageButton() {
var $langBtn = $('#languagebutton');
var target = document.getElementById('languagebutton'); // 原生 DOM 用於 Observer
if ($langBtn.length > 0 && target) {
// 1. 定義修正行為的函數
var enforceA11y = function(el) {
var correctTitle = '在本視窗開啟語言選單';
if (el.getAttribute('title') !== correctTitle) {
el.setAttribute('title', correctTitle);
}
// 同步確保其它屬性正確
if (el.getAttribute('role') !== 'button') {
el.setAttribute('role', 'button');
el.setAttribute('aria-haspopup', 'true');
}
};
// 2. 初始執行一次
enforceA11y(target);
if (!$langBtn.attr('aria-expanded')) {
$langBtn.attr('aria-expanded', 'false');
}
// 3. 使用 MutationObserver 進行「即時監修」
// 這是為了解決套件在 focus 或 click 時偷偷改掉 title 的問題
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.attributeName === 'title') {
enforceA11y(target);
}
});
});
// 開始監聽屬性變動
observer.observe(target, { attributes: true });
// 4. 事件補強:針對點擊與聚焦再次確保 (雙重保險)
$langBtn.on('click focusin', function() {
enforceA11y(this);
});
}
}
// 延遲 600ms 執行,確保避開大部份套件的初始載入時間
setTimeout(forceFixLanguageButton, 600);
});
//修正無超連結目的之連結
$(function() {
/**

View File

@ -3,7 +3,7 @@
a[accesskey] {
position: absolute;
margin-left: -0.9375em;
color: transparent !important;
color: transparent ;
}
#orbit-bar a[accesskey] {