This commit is contained in:
ken 2026-08-07 12:13:08 +08:00
parent c9b96eea16
commit 6bd265047c
17 changed files with 201 additions and 138 deletions

View File

@ -1101,56 +1101,59 @@ $(function() {
}
}
// E. 重新計算標題 (關鍵邏輯:若 hasOriginalTitle 為真,則不進入此區塊)
if (!hasOriginalTitle) {
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 + imgAlt + " " + windowTask).trim());
$img.attr('alt', imgAlt);
}
else if (linkText !== "") {
if (fileExt !== "" || hasBadSymbol || currentTitle === "" || currentTitle.includes('/uploads/')) {
if (fileExt !== "") {
$a.attr('title', linkText + " ." + fileExt + " " + windowTask);
} else {
$a.attr('title', windowTask);
}
// E. 重新計算標題 (關鍵邏輯:若 hasOriginalTitle 為真,則不進入此區塊)
if (!hasOriginalTitle) {
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 + imgAlt + " " + windowTask).trim());
$img.attr('alt', imgAlt);
}
else if (linkText !== "") {
if (fileExt !== "" || hasBadSymbol || currentTitle === "" || currentTitle.includes('/uploads/')) {
if (fileExt !== "") {
$a.attr('title', linkText + " ." + fileExt + " " + windowTask);
} else {
$a.attr('title', windowTask);
}
}
}
}
// ✅ 符合 HM1240404Etitle 不應與連結文字或圖片 alt 重複
if (hasOriginalTitle && currentTitle !== "") {
var titleWithoutWindow = currentTitle
.replace('(在本視窗開啟)', '')
.replace('(在新視窗開啟)', '')
.replace('Open in this window', '')
.replace('Open in new window', '')
.replace('另開新視窗前往', '')
.replace('另開新視窗', '')
.trim();
// ✅ 符合 HM1240404Etitle 不應與連結文字或圖片 alt 重複
if (hasOriginalTitle && currentTitle !== "") {
var titleWithoutWindow = currentTitle
.replace('(在本視窗開啟)', '')
.replace('(在新視窗開啟)', '')
.replace('Open in this window', '')
.replace('Open in new window', '')
.replace('另開新視窗前往', '')
.replace('另開新視窗', '')
.trim();
// ✅ title 去掉開窗字串後,若與連結文字或圖片原始 alt 相同,則只保留開窗提示
if (
(titleWithoutWindow === linkText && linkText !== i18n.link) ||
(imgAltOriginal !== '' && titleWithoutWindow === imgAltOriginal)
) {
$a.attr('title', windowTask);
}
// ✅ 最終清理:若 title 出現空括號 () 則移除並補上正確開窗提示
var finalTitle = ($a.attr('title') || '').trim();
if (finalTitle.includes('()')) {
finalTitle = finalTitle.replace(/\(\)/g, '').trim();
$a.attr('title', finalTitle + ' ' + windowTask);
}
// ✅ title 去掉開窗字串後,若與連結文字或圖片原始 alt 相同,則只保留開窗提示
// ✅ 新增:若 linkText 包含副檔名且 title 也是同樣檔名,也只保留開窗提示
if (
(titleWithoutWindow === linkText && linkText !== i18n.link) ||
(imgAltOriginal !== '' && titleWithoutWindow === imgAltOriginal) ||
(fileExt !== '' && linkText.toLowerCase().endsWith('.' + fileExt) && titleWithoutWindow === linkText)
) {
$a.attr('title', windowTask);
return; // ✅ 加上 return避免繼續執行後面的清理邏輯造成二次污染
}
// ✅ 最終清理:若 title 出現空括號 () 則移除並補上正確開窗提示
var finalTitle = ($a.attr('title') || '').trim();
if (finalTitle.includes('()')) {
finalTitle = finalTitle.replace(/\(\)/g, '').trim();
$a.attr('title', finalTitle + ' ' + windowTask);
}
}
// F. 最終清理:移除冗餘 label避免螢幕閱讀器唸兩次
$a.removeAttr('aria-label');
});
@ -1184,6 +1187,47 @@ $(function() {
fixAccessibilityAll();
}, 800);
});
// 修正漢堡選單按鈕無障礙
$(function() {
function fixNavbarToggleA11y() {
var isEn = $('html').attr('lang') === 'en';
var label = isEn ? '開啟或關閉導覽選單' : '開啟或關閉導覽選單';
$('.navbar-toggle').each(function() {
var $btn = $(this);
// 修正 title
$btn.attr('title', label);
// 修正 sr-only 文字(原本是 "Toggle navigation"
var $sr = $btn.find('.sr-only');
if ($sr.length) {
$sr.text(label);
} else {
$btn.prepend('<span class="sr-only">' + label + '</span>');
}
// 補上 aria-label
$btn.attr('aria-label', label);
// 補上 aria-expanded依據目前是否展開
if (!$btn.attr('aria-expanded')) {
var isExpanded = !$btn.hasClass('collapsed');
$btn.attr('aria-expanded', isExpanded ? 'true' : 'false');
}
// 點擊時同步更新 aria-expanded
$btn.off('click.navA11y').on('click.navA11y', function() {
setTimeout(function() {
var isExpanded = !$('.navbar-toggle').hasClass('collapsed');
$('.navbar-toggle').attr('aria-expanded', isExpanded ? 'true' : 'false');
}, 50);
});
});
}
setTimeout(fixNavbarToggleA11y, 500);
});
$(function() {
@ -2313,7 +2357,7 @@ $(document).ready(function() {
if ($(window).width() <769) {
$('.modules-menu-level-0').after($('.header-nav'));
}else{
$('.navbar-header').before($('.header-nav'));
$('.navbar-header').after($('.header-nav'));
};
$('.sitemenu-vertical .sitemenu-dropdown-toggle').click(function(){
$('.sitemenu-vertical .dropdown-menu').slideToggle();
@ -2381,7 +2425,7 @@ $(document).ready(function() {
$('.modules-menu-level-0').after($('.header-nav'));
}else{
$('.navbar-header').before($('.header-nav'));
$('.navbar-header').after($('.header-nav'));
};
if ($(window).width() > 821) {
@ -3166,6 +3210,16 @@ $(document).ready(function () {
setTimeout(function() {
$('.internal-page .ad-banner-widget-0 .w-ad-banner__image').attr('alt', '');
}, 800);
setTimeout(function() {
var found = false;
$('.navbar-header a[accesskey="M"]').each(function() {
if (found) {
$(this).remove();
} else {
found = true;
}
});
}, 1000);
// 執行 member等高計算目前改用flexbox故mark掉 by ika 20160105
// $(window).load(function() {
// if ($('.index-member-3').length && $(window).width() > 992) {

View File

@ -18,6 +18,7 @@ a[accesskey] {
a[accesskey] {
position: relative!important;
margin-left: -0.9375em;
color: transparent !important;
color: transparent ;
float: left;
}
}

View File

@ -3,7 +3,7 @@
@import "variables";
.go-back-top {
background:#00000080;
background:#2760b0;
text-align: center;
padding: 0.625em 0.75em;
position: fixed;

View File

@ -6,7 +6,7 @@
z-index: 1;
clear: both;
color: #E4E4E4;
background: url(/assets/bg_footer.png) repeat #24436E;
background: url(/assets/bg_footer.png) repeat #183864;
position: relative;
padding: 2em 0;
color: $theme-color-main;

View File

@ -95,6 +95,9 @@
display: flex;
align-items: center;
justify-content: flex-end;
@media(max-width:768px){
width: 100%;
}
ul{
padding: 0;
}
@ -122,7 +125,7 @@
text-decoration: none;
padding:5px;
}
@media (min-width:1025px) {
position: relative;
}
@ -139,14 +142,6 @@
margin-top: 1em!important;
margin-bottom: 1em!important;
}
@media (min-width: 769px){
float: none!important;
}
// @media (max-width: $screen-sm) {
// width: 100%;
// display: flex;
// flex-flow: row-reverse;
// }
.navbar-brand {
line-height: 2.125em;
color: $theme-color-main;

View File

@ -2010,6 +2010,9 @@ a.w-annc__more.btn.btn-primary.pull-right {
text-align: center;
border-radius: 0;
background: #2f4877!important;
.en{
color: #f2f2f2!important;
}
}
.w-annc__more-wrap{
padding-right: 1em;

View File

@ -21,21 +21,23 @@
<div class="outdropdowns kenjohn">
<div class="dropdowns">
<div class="header-nav container no-print">
<a id="accesskey_top" accesskey="U" title="accesskey top" href="#" title="Toolbar">:::</a>
{{header-data}}
</div>
<div class="container navbar-header">
<a title="{{site_title_1}}" class="navbar-brand" href="{{home_link_1}}"><img class="site-logo" src="{{logo_url_1}}" alt="site-logo"></a>
<script>$(document).ready(function(){var url =$('.site-logo').eq(0).attr('src');if(url == "/assets/default-site-logo.png"){$('.navbar-brand').eq(0).remove();};if($('.navbar-brand').length == 2){$('.site-logo').css('height','auto')};$('.site-logo').eq(0).css('margin-right',0);$('.navbar-brand').css('padding-right',0)})</script>
<a title="{{site_title}}" class="navbar-brand" href="{{home_link}}"><img class="site-logo" src="{{logo_url}}" alt="site-logo"> {{site_name}}</a>
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#layout-navigation">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar icon-bar-top"></span>
<span class="icon-bar icon-bar-middle"></span>
<span class="icon-bar icon-bar-bottom"></span>
</button>
<div class="container">
<div class="navbar-header">
<a title="{{site_title_1}}" class="navbar-brand" href="{{home_link_1}}"><img class="site-logo" src="{{logo_url_1}}" alt="site-logo"></a>
<script>$(document).ready(function(){var url =$('.site-logo').eq(0).attr('src');if(url == "/assets/default-site-logo.png"){$('.navbar-brand').eq(0).remove();};if($('.navbar-brand').length == 2){$('.site-logo').css('height','auto')};$('.site-logo').eq(0).css('margin-right',0);$('.navbar-brand').css('padding-right',0)})</script>
<a title="{{site_title}}" class="navbar-brand" href="{{home_link}}"><img class="site-logo" src="{{logo_url}}" alt="site-logo"> {{site_name}}</a>
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#layout-navigation">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar icon-bar-top"></span>
<span class="icon-bar icon-bar-middle"></span>
<span class="icon-bar icon-bar-bottom"></span>
</button>
</div>
<div class="header-nav no-print">
<a id="accesskey_top" accesskey="U" title="accesskey top" href="#" title="Toolbar">:::</a>
{{header-data}}
</div>
</div>
<div class="collapse navbar-collapse modules-menu" id="layout-navigation">
<a id="accesskey_menu" title="accesskey menu" accesskey="M" href="#" title="Main menu">:::</a>
<%= render_menu %>

View File

@ -17,8 +17,7 @@
<ul class="i-archive-files-list" data-list="files" data-level="2">
<li>
<span class="description" style="clear: both;widivh: 100%;position: relative;display: block;">{{description}}</span>
<a href="{{file-url}}" class="i-archive-files-item" target="{{target}}" title="{{file-name}}">{{file-name}}</a>
<span class="label label-primary {{file-type}}">{{file-type}}</span>
<a href="{{file-url}}" class="i-archive-files-item" target="{{target}}" title="{{file-name}}">{{file-name}}<span class="label label-primary {{file-type}}">{{file-type}}</span></a>
</li>
</ul>
</div>

View File

@ -19,8 +19,7 @@
<ul class="i-archive-files-list" data-list="files" data-level="2">
<li>
<span class="description" style="clear: both;widivh: 100%;position: relative;display: block;">{{description}}</span>
<a href="{{file-url}}" class="i-archive-files-item" target="{{target}}" title="{{file-name}}">{{file-name}}</a>
<span class="label label-primary {{file-type}}">{{file-type}}</span>
<a href="{{file-url}}" class="i-archive-files-item" target="{{target}}" title="{{file-name}}">{{file-name}}<span class="label label-primary {{file-type}}">{{file-type}}</span></a>
</li>
</ul>
</div>

View File

@ -1,18 +1,14 @@
<div class="marquee-1" module="text_marquee" data-ps="">
<div class="marquee-1-controls">
<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">
<i aria-hidden="true"></i>
<p style="display: none;">繼續播放</p>
</a>
<a role="radio" aria-checked="false" href="javascript:;" class="pause-slide" title="暫停播放" aria-label="暫停播放" aria-live="assertive">
<i aria-hidden="true"></i>
<p style="display: none;">暫停播放</p>
</a>
</ul>
<div class="controlplay">
<button type="button" class="marquee-toggle-btn" title="暫停跑馬燈" aria-label="暫停跑馬燈" aria-pressed="false">
<i class="marquee-icon" aria-hidden="true"></i>
<span class="visually-hidden">暫停跑馬燈</span>
</button>
</div>
</div>
<ul class="marquee" data-level="0" data-list="texts" aria-live="polite" aria-atomic="true">
<ul class="marquee" data-level="0" data-list="texts" aria-live="polite" aria-atomic="true" aria-label="跑馬燈公告">
<li>{{content}}</li>
</ul>
</div>
@ -26,8 +22,7 @@
var isPaused = false;
var timer = null;
var $resumeBtn = main_div.find(".resume-slide");
var $pauseBtn = main_div.find(".pause-slide");
var $toggleBtn = main_div.find(".marquee-toggle-btn");
var $marquee = main_div.find("ul.marquee");
main_div.find("ul.marquee li").hide();
@ -39,7 +34,7 @@
current_text = (current_text > total_texts ? 0 : current_text);
last_text = (current_text === 0 ? total_texts : current_text - 1);
var speed = $(".marquee > li > a").eq(current_text).attr("speed") || 3000;
var speed = main_div.find(".marquee > li > a").eq(current_text).attr("speed") || 3000;
main_div.find("ul.marquee li").eq(last_text).slideUp(500);
main_div.find("ul.marquee li").eq(current_text).slideDown(500);
@ -52,30 +47,51 @@
function pause() {
isPaused = true;
clearTimeout(timer);
$pauseBtn.attr("aria-checked", "true").addClass("active");
$resumeBtn.attr("aria-checked", "false").removeClass("active");
// aria-live 暫停時設 off避免螢幕報讀繼續讀
$marquee.attr("aria-live", "off");
// 切換按鈕狀態aria-pressed="true" 表示目前已暫停
$toggleBtn
.attr("aria-pressed", "true")
.attr("aria-label", "繼續跑馬燈")
.attr("title", "繼續跑馬燈")
.find("span.visually-hidden").text("繼續跑馬燈");
$toggleBtn.addClass("is-paused");
// 暫停後讓目前顯示的 li 內連結可被 Tab
main_div.find("ul.marquee li").removeAttr("tabindex");
main_div.find("ul.marquee li:visible a").attr("tabindex", "0");
main_div.find("ul.marquee li:hidden a").attr("tabindex", "-1");
}
function resume() {
isPaused = false;
$resumeBtn.attr("aria-checked", "true").addClass("active");
$pauseBtn.attr("aria-checked", "false").removeClass("active");
$marquee.attr("aria-live", "polite");
var speed = $(".marquee > li > a").eq(current_text).attr("speed") || 3000;
// 切換按鈕狀態aria-pressed="false" 表示目前播放中
$toggleBtn
.attr("aria-pressed", "false")
.attr("aria-label", "暫停跑馬燈")
.attr("title", "暫停跑馬燈")
.find("span.visually-hidden").text("暫停跑馬燈");
$toggleBtn.removeClass("is-paused");
// 恢復播放li 內連結不在 Tab 順序
main_div.find("ul.marquee li").removeAttr("tabindex");
main_div.find("ul.marquee li a").attr("tabindex", "-1");
var speed = main_div.find(".marquee > li > a").eq(current_text).attr("speed") || 3000;
timer = setTimeout(textTransform, speed);
}
// 播放/暫停按鈕
$resumeBtn.on("click", function(e) {
// 單一切換按鈕
$toggleBtn.on("click keydown", function(e) {
if (e.type === "keydown" && e.keyCode !== 13 && e.keyCode !== 32) return;
e.preventDefault();
if (isPaused) resume();
});
$pauseBtn.on("click", function(e) {
e.preventDefault();
if (!isPaused) pause();
if (isPaused) {
resume();
} else {
pause();
}
});
// 焦點進入跑馬燈區域時自動暫停
@ -93,8 +109,8 @@
});
// 初始狀態:播放中
$resumeBtn.addClass("active").attr("aria-checked", "true");
$pauseBtn.attr("aria-checked", "false");
main_div.find("ul.marquee li").removeAttr("tabindex");
main_div.find("ul.marquee li a").attr("tabindex", "-1");
timer = setTimeout(textTransform, 500);
})();
@ -118,7 +134,7 @@
gap: 4px;
}
.marquee-1 .controlplay a {
.marquee-1 .controlplay button.marquee-toggle-btn {
display: inline-flex;
align-items: center;
justify-content: center;
@ -128,53 +144,47 @@
border-radius: 50%;
background: #fff;
cursor: pointer;
text-decoration: none;
transition: background 0.15s;
padding: 0;
}
.marquee-1 .controlplay a:hover,
.marquee-1 .controlplay a:focus {
.marquee-1 .controlplay button.marquee-toggle-btn:hover,
.marquee-1 .controlplay button.marquee-toggle-btn:focus {
background: #f0f0f0;
outline: 2px solid #005fcc;
outline-offset: 2px;
}
/* resume iconplay 三角形 */
.marquee-1 .controlplay .resume-slide i::before {
content: '';
display: inline-block;
width: 0;
height: 0;
border-style: solid;
border-width: 4px 0 4px 8px;
border-color: transparent transparent transparent #555;
margin-left: 2px;
}
/* pause icon兩條直線 */
.marquee-1 .controlplay .pause-slide i {
/* 播放中:顯示 pause icon兩條直線 */
.marquee-1 .controlplay button.marquee-toggle-btn:not(.is-paused) .marquee-icon {
display: inline-flex;
gap: 2px;
align-items: center;
}
.marquee-1 .controlplay .pause-slide i::before,
.marquee-1 .controlplay .pause-slide i::after {
.marquee-1 .controlplay button.marquee-toggle-btn:not(.is-paused) .marquee-icon::before,
.marquee-1 .controlplay button.marquee-toggle-btn:not(.is-paused) .marquee-icon::after {
content: '';
display: inline-block;
width: 3px;
height: 10px;
background: #555;
background: #ff4500;
border-radius: 1px;
}
/* active 狀態顏色 */
.marquee-1 .controlplay .resume-slide.active i::before {
/* 已暫停:顯示 play icon三角形 */
.marquee-1 .controlplay button.marquee-toggle-btn.is-paused .marquee-icon::before {
content: '';
display: inline-block;
width: 0;
height: 0;
border-style: solid;
border-width: 5px 0 5px 10px;
border-color: transparent transparent transparent #32D9C3;
margin-left: 2px;
}
.marquee-1 .controlplay .pause-slide.active i::before,
.marquee-1 .controlplay .pause-slide.active i::after {
background: #ff4500;
.marquee-1 .controlplay button.marquee-toggle-btn.is-paused .marquee-icon::after {
display: none;
}
</style>

View File

@ -6,7 +6,7 @@
<li class="widget-content">
<div class="link-img-wrap{{display_image}}">
<a href="{{link_to_show}}" target="{{target}}" title="{{img_description}}">
<img src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
<img src="{{img_src}}" alt="{{img_description}}">
</a>
</div>
<span data-list="statuses" data-level="1">

View File

@ -7,7 +7,7 @@
<div class="link-img-wrap{{display_image}}">
<a href="{{link_to_show}}" target="{{target}}" title="{{img_description}}">
<img src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
<img src="{{img_src}}" alt="{{img_description}}">
</a>
</div>
<div class="widget-content-title">

View File

@ -6,7 +6,7 @@
<li class="widget-content widget-content-horizontal ">
<a href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
<div class="link-img-wrap{{display_image}}">
<img src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
<img src="{{img_src}}" alt="{{img_description}}">
</div>
</a>
<div class="widget-content-title">

View File

@ -6,7 +6,7 @@
<li class="widget-content widget-content-horizontal col-sm-6">
<a href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
<div class="link-img-wrap{{display_image}}">
<img src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
<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>

View File

@ -7,7 +7,7 @@
<div class="hex-border">
<a href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
<div class="link-img-wrap{{display_image}}">
<img src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
<img src="{{img_src}}" alt="{{img_description}}">
</div>
<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">

View File

@ -6,7 +6,7 @@
<li class="index-content">
<a class="index-content-title" href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
<div class="link-img-wrap{{display_image}}">
<img src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
<img src="{{img_src}}" alt="{{img_description}}">
</div>
<h4>
{{title}}

View File

@ -6,7 +6,7 @@
<li class="index-content col-md-4 col-sm-4">
<a class="index-content-title" href="{{link_to_show}}" target="{{target}}" title="{{title_text}}">
<div class="link-img-wrap{{display_image}}">
<img src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
<img src="{{img_src}}" alt="{{img_description}}">
</div>
<h4>
<span class="link-title">