update
This commit is contained in:
parent
9090361cea
commit
0287a4eb1e
|
|
@ -653,7 +653,7 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
if (document.documentElement.lang === 'zh_tw') {
|
if (document.documentElement.lang === 'zh_tw') {
|
||||||
document.documentElement.lang = 'zh-Hant';
|
document.documentElement.lang = 'zh-Hant-TW';
|
||||||
}
|
}
|
||||||
//tab鍵按下
|
//tab鍵按下
|
||||||
$(document).on('keydown', function(e) {
|
$(document).on('keydown', function(e) {
|
||||||
|
|
@ -975,7 +975,7 @@ $(function() {
|
||||||
var urlParams = new URLSearchParams(window.location.search);
|
var urlParams = new URLSearchParams(window.location.search);
|
||||||
var isEditMode = urlParams.get('editmode') === 'on';
|
var isEditMode = urlParams.get('editmode') === 'on';
|
||||||
|
|
||||||
var pageLang = $('html').attr('lang') || 'zh-Hant';
|
var pageLang = $('html').attr('lang') || 'zh-Hant-TW';
|
||||||
var isEn = pageLang.toLowerCase().startsWith('en');
|
var isEn = pageLang.toLowerCase().startsWith('en');
|
||||||
|
|
||||||
var i18n = {
|
var i18n = {
|
||||||
|
|
@ -1536,92 +1536,7 @@ $(function() {
|
||||||
resizeTimer = setTimeout(fixAccessKeyM, 150);
|
resizeTimer = setTimeout(fixAccessKeyM, 150);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
//公告頁籤無障礙
|
|
||||||
$(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');
|
|
||||||
|
|
||||||
// --- 1. 順向遊走:標籤 -> 對應內容 ---
|
|
||||||
$tabs.on('keydown', function(e) {
|
|
||||||
if (e.which === 9 && !e.shiftKey) {
|
|
||||||
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) {
|
|
||||||
e.preventDefault();
|
|
||||||
$firstLink.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 $scope = $currentLink.closest('.w-annc'); // 限定在同一個 .w-annc
|
|
||||||
var category = $currentItem.data('category');
|
|
||||||
var $visibleItems = $scope.find('.w-annc__item[data-category="' + category + '"]:visible');
|
|
||||||
|
|
||||||
if (e.which === 9 && e.shiftKey) {
|
|
||||||
if ($currentLink.is($visibleItems.find('a').first())) {
|
|
||||||
e.preventDefault();
|
|
||||||
$scope.find('.filter_tab[data-category="' + category + '"]').focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
$nextTab.focus();
|
|
||||||
$nextTab.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// --- 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();
|
|
||||||
|
|
||||||
var $prevItems = $scope.find('.w-annc__item[data-category="' + prevCategory + '"]:visible');
|
|
||||||
var $lastLink = $prevItems.find('a').last();
|
|
||||||
|
|
||||||
if ($lastLink.length > 0) {
|
|
||||||
e.preventDefault();
|
|
||||||
$lastLink.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
fixTabLinearOrder();
|
|
||||||
});
|
|
||||||
//導覽選單子選單無障礙狀態修正 (支援多層級)
|
//導覽選單子選單無障礙狀態修正 (支援多層級)
|
||||||
function fixNavMenuA11y() {
|
function fixNavMenuA11y() {
|
||||||
const $navItems = $('#main-nav li');
|
const $navItems = $('#main-nav li');
|
||||||
|
|
@ -1687,62 +1602,222 @@ $(function() {
|
||||||
// 延遲執行,確保動態產生的選單也能被補強
|
// 延遲執行,確保動態產生的選單也能被補強
|
||||||
setTimeout(fixEmptyHref, 500);
|
setTimeout(fixEmptyHref, 500);
|
||||||
});
|
});
|
||||||
//頁籤無障礙
|
//公告頁籤無障礙
|
||||||
$(function() {
|
$(function() {
|
||||||
/**
|
function fixTabLinearOrder() {
|
||||||
* 頁籤導覽 (Tab Navigation) 無障礙補強
|
var $targetAnnc = $('.w-annc').filter(function() {
|
||||||
* 1. 容器加入 role="tablist"
|
return $(this).find('.tab_nav').length > 0;
|
||||||
* 2. 項目加入 role="tab"
|
|
||||||
* 3. 動態切換 aria-selected="true/false"
|
|
||||||
* 4. 確保 Enter 鍵可以觸發切換 (針對 tabindex="0" 的優化)
|
|
||||||
*/
|
|
||||||
function fixTabAccessibility() {
|
|
||||||
var $tabNav = $('.tab_nav');
|
|
||||||
var $tabs = $tabNav.find('.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'
|
|
||||||
});
|
|
||||||
|
|
||||||
// 修正 Title:讓使用者知道這是切換頁籤
|
|
||||||
var tabName = $this.text().trim();
|
|
||||||
$this.attr('title', '切換至 ' + tabName);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// --- 2. 監聽切換事件 (點擊或鍵盤) ---
|
if ($targetAnnc.length === 0) return;
|
||||||
// 假設原本已有切換邏輯,我們在此「補強」屬性的變更
|
|
||||||
$tabs.on('click', function() {
|
|
||||||
var $clickedTab = $(this);
|
|
||||||
|
|
||||||
// 先將所有頁籤設為未選取
|
var $tabs = $targetAnnc.find('.filter_tab');
|
||||||
$tabs.attr('aria-selected', 'false');
|
var $anncList = $targetAnnc.find('.w-annc__list');
|
||||||
|
|
||||||
// 將當前點擊的頁籤設為已選取
|
// 智慧判斷:偵測 filter_tab 用哪個屬性來分類
|
||||||
$clickedTab.attr('aria-selected', 'true');
|
// 優先用 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 $();
|
||||||
|
}
|
||||||
|
|
||||||
// --- 3. 鍵盤操作補強 (針對 tabindex="0" 的非按鈕元素) ---
|
|
||||||
$tabs.on('keydown', function(e) {
|
$tabs.on('keydown', function(e) {
|
||||||
// 當按下 Enter (13) 或 Space (32) 時觸發點擊
|
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) {
|
if (e.which === 13 || e.which === 32) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$(this).trigger('click');
|
$(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);
|
setTimeout(fixTabAccessibility, 500);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
//移除 accesskey="W" 之後的 | 符號
|
//移除 accesskey="W" 之後的 | 符號
|
||||||
$(function() {
|
$(function() {
|
||||||
function removeSeparatorAfterAccesskeyW() {
|
function removeSeparatorAfterAccesskeyW() {
|
||||||
|
|
@ -1767,6 +1842,12 @@ $(function() {
|
||||||
if ($('#language-li').is(':empty') || $('#language-li').html().trim() === '') {
|
if ($('#language-li').is(':empty') || $('#language-li').html().trim() === '') {
|
||||||
$('#language-li').remove();
|
$('#language-li').remove();
|
||||||
};
|
};
|
||||||
|
$('.header-nav').each(function() {
|
||||||
|
const cleaned = $(this).text().replace(/[\s|]/g, '');
|
||||||
|
if (cleaned === '') {
|
||||||
|
$(this).remove();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
forFreeGo();
|
forFreeGo();
|
||||||
|
|
||||||
|
|
@ -3033,6 +3114,129 @@ $(document).ready(function () {
|
||||||
// }, 500);
|
// }, 500);
|
||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
|
//cycle2無障礙
|
||||||
|
$(document).ready(function() {
|
||||||
|
// 取得頁面上所有的 Cycle2 輪播圖
|
||||||
|
var $allSlideshows = $('.cycle-slideshow');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 核心無障礙狀態刷新函式
|
||||||
|
*/
|
||||||
|
function refreshCycleA11y($el) {
|
||||||
|
var $items = $el.find('.w-annc__item, .widget-link__item, [class*="cycle-slide"], .widget-pic');
|
||||||
|
|
||||||
|
$items.each(function() {
|
||||||
|
var $slide = $(this);
|
||||||
|
var isActive = $slide.hasClass('cycle-slide-active');
|
||||||
|
|
||||||
|
if (isActive) {
|
||||||
|
// ✅ li 只設 aria-hidden,不加 tabindex
|
||||||
|
$slide.attr('aria-hidden', 'false');
|
||||||
|
$slide.removeAttr('tabindex'); // ← 確保 li 本身沒有 tabindex
|
||||||
|
$slide.find('a, button, input, [tabindex]').attr('tabindex', '0');
|
||||||
|
} else {
|
||||||
|
// 隱藏中的投影片:徹底隔離
|
||||||
|
$slide.attr('aria-hidden', 'true');
|
||||||
|
$slide.removeAttr('tabindex');
|
||||||
|
$slide.find('a, button, input, [tabindex]').attr('tabindex', '-1');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- 防鎖死邊界處理 (Shift + Tab) ---
|
||||||
|
var $container = $el.closest('.w-annc, .widget-link_wrapper, .widget-link');
|
||||||
|
var $prevBtn = $container.find('.btn-left, .prev-button');
|
||||||
|
|
||||||
|
$el.find('.cycle-slide-active a, .cycle-slide-active button').first()
|
||||||
|
.off('keydown.a11y').on('keydown.a11y', function(e) {
|
||||||
|
if (e.keyCode === 9 && e.shiftKey) {
|
||||||
|
if ($prevBtn.length) {
|
||||||
|
e.preventDefault();
|
||||||
|
$prevBtn.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 針對 widget-link 非語意化標籤 (如 i 標籤當按鈕) 的無障礙補強
|
||||||
|
*/
|
||||||
|
function refreshCycleA11y($el) {
|
||||||
|
var $items = $el.find('.w-annc__item, .widget-link__item, [class*="cycle-slide"]');
|
||||||
|
|
||||||
|
$items.each(function() {
|
||||||
|
var $slide = $(this);
|
||||||
|
var isActive = $slide.hasClass('cycle-slide-active');
|
||||||
|
|
||||||
|
if (isActive) {
|
||||||
|
// ✅ li 只設 aria-hidden,不加 tabindex
|
||||||
|
$slide.attr('aria-hidden', 'false');
|
||||||
|
$slide.removeAttr('tabindex'); // ← 確保 li 本身沒有 tabindex
|
||||||
|
$slide.find('a, button, input, [tabindex]').attr('tabindex', '0');
|
||||||
|
} else {
|
||||||
|
// 隱藏中的投影片:徹底隔離
|
||||||
|
$slide.attr('aria-hidden', 'true');
|
||||||
|
$slide.removeAttr('tabindex');
|
||||||
|
$slide.find('a, button, input, [tabindex]').attr('tabindex', '-1');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// --- 防鎖死邊界處理 (Shift + Tab) ---
|
||||||
|
var $container = $el.closest('.w-annc, .widget-link_wrapper, .widget-link');
|
||||||
|
var $prevBtn = $container.find('.btn-left, .prev-button');
|
||||||
|
|
||||||
|
$el.find('.cycle-slide-active a, .cycle-slide-active button').first()
|
||||||
|
.off('keydown.a11y').on('keydown.a11y', function(e) {
|
||||||
|
if (e.keyCode === 9 && e.shiftKey) {
|
||||||
|
if ($prevBtn.length) {
|
||||||
|
e.preventDefault();
|
||||||
|
$prevBtn.focus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 輔助函式:切換後更新 A11y 狀態並鎖定焦點
|
||||||
|
function triggerPostUpdate($el, $activeBtn) {
|
||||||
|
$el.one('cycle-after', function() {
|
||||||
|
setTimeout(function() {
|
||||||
|
refreshCycleA11y($el);
|
||||||
|
$activeBtn.focus();
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 舊有按鈕事件相容與整合
|
||||||
|
*/
|
||||||
|
$(document).on('keydown', '.btn-right, .btn-left', function(e) {
|
||||||
|
if (e.keyCode === 13) {
|
||||||
|
var $btn = $(this);
|
||||||
|
var $el = $btn.closest('.w-annc').find('.cycle-slideshow');
|
||||||
|
triggerPostUpdate($el, $btn);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 綁定 Cycle2 核心事件
|
||||||
|
*/
|
||||||
|
$allSlideshows.on('cycle-initialized cycle-after', function() {
|
||||||
|
var $this = $(this);
|
||||||
|
setTimeout(function() {
|
||||||
|
refreshCycleA11y($this);
|
||||||
|
}, 300);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化執行
|
||||||
|
patchWidgetLinkElements();
|
||||||
|
|
||||||
|
$allSlideshows.each(function() {
|
||||||
|
var $this = $(this);
|
||||||
|
setTimeout(function() {
|
||||||
|
refreshCycleA11y($this);
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
//post
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
$('iframe.twitter-share-button, iframe.twitter-tweet-button').each(function () {
|
$('iframe.twitter-share-button, iframe.twitter-tweet-button').each(function () {
|
||||||
|
|
@ -3041,56 +3245,53 @@ $(document).ready(function () {
|
||||||
}, 1500);
|
}, 1500);
|
||||||
});
|
});
|
||||||
$(function() {
|
$(function() {
|
||||||
function fixAccordionA11y() {
|
function bindIframeFocus() {
|
||||||
// === 1. 核心邏輯:修正可展開/收合開關的 4.1.2 成功準則 ===
|
var $iframe = $('.twitter-share-button');
|
||||||
// 尋找所有帶有 data-toggle="collapse" 的連結或按鈕
|
if ($iframe.length === 0) return;
|
||||||
$('[data-toggle="collapse"]').each(function() {
|
|
||||||
var $trigger = $(this);
|
|
||||||
var targetId = $trigger.attr('href') || $trigger.attr('data-target');
|
|
||||||
|
|
||||||
if (!targetId || targetId.indexOf('#') !== 0) return; // 確保有明確的 ID 目標
|
$iframe.each(function() {
|
||||||
|
var $wrap = $(this).closest('.tw-share-button');
|
||||||
|
|
||||||
var $targetPanel = $(targetId);
|
// 讓外層可以被 tab 到並顯示焦點框
|
||||||
|
$wrap.attr('tabindex', '-1');
|
||||||
|
|
||||||
// 1a. 暴露名稱與角色 (Role)
|
$(window).on('blur.twitterFocus', function() {
|
||||||
$trigger.attr({
|
setTimeout(function() {
|
||||||
'role': 'button',
|
if (document.activeElement &&
|
||||||
'aria-controls': targetId.replace('#', '') // 建立關聯,移除 # 號
|
$(document.activeElement).hasClass('twitter-share-button')) {
|
||||||
|
$wrap.css({
|
||||||
|
'outline': '3px solid #005fcc',
|
||||||
|
'outline-offset': '2px',
|
||||||
|
'border-radius': '2px'
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
// 1b. 設定初始的「值與狀態」 (Value / State)
|
$(window).on('focus.twitterFocus', function() {
|
||||||
// 檢查目標面板目前有沒有 Bootstrap 的展開樣式 "in"(或 "show")
|
$wrap.css({
|
||||||
var isExpanded = $targetPanel.hasClass('in') || $targetPanel.hasClass('show');
|
'outline': '',
|
||||||
$trigger.attr('aria-expanded', isExpanded ? 'true' : 'false');
|
'outline-offset': ''
|
||||||
|
|
||||||
// 1c. 強化視覺說明的 title(相容現有 title)
|
|
||||||
var currentTitle = $trigger.attr('title') || $trigger.text().trim();
|
|
||||||
if (currentTitle.indexOf('展開/收合') === -1) {
|
|
||||||
$trigger.attr('title', currentTitle + ' (點擊展開/收合)');
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1d. 面板本體也補上無障礙語意區塊 (Region)
|
|
||||||
$targetPanel.attr({
|
|
||||||
'role': 'region',
|
|
||||||
'aria-labelledby': $trigger.attr('id') || ''
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// === 2. 動態通知:變更狀態時即時通知螢幕閱讀器 (EV1120200) ===
|
// 用 MutationObserver 等 iframe 被 Twitter script 插入後才綁定
|
||||||
// 監聽 Bootstrap Collapse 的原生切換事件,不論是滑鼠點擊或鍵盤 Enter 都支援
|
var observer = new MutationObserver(function(mutations) {
|
||||||
$(document).on('shown.bs.collapse', '.panel-collapse, .collapse', function (e) {
|
if ($('.twitter-share-button').length > 0) {
|
||||||
// 當面板成功「展開」後
|
bindIframeFocus();
|
||||||
var targetId = '#' + $(e.target).attr('id');
|
observer.disconnect(); // 綁定成功後停止監聽
|
||||||
$('[href="' + targetId + '"], [data-target="' + targetId + '"]').attr('aria-expanded', 'true');
|
|
||||||
}).on('hidden.bs.collapse', '.panel-collapse, .collapse', function (e) {
|
|
||||||
// 當面板成功「收合」後
|
|
||||||
var targetId = '#' + $(e.target).attr('id');
|
|
||||||
$('[href="' + targetId + '"], [data-target="' + targetId + '"]').attr('aria-expanded', 'false');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 執行無障礙自動修正功能
|
observer.observe(document.body, {
|
||||||
fixAccordionA11y();
|
childList: true,
|
||||||
|
subtree: true
|
||||||
|
});
|
||||||
|
|
||||||
|
// 保險:2秒後強制執行一次
|
||||||
|
setTimeout(bindIframeFocus, 1000);
|
||||||
});
|
});
|
||||||
//orbitbarlogo無障礙
|
//orbitbarlogo無障礙
|
||||||
$(function() {
|
$(function() {
|
||||||
|
|
@ -3265,7 +3466,6 @@ function fixSearchInputA11y() {
|
||||||
$input.attr('title', label);
|
$input.attr('title', label);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
fixSortLinkA11y();
|
fixSortLinkA11y();
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
|
||||||
.fa-classic, .fa-regular, .fa-solid, .far, .fas ,.fa{
|
.fa-classic, .fa-regular, .fa-solid, .far, .fas ,.fa{
|
||||||
font-family: var(--fa-style-family, "FontAwesome");
|
font-family: "FontAwesome";
|
||||||
}
|
}
|
||||||
#orbit-bar .orbit-bar-inner > label:focus, #orbit-bar .orbit-bar-inner > label.focus{
|
#orbit-bar .orbit-bar-inner > label:focus, #orbit-bar .orbit-bar-inner > label.focus{
|
||||||
.orbit-bar-search-sign-language{
|
.orbit-bar-search-sign-language{
|
||||||
|
|
@ -26,16 +26,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
label[for="open-orbit-login"] {
|
// label[for="open-orbit-login"] {
|
||||||
@media(max-width:768px){
|
// @media(max-width:768px){
|
||||||
display: none!important;
|
// display: none!important;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
[accesskey="U"],[accesskey="W"]{
|
// [accesskey="U"],[accesskey="W"]{
|
||||||
@media(max-width:768px){
|
// @media(max-width:768px){
|
||||||
color: #666!important;
|
// color: #666!important;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
.orbit-bar-inner{
|
.orbit-bar-inner{
|
||||||
[accesskey="U"]{
|
[accesskey="U"]{
|
||||||
height: 40px;
|
height: 40px;
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,11 @@ caption{
|
||||||
|
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
.line-it-button{
|
||||||
|
.label{
|
||||||
|
color: #333!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
.col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9{
|
.col-lg-1, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-md-1, .col-md-10, .col-md-11, .col-md-12, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-sm-1, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-xs-1, .col-xs-10, .col-xs-11, .col-xs-12, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9{
|
||||||
@media(max-width: $screen-xs){
|
@media(max-width: $screen-xs){
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
|
||||||
|
|
@ -30,9 +30,11 @@ ul.button-mid{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ul.button-mid{
|
.button-mid {
|
||||||
margin:0;
|
position: absolute;
|
||||||
z-index: 201;
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
top: 50%;
|
||||||
}
|
}
|
||||||
.banner-pager .active-slide button{
|
.banner-pager .active-slide button{
|
||||||
background: $theme-color-second!important;
|
background: $theme-color-second!important;
|
||||||
|
|
|
||||||
|
|
@ -2680,12 +2680,6 @@ span.i-annc__postdate {
|
||||||
.i-annc__entry-title {
|
.i-annc__entry-title {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-line-clamp: 2;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
// clear: both;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.i-annc__title {
|
.i-annc__title {
|
||||||
|
|
@ -2693,6 +2687,11 @@ span.i-annc__postdate {
|
||||||
color: $theme-color-main;
|
color: $theme-color-main;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
@extend .i-title;
|
@extend .i-title;
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $theme-color-second;
|
color: $theme-color-second;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
@charset "utf-8";
|
@charset "utf-8";
|
||||||
|
|
||||||
@import "../initial";
|
@import "../initial";
|
||||||
|
.widget-link{
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
@keyframes shine{
|
@keyframes shine{
|
||||||
0% {
|
0% {
|
||||||
left: -40%;
|
left: -40%;
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,9 @@
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="w-ba-banner__pager-2 banner-pager banner_caption_{{subpart-id}}"></ul>
|
<div class="w-ad-banner__pager-2 w-ba-banner__caption banner-pager banner_caption_{{subpart-id}}" data-list="images" data-level="0">
|
||||||
|
<li><button title="Slide {{slide_number}}" aria-label="Pager"><span style="display: none;">Slide {{slide_number}}</span></button></li>
|
||||||
|
</div>
|
||||||
<ul class="controlplay" role="radiogroup" aria-label="播放控制選項">
|
<ul class="controlplay" role="radiogroup" aria-label="播放控制選項">
|
||||||
<a role="radio" aria-checked="true" href="javascript:;" class="resume-slide active" title="繼續播放" aria-label="繼續播放" aria-live="assertive">
|
<a role="radio" aria-checked="true" href="javascript:;" class="resume-slide active" title="繼續播放" aria-label="繼續播放" aria-live="assertive">
|
||||||
<i aria-hidden="true"></i>
|
<i aria-hidden="true"></i>
|
||||||
|
|
|
||||||
|
|
@ -5,29 +5,27 @@
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="widget-link_wrapper">
|
<div class="widget-link_wrapper">
|
||||||
<ul class="cycle-slideshow widget-content" style="margin: 0em 3.125em;"
|
<div class="cycle-slideshow widget-content" style="margin: 0em 3.125em;"
|
||||||
data-level="0" data-list="web_link" data-cycle-slides="> li"
|
data-level="0" data-list="web_link" data-cycle-slides="> li"
|
||||||
data-cycle-fx="carousel" data-cycle-timeout="0" data-cycle-carousel-visible="1"
|
data-cycle-fx="carousel" data-cycle-timeout="0" data-cycle-carousel-visible="1"
|
||||||
data-cycle-carousel-rwd-json="{768: 1}"
|
data-cycle-carousel-rwd-json="{768: 1}"
|
||||||
data-cycle-pause-on-hover="true" data-cycle-log="false" data-cycle-carousel-fluid="true">
|
data-cycle-pause-on-hover="true" data-cycle-log="false" data-cycle-carousel-fluid="true">
|
||||||
<li class="widget-link__item">
|
<li class="widget-link__item">
|
||||||
<a href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
|
<a href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
|
||||||
<div class="liWrapper">
|
<div class="liWrapper">
|
||||||
<img class="widget-link__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}"><br />
|
<img class="widget-link__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}"><br>
|
||||||
</div>
|
</div>
|
||||||
<div class="widget-content-title">{{title}}</div>
|
<div class="widget-content-title">{{title}}</div>
|
||||||
</a>
|
</a>
|
||||||
</ul>
|
</li>
|
||||||
</div>
|
</div>
|
||||||
<ul class="button-mid">
|
<ul class="button-mid">
|
||||||
<i class="fa fa-angle-left prev-button" aria-label="<%= I18n.t("ad_banner.prev") %>"></i>
|
<i class="fa fa-angle-left prev-button" aria-label="<%= I18n.t("ad_banner.prev") %>"></i>
|
||||||
<i class="fa fa-angle-right next-button" aria-label="<%= I18n.t("ad_banner.next") %>"></i>
|
<i class="fa fa-angle-right next-button" aria-label="<%= I18n.t("ad_banner.next") %>"></i>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
$('[data-subpart-id="{{subpart-id}}"] .next-button').click(function(){
|
$('[data-subpart-id="{{subpart-id}}"] .next-button').click(function(){
|
||||||
$(this).parent("ul").siblings('.widget-content').cycle("next");
|
$(this).parent("ul").siblings('.widget-content').cycle("next");
|
||||||
|
|
@ -37,16 +35,18 @@
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
.widget-link_wrapper{
|
.widget-link_wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.widget-link.widget-4 .button-mid{
|
.widget-link.widget-12 .button-mid,
|
||||||
|
.widget-link.widget-4 .button-mid {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 0;
|
height: 0;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
}
|
}
|
||||||
.widget-link.widget-4 .button-mid .fa{
|
.widget-link.widget-12 .button-mid .fa,
|
||||||
cursor: pointer;
|
.widget-link.widget-4 .button-mid .fa {
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
<div class="link-img-wrap{{display_image}}">
|
<div class="link-img-wrap{{display_image}}">
|
||||||
<img src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
|
<img src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
|
||||||
</div>
|
</div>
|
||||||
<a class="widget-content-title" href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">{{title}}</a>
|
<a class="widget-content-title" href="{{link_to_show}}" target="{{target}}" title="{{title_text}}" onclick="{{onclick}}">{{title}}</a>
|
||||||
<span data-list="statuses" data-level="1">
|
<span data-list="statuses" data-level="1">
|
||||||
<span class="label status {{status-class}}">{{status}}</span>
|
<span class="label status {{status-class}}">{{status}}</span>
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue