This commit is contained in:
ken 2026-06-26 15:22:15 +08:00
parent 10302c125f
commit 70c31e4656
2 changed files with 168 additions and 159 deletions

View File

@ -1591,6 +1591,7 @@ $(function() {
resizeTimer = setTimeout(fixAccessKeyM, 150);
});
});
//導覽選單子選單無障礙狀態修正 (支援多層級)
function fixNavMenuA11y() {
const $navItems = $('#main-nav li');
@ -1659,53 +1660,24 @@ $(function() {
//公告頁籤無障礙
$(function() {
function fixTabLinearOrder() {
// 只處理內部含有 .tab_nav 的 .w-annc
var $targetAnnc = $('.w-annc').filter(function() {
return $(this).find('.tab_nav').length > 0;
});
// 若頁面上沒有符合條件的 .w-annc直接離開
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 $();
}
// --- 1. 順向遊走:標籤 -> 對應內容 ---
$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);
var category = $(this).data('category');
var $scope = $(this).closest('.w-annc'); // 限定在同一個 .w-annc
var $visibleItems = $scope.find('.w-annc__item[data-category="' + category + '"]:visible');
if ($visibleItems.length > 0) {
var $firstLink = $visibleItems.find('a').first();
if ($firstLink.length > 0) {
@ -1714,62 +1686,30 @@ $(function() {
}
}
}
// 反向 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 到最後一個連結跳下一個頁籤
// --- 2. 反向遊走:內容 -> 對應標籤 ---
$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');
var $scope = $currentLink.closest('.w-annc'); // 限定在同一個 .w-annc
var category = $currentItem.data('category');
var $visibleItems = $scope.find('.w-annc__item[data-category="' + category + '"]:visible');
// 找出當前 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();
$scope.find('.filter_tab[data-category="' + category + '"]').focus();
}
}
// Tab若是最後一個連結跳到下一個頁籤並切換
if (e.which === 9 && !e.shiftKey) {
if ($currentLink.is($visibleItems.find('a').last())) {
var $currentTab = $scope.find('.filter_tab[data-category="' + category + '"]');
var $nextTab = $currentTab.next('.filter_tab');
if ($nextTab.length > 0) {
e.preventDefault();
@ -1779,96 +1719,111 @@ $(function() {
}
}
});
}
setTimeout(fixTabLinearOrder, 500);
});
// --- 3. 反向遊走:標籤 -> 上一個標籤的內容最後一個連結 ---
$tabs.on('keydown', function(e) {
if (e.which === 9 && e.shiftKey) {
var $scope = $(this).closest('.w-annc'); // 限定在同一個 .w-annc
var $prevTab = $(this).prev('.filter_tab');
if ($prevTab.length > 0) {
var prevCategory = $prevTab.data('category');
$prevTab.click();
//頁籤無障礙
$(function () {
function fixTabAccessibility() {
var $prevItems = $scope.find('.w-annc__item[data-category="' + prevCategory + '"]:visible');
var $lastLink = $prevItems.find('a').last();
// 各自獨立處理每組 .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
if ($lastLink.length > 0) {
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;
$lastLink.focus();
}
}
// 移動焦點並觸發點擊切換
if ($target && $target.length) {
$tabs.attr('tabindex', '-1');
$target.attr('tabindex', '0').focus().trigger('click');
}
});
}
});
}
setTimeout(fixTabAccessibility, 500);
fixTabLinearOrder();
});
//頁籤無障礙
$(function () {
function fixTabAccessibility() {
var $tabNav = $('.tab_nav');
var $tabs = $tabNav.find('li'); // ✅ 你的 HTML 是 li不是 .filter_tab
// --- 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' // ✅ 只有 active 的可以被 Tab 聚焦
});
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() {
@ -2477,7 +2432,63 @@ $(function() {
init();
});
//post
$(document).ready(function () {
setTimeout(function () {
$('iframe.twitter-share-button, iframe.twitter-tweet-button').each(function () {
$(this).attr('title', '分享至 X 在新視窗開啟');
});
}, 1500);
});
$(function() {
function bindIframeFocus() {
var $iframe = $('.twitter-share-button');
if ($iframe.length === 0) return;
$iframe.each(function() {
var $wrap = $(this).closest('.tw-share-button');
// 讓外層可以被 tab 到並顯示焦點框
$wrap.attr('tabindex', '-1');
$(window).on('blur.twitterFocus', function() {
setTimeout(function() {
if (document.activeElement &&
$(document.activeElement).hasClass('twitter-share-button')) {
$wrap.css({
'outline': '3px solid #005fcc',
'outline-offset': '2px',
'border-radius': '2px'
});
}
}, 100);
});
$(window).on('focus.twitterFocus', function() {
$wrap.css({
'outline': '',
'outline-offset': ''
});
});
});
}
// 用 MutationObserver 等 iframe 被 Twitter script 插入後才綁定
var observer = new MutationObserver(function(mutations) {
if ($('.twitter-share-button').length > 0) {
bindIframeFocus();
observer.disconnect(); // 綁定成功後停止監聽
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
// 保險2秒後強制執行一次
setTimeout(bindIframeFocus, 1000);
});
// 1. OrbitBar 基礎與搜尋選單邏輯
$(document).ready(function() {
const isEn = document.documentElement.lang === 'en';

View File

@ -2,9 +2,7 @@
@import "../initial";
@import "variables";
#orbit-bar .orbit-bar-title a{
color: #333!important;
}
#orbit-bar .orbit-bar-inner > label:focus, #orbit-bar .orbit-bar-inner > label.focus{
.orbit-bar-search-sign-language{
display: block