This commit is contained in:
ken 2026-09-08 20:16:22 +08:00
parent 4a1d6dfc3d
commit 8eb35ac5a6
6 changed files with 213 additions and 112 deletions

View File

@ -515,20 +515,28 @@
}); });
//播放驗證碼語音 //播放驗證碼語音
$(function () { $(function () {
$('.ask-question') var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase();
.find('.controls button.fas.fa-volume-up') var isEn = pageLang.startsWith('en');
.each(function () { var label = isEn ? 'Play Captcha Voice' : '播放驗證碼語音';
const $btn = $(this);
// 已經補過就不重複處理 $('.ask-question')
if ($btn.attr('aria-label')) return; .find('.controls button.fas.fa-volume-up')
.each(function () {
var $btn = $(this);
$btn.attr({ $btn.attr({
'aria-label': '播放驗證碼語音', 'aria-label': label,
'aria-controls': 'captcha_audio', 'title': label,
'role': 'button' 'aria-controls': 'captcha_audio',
}); 'role': 'button'
}); });
// ✅ 同步更新 sr-only 文字(若有)
var $sr = $btn.find('.sr-only');
if ($sr.length > 0) {
$sr.text(label);
}
});
}); });
//刪除td的id //刪除td的id
@ -2119,28 +2127,68 @@ $(document).ready(function () {
//rucaptcha-image //rucaptcha-image
$(document).ready(function () { $(document).ready(function () {
// >>> 修正:先確認頁面上真的有驗證碼圖片,再往下執行,避免沒有驗證碼的頁面也發出多餘的 wav 請求 function fixCaptchaImgA11y() {
if ($('.rucaptcha-image').length) { setTimeout(function () {
$('.rucaptcha-image').removeAttr('onload'); // ✅ 先確認頁面上真的有驗證碼圖片,再往下執行
// 檢查是否已插入過 if (!$('.rucaptcha-image').length) return;
if (!$('#captcha_audio').length) {
const audioButton = $(` var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase();
<button var isEn = pageLang.startsWith('en');
title="播放驗證碼語音"
type="button" var i18n = {
onclick="document.getElementById('captcha_audio').play();" alt: isEn ? 'Captcha image, click to refresh' : '驗證碼圖片,點擊可更換',
class="fas fa-volume-up" title: isEn ? 'Captcha image, click to refresh' : '驗證碼圖片,點擊可更換',
aria-label="播放驗證碼語音" label: isEn ? 'Click to refresh captcha' : '點擊更換驗證碼',
role="button" audioBtn: isEn ? 'Play captcha audio' : '播放驗證碼語音',
style="font-size: 1.5em; color: #333; cursor: pointer; border: 2px solid #333; padding: 0.2em;"> audioSrc: isEn ? '/rucaptcha/?format=wav&locale=en' : '/rucaptcha/?format=wav&locale=zh_tw'
<span class="sr-only">播放驗證碼語音</span> };
</button>
`); var $captchaImg = $('.rucaptcha-image');
const audio = $('<audio id="captcha_audio" src="/rucaptcha/?format=wav&amp;locale=zh_tw"></audio>');
$('.rucaptcha-image').after(audioButton, audio); // ✅ 移除 onload
} $captchaImg.removeAttr('onload');
// ✅ 補上有意義的 alt、role、tabindex、title
$captchaImg.attr({
'alt': i18n.alt,
'title': i18n.title,
'role': 'button',
'tabindex': '0',
'aria-label': i18n.label
});
// ✅ Enter / Space 觸發更換驗證碼
$captchaImg.off('keydown.captchaA11y').on('keydown.captchaA11y', function (e) {
if (e.which === 13 || e.which === 32) {
e.preventDefault();
$(this).trigger('click');
}
});
// ✅ 插入語音按鈕和 audio若還沒插入過
if (!$('#captcha_audio').length) {
var $audioButton = $(
'<button ' +
'title="' + i18n.audioBtn + '" ' +
'type="button" ' +
'onclick="document.getElementById(\'captcha_audio\').play();" ' +
'class="fas fa-volume-up" ' +
'aria-label="' + i18n.audioBtn + '" ' +
'role="button" ' +
'style="font-size: 1.5em; color: #333; cursor: pointer; border: 2px solid #333; padding: 0.2em;">' +
'<span class="sr-only">' + i18n.audioBtn + '</span>' +
'</button>'
);
var $audio = $('<audio id="captcha_audio" src="' + i18n.audioSrc + '"></audio>');
$captchaImg.after($audioButton, $audio);
}
}, 500);
} }
// <<< 修正結束
fixCaptchaImgA11y();
}); });
//萬用表格searchbtn2 //萬用表格searchbtn2
@ -3316,66 +3364,67 @@ $(function() {
}, 200); }, 200);
}); });
}); });
$(function() { //選單
function fixNavDropdownKeyboard() { // $(function() {
setTimeout(function() { // function fixNavDropdownKeyboard() {
// ✅ 找所有有子選單的父層連結 // setTimeout(function() {
$('#main-nav > li > a[aria-haspopup="true"]').each(function() { // // ✅ 找所有有子選單的父層連結
var $parentLink = $(this); // $('#main-nav > li > a[aria-haspopup="true"]').each(function() {
var $submenu = $parentLink.next('ul'); // var $parentLink = $(this);
if ($submenu.length === 0) return; // var $submenu = $parentLink.next('ul');
// if ($submenu.length === 0) return;
$parentLink.off('keydown.navDropdown').on('keydown.navDropdown', function(e) { // $parentLink.off('keydown.navDropdown').on('keydown.navDropdown', function(e) {
// ✅ Enter 鍵:若選單已展開則收合,未展開則展開(不跳頁) // // ✅ Enter 鍵:若選單已展開則收合,未展開則展開(不跳頁)
if (e.which === 13) { // if (e.which === 13) {
var isExpanded = $parentLink.attr('aria-expanded') === 'true'; // var isExpanded = $parentLink.attr('aria-expanded') === 'true';
if (isExpanded) { // if (isExpanded) {
e.preventDefault(); // ✅ 阻止跳頁 // e.preventDefault(); // ✅ 阻止跳頁
$parentLink.attr('aria-expanded', 'false'); // $parentLink.attr('aria-expanded', 'false');
$submenu.removeClass('show'); // $submenu.removeClass('show');
} // }
// 未展開時讓原本的 hover/focus 展開邏輯處理,不攔截 // // 未展開時讓原本的 hover/focus 展開邏輯處理,不攔截
} // }
// ✅ Escape 鍵收合 // // ✅ Escape 鍵收合
if (e.which === 27) { // if (e.which === 27) {
$parentLink.attr('aria-expanded', 'false'); // $parentLink.attr('aria-expanded', 'false');
$submenu.removeClass('show'); // $submenu.removeClass('show');
$parentLink.focus(); // $parentLink.focus();
} // }
}); // });
}); // });
// ✅ 二層子選單同樣處理 // // ✅ 二層子選單同樣處理
$('#main-nav li > a[aria-haspopup="true"]').filter(function() { // $('#main-nav li > a[aria-haspopup="true"]').filter(function() {
return $(this).closest('ul').hasClass('modules-menu-level-1'); // return $(this).closest('ul').hasClass('modules-menu-level-1');
}).each(function() { // }).each(function() {
var $parentLink = $(this); // var $parentLink = $(this);
var $submenu = $parentLink.next('ul'); // var $submenu = $parentLink.next('ul');
if ($submenu.length === 0) return; // if ($submenu.length === 0) return;
$parentLink.off('keydown.navDropdown2').on('keydown.navDropdown2', function(e) { // $parentLink.off('keydown.navDropdown2').on('keydown.navDropdown2', function(e) {
if (e.which === 13) { // if (e.which === 13) {
var isExpanded = $parentLink.attr('aria-expanded') === 'true'; // var isExpanded = $parentLink.attr('aria-expanded') === 'true';
if (isExpanded) { // if (isExpanded) {
e.preventDefault(); // e.preventDefault();
$parentLink.attr('aria-expanded', 'false'); // $parentLink.attr('aria-expanded', 'false');
$submenu.removeClass('show'); // $submenu.removeClass('show');
} // }
} // }
if (e.which === 27) { // if (e.which === 27) {
$parentLink.attr('aria-expanded', 'false'); // $parentLink.attr('aria-expanded', 'false');
$submenu.removeClass('show'); // $submenu.removeClass('show');
$parentLink.focus(); // $parentLink.focus();
} // }
}); // });
}); // });
}, 500); // }, 500);
} // }
fixNavDropdownKeyboard(); // fixNavDropdownKeyboard();
}); // });
// 執行 member等高計算目前改用flexbox故mark掉 by ika 20160105 // 執行 member等高計算目前改用flexbox故mark掉 by ika 20160105
// $(window).load(function() { // $(window).load(function() {
// if ($('.index-member-3').length && $(window).width() > 992) { // if ($('.index-member-3').length && $(window).width() > 992) {
@ -3461,4 +3510,59 @@ $(function() {
fixBannerA11yByLang(); fixBannerA11yByLang();
}); });
//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();
});
}(jQuery, window)); }(jQuery, window));

View File

@ -217,6 +217,6 @@ img{
// overflow-x: auto; // overflow-x: auto;
// } // }
// } // }
*[data-pp]>.editmode-ps>a, .admin-subpart-area .content>.editmode-ps>a{ input[type=checkbox]:focus {
position: !important; outline: 0.3125em auto -webkit-focus-ring-color;
} }

View File

@ -81,13 +81,7 @@
</div> </div>
<div class="contentwrap2"> <div class="contentwrap2">
<div class="marqueeken">
<div class="scroll">
<div class="text1">
NATIONAL FORMOSA UNIVERSITY
</div>
</div>
</div>
<div class="layout-content-inner container"> <div class="layout-content-inner container">
<div class="column row"> <div class="column row">
<section class="two-column col-sm-9" data-pp="39"></section> <section class="two-column col-sm-9" data-pp="39"></section>

View File

@ -47,20 +47,23 @@
</ul> </ul>
</div> </div>
<script> <script>
var flag = 1; $('[data-subpart-id="{{subpart-id}}"] .pause-slide').click(function(){
$('.pause-slide').click(function(){ $(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle('pause');
$(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle('pause'); $(this).addClass('active')
}); $(this).parents('.controlplay').eq(0).find('.resume-slide').removeClass('active')
$('.resume-slide').click(function(){ });
$(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle('resume'); $('[data-subpart-id="{{subpart-id}}"] .resume-slide').click(function(){
}); $(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle('resume');
$('.next-button').off('click').on('click',function(){ $(this).addClass('active')
$(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle("next"); $(this).parents('.controlplay').eq(0).find('.pause-slide').removeClass('active')
});
$('[data-subpart-id="{{subpart-id}}"] .next-button').click(function(){
$(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle("next");
}) })
$('.prev-button').off('click').on('click',function(){ $('[data-subpart-id="{{subpart-id}}"] .prev-button').click(function(){
$(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle("prev"); $(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle("prev");
}); });
/* 修正點:處理 Pager 無障礙朗讀文字 */ /* 修正點:處理 Pager 無障礙朗讀文字 */
$('.cycle-slideshow').on('cycle-post-initialize', function(event, optionHash) { $('.cycle-slideshow').on('cycle-post-initialize', function(event, optionHash) {
var $container = $(this).closest('.w-ba-banner'); var $container = $(this).closest('.w-ba-banner');

View File

@ -4,7 +4,7 @@
</h3> </h3>
<ul class="list-unstyled" data-list="web_link" data-level="0"> <ul class="list-unstyled" data-list="web_link" data-level="0">
<li class="index-content"> <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}}"> <div class="link-img-wrap{{display_image}}">
<img src="{{img_src}}" alt="{{img_description}}"> <img src="{{img_src}}" alt="{{img_description}}">
</div> </div>

View File

@ -4,7 +4,7 @@
</h3> </h3>
<ul class="list-unstyled" data-list="web_link" data-level="0"> <ul class="list-unstyled" data-list="web_link" data-level="0">
<li class="index-content col-md-4 col-sm-4"> <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}}"> <div class="link-img-wrap{{display_image}}">
<img src="{{img_src}}" alt="{{img_description}}"> <img src="{{img_src}}" alt="{{img_description}}">
</div> </div>