This commit is contained in:
ken 2026-09-08 12:33:18 +08:00
parent 091f55d25a
commit d9a416d9c8
15 changed files with 364 additions and 61 deletions

View File

@ -532,20 +532,28 @@ $(function () {
});
//播放驗證碼語音
$(function () {
$('.ask-question')
.find('.controls button.fas.fa-volume-up')
.each(function () {
const $btn = $(this);
var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase();
var isEn = pageLang.startsWith('en');
var label = isEn ? 'Play Captcha Voice' : '播放驗證碼語音';
// 已經補過就不重複處理
if ($btn.attr('aria-label')) return;
$('.ask-question')
.find('.controls button.fas.fa-volume-up')
.each(function () {
var $btn = $(this);
$btn.attr({
'aria-label': '播放驗證碼語音',
'aria-controls': 'captcha_audio',
'role': 'button'
});
});
$btn.attr({
'aria-label': label,
'title': label,
'aria-controls': 'captcha_audio',
'role': 'button'
});
// ✅ 同步更新 sr-only 文字(若有)
var $sr = $btn.find('.sr-only');
if ($sr.length > 0) {
$sr.text(label);
}
});
});
//刪除td的id
@ -916,7 +924,7 @@ $(function () {
var isLinkImage = $parentA.length > 0 && $parentA.text().replace(/\u00a0/g, '').trim() === "";
// --- 1. 處理「裝飾性圖片」標註 ---
if (currentAlt === "announcement image" || currentAlt === "裝飾圖片" || currentTitle === "裝飾圖片" || currentAlt === "這是一張圖片" || currentTitle === "這是一張圖片") {
if (currentAlt === "announcement image" || currentAlt === "裝飾圖片" || currentTitle === "裝飾圖片" || currentAlt === "這是一張圖片" || currentTitle === "這是一張圖片"||currentAlt === "This is a image" ||currentTitle === "This is a image"){
$img.attr('alt', '');
$img.removeAttr('title');
return;
@ -3103,11 +3111,15 @@ $(document).ready(function () {
});
//post
$(document).ready(function () {
setTimeout(function () {
$('iframe.twitter-share-button, iframe.twitter-tweet-button').each(function () {
$(this).attr('title', '分享至 X 在新視窗開啟');
});
}, 1500);
setTimeout(function () {
var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase();
var isEn = pageLang.startsWith('en');
var title = isEn ? 'Share to X Open in new window' : '分享至 X 在新視窗開啟';
$('iframe.twitter-share-button, iframe.twitter-tweet-button').each(function () {
$(this).attr('title', title);
});
}, 1500);
});
$(function() {
function bindIframeFocus() {
@ -3334,13 +3346,141 @@ function fixSearchInputA11y() {
$input.attr('title', label);
});
}
$(document).ready(function () {
setTimeout(function () {
fixSortLinkA11y();
fixSearchInputA11y();
}, 500);
});
//萬用表格input
$(function() {
function fixUniversalSearchLabelA11y() {
setTimeout(function() {
var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase();
var isEn = pageLang.startsWith('en');
$('.universal-dropdown').each(function(index) {
var $dropdown = $(this);
var $input = $dropdown.find('input[type="text"], input[type="search"]').first();
if ($input.length === 0) return;
// ✅ 優先從 .universal-th-text 取欄位名稱
var labelText = $dropdown.closest('[class*="col-"]').find('.universal-th-text').first().text().trim();
// ✅ 備援
if (!labelText) {
labelText = ($input.attr('placeholder') || '').trim();
}
if (!labelText) {
labelText = isEn ? 'Search' : '搜尋';
}
// ✅ 補上唯一 id(若已有就沿用)
var inputId = $input.attr('id') || ('universal-search-input-' + index);
$input.attr('id', inputId);
// ✅ 更新 label 文字(移除舊的再插入新的)
$('label[for="' + inputId + '"]').remove();
$input.before('<label for="' + inputId + '" class="sr-only">' + labelText + '</label>');
// ✅ 同步 aria-label 和 title
$input.attr({
'aria-label': labelText,
'title': labelText
});
});
// ✅ 修正 submit 按鈕的無意義 title
$('.theadsearch2 button[type="submit"]').each(function() {
var $btn = $(this);
var btnText = $btn.text().trim() || $btn.attr('aria-label') || '';
if (btnText) {
$btn.attr('title', isEn ? btnText + ' Open in this window' : btnText + ' 在本視窗開啟');
}
});
}, 500);
}
fixUniversalSearchLabelA11y();
});
//萬用表格顯示狀態訊息
$(function() {
function fixSearchResultStatusA11y() {
setTimeout(function() {
var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase();
var isEn = pageLang.startsWith('en');
// ✅ 加上 role="status" live region(若還沒有的話)
if ($('#search-result-status').length === 0) {
$('body').append(
'<div id="search-result-status" role="status" aria-live="polite" aria-atomic="true" class="sr-only"></div>'
);
}
// ✅ 計算目前搜尋結果數量並通知
function announceResultCount() {
var $rows = $('.universal-table-show tbody tr:visible');
var count = $rows.length;
// ✅ 只取有值的欄位,且去除重複
var keywords = [];
$('input[name^="q["]').each(function() {
var val = $(this).val().trim();
if (val && keywords.indexOf(val) === -1) {
keywords.push(val);
}
});
var keyword = keywords.join(' ').trim();
var message = '';
if (isEn) {
message = keyword
? 'Search results for "' + keyword + '": ' + count + ' items found.'
: count + ' items found.';
} else {
message = keyword
? '搜尋「' + keyword + '」的結果:共找到 ' + count + ' 筆資料。'
: '共找到 ' + count + ' 筆資料。';
}
// ✅ 清空再設定,確保 aria-live 每次都觸發
$('#search-result-status').text('');
setTimeout(function() {
$('#search-result-status').text(message);
}, 100);
}
// ✅ 頁面載入時播報目前結果數
announceResultCount();
// ✅ 搜尋按鈕點擊後播報
$(document).on('click', '.theadsearch2 button[type="submit"], #search-submit', function() {
setTimeout(function() {
announceResultCount();
}, 1000);
});
// ✅ AJAX 結果更新時用 MutationObserver 監聽
var $tableBody = $('.universal-table-show tbody');
if ($tableBody.length > 0) {
var observer = new MutationObserver(function() {
setTimeout(function() {
announceResultCount();
}, 300);
});
observer.observe($tableBody[0], {
childList: true,
subtree: true
});
}
}, 800);
}
fixSearchResultStatusA11y();
});
setTimeout(function() {
$('.tdken').each(function() {
var $tr = $(this);
@ -3463,31 +3603,58 @@ $(document).ready(function () {
});
$(function() {
function fixSearchBtnNewWindowA11y() {
setTimeout(function() {
// ✅ 找所有 target="_blank" 的搜尋 form 裡的送出按鈕
$('form[target="_blank"] .btn-search').each(function() {
var $btn = $(this);
function fixVoicePlayerA11y() {
setTimeout(function() {
$('a.voice-player').each(function() {
var $a = $(this);
$btn.attr('aria-label', '全站搜尋 在新視窗開啟');
$btn.attr('title', '全站搜尋 在新視窗開啟');
// ✅ 移除「在本視窗開啟」的 title,因為這是播放按鈕不是連結
var currentTitle = ($a.attr('title') || '').trim();
if (currentTitle === '在本視窗開啟' || currentTitle === 'Open in this window') {
$a.removeAttr('title');
}
// ✅ 更新 sr-only 文字
var $sr = $btn.find('.sr-only');
if ($sr.length > 0) {
$sr.text('全站搜尋 在新視窗開啟');
} else {
$btn.append('<span class="sr-only">全站搜尋 在新視窗開啟</span>');
// ✅ 補上 role="button"
$a.attr('role', 'button');
// ✅ 補上 tabindex 確保可被 Tab 聚焦
if (!$a.attr('tabindex')) {
$a.attr('tabindex', '0');
}
// ✅ 補上 aria-pressed 初始狀態(未播放)
$a.attr('aria-pressed', 'false');
// ✅ Enter / Space 觸發點擊
$a.off('keydown.voiceA11y').on('keydown.voiceA11y', function(e) {
if (e.which === 13 || e.which === 32) {
e.preventDefault();
$(this).trigger('click');
}
});
// ✅ 同步修正搜尋 input 的 title
$('form[target="_blank"] .input-search').each(function() {
$(this).attr('title', '全站搜尋');
});
// ✅ 點擊時切換 aria-pressed 和圖示狀態
$a.off('click.voiceA11y').on('click.voiceA11y', function() {
var $btn = $(this);
var $icon = $btn.find('i.fa');
var isPlaying = $icon.hasClass('fa-pause');
}, 500);
}
if (isPlaying) {
$icon.removeClass('fa-pause').addClass('fa-play');
$btn.attr('aria-pressed', 'false');
} else {
$('a.voice-player').not($btn).each(function() {
$(this).find('i.fa').removeClass('fa-pause').addClass('fa-play');
$(this).attr('aria-pressed', 'false');
});
$icon.removeClass('fa-play').addClass('fa-pause');
$btn.attr('aria-pressed', 'true');
}
});
});
}, 500);
}
fixSearchBtnNewWindowA11y();
});
@ -3543,4 +3710,136 @@ $(function() {
fixVoicePlayerA11y();
});
//bannercontrolplay
$(function() {
function fixBannerPlayPauseA11y() {
setTimeout(function() {
var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase();
var isEn = pageLang.startsWith('en');
var i18n = {
resume: isEn ? 'Play' : '繼續播放',
pause: isEn ? 'Pause' : '暫停播放'
};
$('.w-ba-banner').each(function() {
var $banner = $(this);
var $controlplay = $banner.find('.controlplay');
// ✅ 把 radiogroup 改為一般容器
$controlplay.removeAttr('role aria-label');
// ✅ 繼續播放按鈕
var $resume = $banner.find('.resume-slide');
$resume
.attr('role', 'button')
.attr('aria-pressed', $resume.hasClass('active') ? 'true' : 'false')
.attr('aria-label', i18n.resume)
.attr('title', i18n.resume)
.removeAttr('aria-checked aria-live');
// ✅ 暫停播放按鈕
var $pause = $banner.find('.pause-slide');
$pause
.attr('role', 'button')
.attr('aria-pressed', $pause.hasClass('active') ? 'true' : 'false')
.attr('aria-label', i18n.pause)
.attr('title', i18n.pause)
.removeAttr('aria-checked aria-live');
// ✅ 點擊後同步 aria-pressed
$resume.off('click.bannerA11y').on('click.bannerA11y', function() {
$resume.attr('aria-pressed', 'true');
$pause.attr('aria-pressed', 'false');
});
$pause.off('click.bannerA11y').on('click.bannerA11y', function() {
$pause.attr('aria-pressed', 'true');
$resume.attr('aria-pressed', 'false');
});
});
}, 800);
}
fixBannerPlayPauseA11y();
});
//banner英文
$(function() {
function fixBannerA11yByLang() {
setTimeout(function() {
var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase();
var isEn = pageLang.startsWith('en');
var i18n = {
playControls: isEn ? 'Playback Controls' : '播放控制選項',
resume: isEn ? 'Play' : '繼續播放',
pause: isEn ? 'Pause' : '暫停播放',
prev: isEn ? 'Previous' : '上一張',
next: isEn ? 'Next' : '下一張',
slide: isEn ? 'Slide' : '第',
slideUnit: isEn ? '' : ' 張投影片'
};
$('.w-ba-banner').each(function() {
var $banner = $(this);
// ✅ 播放控制選項 radiogroup label
$banner.find('.controlplay').attr('aria-label', i18n.playControls);
// ✅ 繼續播放按鈕
$banner.find('.resume-slide').attr({
'aria-label': i18n.resume,
'title': i18n.resume
});
$banner.find('.resume-slide p').text(i18n.resume);
// ✅ 暫停播放按鈕
$banner.find('.pause-slide').attr({
'aria-label': i18n.pause,
'title': i18n.pause
});
$banner.find('.pause-slide p').text(i18n.pause);
// ✅ 上一張按鈕
$banner.find('.prev-button').attr('aria-label', i18n.prev);
// ✅ 下一張按鈕
$banner.find('.next-button').attr('aria-label', i18n.next);
// ✅ Pager 按鈕
var $slides = $banner.find('.w-ba-banner__slide');
$banner.find('.banner-pager button').each(function(index) {
var slideTitle = $slides.eq(index).data('cycle-title') || '';
var ariaLabel = isEn
? i18n.slide + ' ' + (index + 1) + (slideTitle ? ' ' + slideTitle : '')
: i18n.slide + (index + 1) + i18n.slideUnit + (slideTitle ? ' ' + slideTitle : '');
$(this).attr({
'aria-label': ariaLabel,
'title': ariaLabel
});
});
});
// ✅ Cycle2 初始化後也重新處理 Pager(因為 pager 是動態產生的)
$('.w-ba-banner .cycle-slideshow').on('cycle-post-initialize cycle-after', function() {
var $banner = $(this).closest('.w-ba-banner');
var $slides = $banner.find('.w-ba-banner__slide');
$banner.find('.banner-pager button').each(function(index) {
var slideTitle = $slides.eq(index).data('cycle-title') || '';
var ariaLabel = isEn
? i18n.slide + ' ' + (index + 1) + (slideTitle ? ' ' + slideTitle : '')
: i18n.slide + (index + 1) + i18n.slideUnit + (slideTitle ? ' ' + slideTitle : '');
$(this).attr({
'aria-label': ariaLabel,
'title': ariaLabel
});
});
});
}, 800);
}
fixBannerA11yByLang();
});
}(jQuery, window));

View File

@ -6,6 +6,11 @@
.fa-classic, .fa-regular, .fa-solid, .far, .fas ,.fa{
font-family: "FontAwesome";
}
li#language-li {
@media(max-width:767px){
display: none !important;
}
}
#orbit-bar .orbit-bar-inner > label:focus, #orbit-bar .orbit-bar-inner > label.focus{
.orbit-bar-search-sign-language{
display: block
@ -209,6 +214,6 @@ img{
// overflow-x: auto;
// }
// }
*[data-pp]>.editmode-ps>a, .admin-subpart-area .content>.editmode-ps>a{
position: !important;
}
input[type=checkbox]:focus {
outline: 0.3125em auto -webkit-focus-ring-color;
}

View File

@ -3,7 +3,7 @@
<ul class="i-annc__list row" data-level="0" data-list="announcements">
<li class="i-annc__item rotate0">
<div class="i-annc__img-wrap bullseye">
<a href="{{link_to_show}}" alt="{{img_description}}" title="{{img_description}}">
<a href="{{link_to_show}}" title="{{img_description}}">
<img class="i-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
</a>
</div>

View File

@ -2,9 +2,9 @@
<h3 class="i-annc__page-title"><span>{{page-title}}</span></h3>
<ul class="i-annc__list row" data-level="0" data-list="announcements">
<li class="i-annc__item col-md-3 col-sm-3">
<a href="{{link_to_show}}" alt="{{img_description}}" title="{{img_description}}">
<a href="{{link_to_show}}" title="{{img_description}}">
<div class="i-annc__img-wrap bullseye">
<img class="i-annc__img" src="{{img_src}}" alt="" title="{{img_description}}">
<img class="i-annc__img" src="{{img_src}}" alt="{{img_description}}">
</div>
<div class="i-annc__content-wrap">
<div class="i-annc__meta">

View File

@ -2,10 +2,10 @@
<h3 class="i-annc__page-title"><span>{{page-title}}</span></h3>
<ul class="i-annc__list" data-level="0" data-list="announcements">
<li class="i-annc__item row">
<a href="{{link_to_show}}" alt="{{img_description}}" title="{{img_description}}">
<a href="{{link_to_show}}" title="{{img_description}}">
<div class="i-annc__img-wrap col-sm-4">
<img class="i-annc__img" src="{{img_src}}" alt="" title="{{img_description}}">
<img class="i-annc__img" src="{{img_src}}" alt="{{img_description}}">
</div>
<div class="i-annc__content-wrap col-sm-8">

View File

@ -2,7 +2,7 @@
<h3 class="i-annc__page-title"><span>{{page-title}}</span></h3>
<ul class="i-annc__list" data-level="0" data-list="announcements">
<li class="i-annc__item row">
<a href="{{link_to_show}}" alt="{{img_description}}" title="{{img_description}}">
<a href="{{link_to_show}}" title="{{img_description}}">
<div class="i-annc__content-wrap col-sm-8">
<div class="i-annc__meta">
<span class="i-annc__status-wrap" data-list="statuses" data-level="1">
@ -23,7 +23,7 @@
<p class="i-annc__subtitle">{{subtitle}}</p>
</div>
<div class="i-annc__img-wrap col-sm-4">
<img class="i-annc__img" src="{{img_src}}" alt="" title="{{img_description}}">
<img class="i-annc__img" src="{{img_src}}" alt="{{img_description}}">
</div>
</a>
</li>

View File

@ -4,7 +4,7 @@
<li class="i-annc__item row">
<a href="{{link_to_show}}" title="{{img_description}}">
<div class="i-annc__img-wrap col-sm-4">
<img class="i-annc__img" src="{{img_src}}" alt="" title="{{img_description}}">
<img class="i-annc__img" src="{{img_src}}" alt="{{img_description}}">
</div>
<div class="i-annc__content-wrap col-sm-8">
<div class="i-annc__meta">

View File

@ -23,7 +23,7 @@
<p class="i-annc__subtitle">{{subtitle}}</p>
</div>
<div class="i-annc__img-wrap col-sm-4">
<img class="i-annc__img" src="{{img_src}}" alt="" title="{{img_description}}">
<img class="i-annc__img" src="{{img_src}}" alt="{{img_description}}">
</div>
</a>
</li>

View File

@ -4,7 +4,7 @@
<li class="i-annc__item col-md-4">
<a href="{{link_to_show}}" title="{{img_description}}">
<div class="i-annc__img-wrap bullseye" style="position:relative">
<img class="i-annc__img" src="{{img_src}}" alt="" title="{{img_description}}">
<img class="i-annc__img" src="{{img_src}}" alt="{{img_description}}">
</div>
<div class="i-annc__content-wrap">
<div class="i-annc__meta">

View File

@ -8,7 +8,7 @@
<div class="i-member-item-inner clearfix">
<div class="i-member-pic-wrap col-sm-3">
<a href="{{link_to_show}}" title="{{name}}">
<img class="i-member-pic img-thumbnail" src="{{image}}" title="{{name}}">
<img class="i-member-pic img-thumbnail" src="{{image}}" alt="{{name}}">
</a>
</div>
<div class="i-member-profile-data-wrap col-sm-9">

View File

@ -13,12 +13,11 @@
white-space: nowrap;
}
.universal-th-text{
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
white-space: normal;
}
white-space: pre !important;
}
.universal-dropdown-menu {
padding: 15px 18px;
white-space: nowrap;

View File

@ -13,12 +13,11 @@
white-space: nowrap;
}
.universal-th-text{
overflow: hidden;
display: -webkit-box;
-webkit-line-clamp: 2;
white-space: normal;
}
white-space: pre !important;
}
.universal-dropdown-menu {
padding: 15px 18px;
white-space: nowrap;

View File

@ -9,11 +9,12 @@
<img src="{{img_src}}" alt="{{img_description}}">
</div>
<div class="widget-content-title">
<a class="" href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">{{title}}</a>
<span>{{title}}</span>
<span data-list="statuses" data-level="1">
<span class="label status {{status-class}}">{{status}}</span>
</span>
</div>
</a>
</li>
</ul>
</div>

View File

@ -4,7 +4,7 @@
</h3>
<ul class="list-unstyled" data-list="web_link" data-level="0">
<li class="index-content">
<a class="index-content-title" href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
<a class="" href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
<div class="link-img-wrap{{display_image}}">
<img src="{{img_src}}" alt="{{img_description}}">
</div>

View File

@ -4,7 +4,7 @@
</h3>
<ul class="list-unstyled" data-list="web_link" data-level="0">
<li class="index-content col-md-4 col-sm-4">
<a class="index-content-title" href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
<a class="" href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
<div class="link-img-wrap{{display_image}}">
<img src="{{img_src}}" alt="{{img_description}}">
</div>