This commit is contained in:
ken 2026-08-06 16:11:36 +08:00
parent 14b0b5b614
commit 65486d4504
9 changed files with 264 additions and 127 deletions

View File

@ -292,80 +292,103 @@
} }
}, },
ClickMenuHandler: function() { ClickMenuHandler: function() {
// 處理主選單切換(漢堡 icon // 處理主選單切換(漢堡 icon
$(document).on('click', '.navbar-toggle', function (e) { $(document).on('click', '.navbar-toggle', function (e) {
e.preventDefault(); e.preventDefault();
// 確保 .navbar-toggle 放到 .modules-menu 後面 // 確保 .navbar-toggle 放到 .modules-menu 後面
$('.mobile-menu').each(function () { $('.mobile-menu').each(function () {
var $menu = $(this); var $menu = $(this);
if ($menu.find('.modules-menu').length && !$menu.find('.modules-menu + .navbar-toggle').length) { if ($menu.find('.modules-menu').length && !$menu.find('.modules-menu + .navbar-toggle').length) {
$menu.find('.modules-menu').after($menu.find('.navbar-toggle')); $menu.find('.modules-menu').after($menu.find('.navbar-toggle'));
}
});
$('.mobile-menu').toggleClass('active');
$('body').toggleClass('noscroll');
// ★ 修正:依據 active 狀態決定 collapsed 的加/移除
if ($('.mobile-menu').hasClass('active')) {
$('.mobile-menu .navbar-toggle').removeClass('collapsed'); // 打開 → 叉叉
} else {
$('.mobile-menu .navbar-toggle').addClass('collapsed'); // 關閉 → 三條橫線
}
// 關閉所有下拉選單
$('.mobile-menu1 > ul, .mobile-menu2 > ul').slideUp(500);
$('.mobile-menu1 > .menu-drop, .mobile-menu2 > .menu-drop').removeClass('opened');
// 無障礙:聚焦第一個互動元素
if ($('.mobile-menu').hasClass('active')) {
setTimeout(function () {
$('.modules-menu').find('input, button, select, textarea, a').first().focus();
}, 100);
} }
}); });
$('.mobile-menu').toggleClass('active'); // ✅ Tab 鍵跳過 .mobile-menu 時,觸發收合邏輯
$('body').toggleClass('noscroll'); $(document).on('focusout', '.mobile-menu', function(e) {
$('.mobile-menu .navbar-toggle').removeClass('collapsed');
// 關閉所有下拉選單
$('.mobile-menu1 > ul, .mobile-menu2 > ul').slideUp(500);
$('.mobile-menu1 > .menu-drop, .mobile-menu2 > .menu-drop').removeClass('opened');
// 無障礙:聚焦第一個互動元素
if ($('.mobile-menu').hasClass('active')) {
setTimeout(function () {
$('.modules-menu').find('input, button, select, textarea, a').first().focus();
}, 100);
}
});
// ✅ Tab 鍵跳過 .navbar-toggle 時,觸發與點擊相同的收合邏輯
$(document).on('focusout', '.mobile-menu', function(e) {
setTimeout(function() { setTimeout(function() {
var $newFocus = $(document.activeElement); var $newFocus = $(document.activeElement);
// 焦點已離開 .mobile-menu 且選單是展開狀態
if ($('.mobile-menu').hasClass('active') && $newFocus.closest('.mobile-menu').length === 0) { // 焦點在 body 時代表滑鼠正在點擊中,不處理
// ✅ 直接 trigger click與按下 .navbar-toggle 執行完全相同的動作 if ($newFocus.is('body')) return;
$('.navbar-toggle').first().trigger('click');
if ($('.mobile-menu').hasClass('active') && $newFocus.closest('.mobile-menu').length === 0) {
var $btn = $('.navbar-toggle').first();
if ($btn.attr('data-bs-toggle')) {
var target = $btn.attr('data-bs-target');
var bsCollapse = window.bootstrap && bootstrap.Collapse.getInstance($(target)[0]);
if (bsCollapse) bsCollapse.hide();
$('.mobile-menu').removeClass('active');
$('body').removeClass('noscroll');
$('.mobile-menu .navbar-toggle').addClass('collapsed');
$('.mobile-menu1 > ul, .mobile-menu2 > ul').slideUp(500);
$('.mobile-menu1 > .menu-drop, .mobile-menu2 > .menu-drop').removeClass('opened');
} else {
$btn.trigger('click');
} }
}
}, 50); }, 50);
}); });
$('.mobile-menu1 > .menu-drop').click(function(){ $('.mobile-menu1 > .menu-drop').click(function(){
var $that = $(this); var $that = $(this);
var opencheck1 = $that.hasClass('opened'); var opencheck1 = $that.hasClass('opened');
if ( opencheck1 == 0 ) { if ( opencheck1 == 0 ) {
$('.mobile-menu1 > ul').not($that.siblings('ul')).slideUp(500); $('.mobile-menu1 > ul').not($that.siblings('ul')).slideUp(500);
$('.mobile-menu1 > .menu-drop').not($that).removeClass('opened'); $('.mobile-menu1 > .menu-drop').not($that).removeClass('opened');
$('.mobile-menu2 > ul').slideUp(500); $('.mobile-menu2 > ul').slideUp(500);
$('.mobile-menu2 > .menu-drop').removeClass('opened'); $('.mobile-menu2 > .menu-drop').removeClass('opened');
$that.siblings('ul').slideDown(500); $that.siblings('ul').slideDown(500);
$that.addClass('opened'); $that.addClass('opened');
} else if (opencheck1 == 1) { } else if (opencheck1 == 1) {
$that.siblings('ul').slideUp(500); $that.siblings('ul').slideUp(500);
$('.mobile-menu2 > ul').slideUp(500); $('.mobile-menu2 > ul').slideUp(500);
$('.mobile-menu2 > .menu-drop').removeClass('opened'); $('.mobile-menu2 > .menu-drop').removeClass('opened');
$that.removeClass('opened'); $that.removeClass('opened');
} }
}) })
$('.mobile-menu2 > .menu-drop').click(function(){ $('.mobile-menu2 > .menu-drop').click(function(){
var $that = $(this); var $that = $(this);
var opencheck2 = $that.hasClass('opened'); var opencheck2 = $that.hasClass('opened');
if ( opencheck2 == 0 ) { if ( opencheck2 == 0 ) {
$('.mobile-menu2 > ul').not($that.siblings('ul')).slideUp(500); $('.mobile-menu2 > ul').not($that.siblings('ul')).slideUp(500);
$('.mobile-menu2 > .menu-drop').not($that).removeClass('opened'); $('.mobile-menu2 > .menu-drop').not($that).removeClass('opened');
$that.siblings('ul').slideDown(500); $that.siblings('ul').slideDown(500);
$that.addClass('opened'); $that.addClass('opened');
} else if (opencheck2 == 1) { } else if (opencheck2 == 1) {
$that.siblings('ul').slideUp(500); $that.siblings('ul').slideUp(500);
$that.removeClass('opened'); $that.removeClass('opened');
} }
}) })
} }
}; };
// 把orbit物件加到window物件裡面並改名為ORBITFRONT來減少名稱衝突的機會 // 把orbit物件加到window物件裡面並改名為ORBITFRONT來減少名稱衝突的機會
@ -1077,56 +1100,59 @@ $(function() {
} }
} }
// E. 重新計算標題 (關鍵邏輯:若 hasOriginalTitle 為真,則不進入此區塊) // E. 重新計算標題 (關鍵邏輯:若 hasOriginalTitle 為真,則不進入此區塊)
if (!hasOriginalTitle) { if (!hasOriginalTitle) {
if (linkText === "" && $img.length > 0) { if (linkText === "" && $img.length > 0) {
var rawAlt = ($img.attr('alt') || '').trim(); var rawAlt = ($img.attr('alt') || '').trim();
var forbidden = ['這是一張圖片', '圖片', 'image', 'photo', '圖', '']; var forbidden = ['這是一張圖片', '圖片', 'image', 'photo', '圖', ''];
var imgAlt = forbidden.some(function(txt) { return rawAlt.toLowerCase() === txt; }) var imgAlt = forbidden.some(function(txt) { return rawAlt.toLowerCase() === txt; })
? ($a.attr('aria-label') || i18n.link) : rawAlt; ? ($a.attr('aria-label') || i18n.link) : rawAlt;
var fileInfo = fileExt ? '[' + fileExt.toUpperCase() + '] ' : ''; var fileInfo = fileExt ? '[' + fileExt.toUpperCase() + '] ' : '';
$a.attr('title', (fileInfo + imgAlt + " " + windowTask).trim()); $a.attr('title', (fileInfo + imgAlt + " " + windowTask).trim());
$img.attr('alt', imgAlt); $img.attr('alt', imgAlt);
} }
else if (linkText !== "") { else if (linkText !== "") {
if (fileExt !== "" || hasBadSymbol || currentTitle === "" || currentTitle.includes('/uploads/')) { if (fileExt !== "" || hasBadSymbol || currentTitle === "" || currentTitle.includes('/uploads/')) {
if (fileExt !== "") { if (fileExt !== "") {
$a.attr('title', linkText + " ." + fileExt + " " + windowTask); $a.attr('title', linkText + " ." + fileExt + " " + windowTask);
} else { } else {
$a.attr('title', windowTask); $a.attr('title', windowTask);
}
} }
} }
} }
}
// ✅ 符合 HM1240404Etitle 不應與連結文字或圖片 alt 重複 // ✅ 符合 HM1240404Etitle 不應與連結文字或圖片 alt 重複
if (hasOriginalTitle && currentTitle !== "") { if (hasOriginalTitle && currentTitle !== "") {
var titleWithoutWindow = currentTitle var titleWithoutWindow = currentTitle
.replace('(在本視窗開啟)', '') .replace('(在本視窗開啟)', '')
.replace('(在新視窗開啟)', '') .replace('(在新視窗開啟)', '')
.replace('Open in this window', '') .replace('Open in this window', '')
.replace('Open in new window', '') .replace('Open in new window', '')
.replace('另開新視窗前往', '') .replace('另開新視窗前往', '')
.replace('另開新視窗', '') .replace('另開新視窗', '')
.trim(); .trim();
// ✅ title 去掉開窗字串後,若與連結文字或圖片原始 alt 相同,則只保留開窗提示 // ✅ title 去掉開窗字串後,若與連結文字或圖片原始 alt 相同,則只保留開窗提示
if ( // ✅ 新增:若 linkText 包含副檔名且 title 也是同樣檔名,也只保留開窗提示
(titleWithoutWindow === linkText && linkText !== i18n.link) || if (
(imgAltOriginal !== '' && titleWithoutWindow === imgAltOriginal) (titleWithoutWindow === linkText && linkText !== i18n.link) ||
) { (imgAltOriginal !== '' && titleWithoutWindow === imgAltOriginal) ||
$a.attr('title', windowTask); (fileExt !== '' && linkText.toLowerCase().endsWith('.' + fileExt) && titleWithoutWindow === linkText)
} ) {
$a.attr('title', windowTask);
// ✅ 最終清理:若 title 出現空括號 () 則移除並補上正確開窗提示 return; // ✅ 加上 return避免繼續執行後面的清理邏輯造成二次污染
var finalTitle = ($a.attr('title') || '').trim();
if (finalTitle.includes('()')) {
finalTitle = finalTitle.replace(/\(\)/g, '').trim();
$a.attr('title', finalTitle + ' ' + windowTask);
}
} }
// ✅ 最終清理:若 title 出現空括號 () 則移除並補上正確開窗提示
var finalTitle = ($a.attr('title') || '').trim();
if (finalTitle.includes('()')) {
finalTitle = finalTitle.replace(/\(\)/g, '').trim();
$a.attr('title', finalTitle + ' ' + windowTask);
}
}
// F. 最終清理:移除冗餘 label避免螢幕閱讀器唸兩次 // F. 最終清理:移除冗餘 label避免螢幕閱讀器唸兩次
$a.removeAttr('aria-label'); $a.removeAttr('aria-label');
}); });
@ -3062,6 +3088,96 @@ $(document).ready(function () {
setTimeout(function () { setTimeout(function () {
$('.dtr-control').removeAttr('tabindex'); $('.dtr-control').removeAttr('tabindex');
}, 500); }, 500);
});
//會員tab邏輯
$(document).ready(function () {
setTimeout(function () {
$('.dtr-control').removeAttr('tabindex');
}, 500);
});
function fixTabKeyboardNav() {
setTimeout(function () {
var $tablist = $('.member-plugins[role="tablist"]');
var $tabs = $tablist.find('a[role="tab"]');
// 初始化 roving tabindex 和 aria-selected
$tabs.each(function (i) {
var $tab = $(this);
var isActive = $tab.closest('li').hasClass('active');
$tab.attr({
'tabindex': isActive ? '0' : '-1',
'aria-selected': isActive ? 'true' : 'false'
});
});
// 方向鍵切換頁籤
$tabs.on('keydown', function (e) {
var $current = $(this);
var currentIndex = $tabs.index($current);
var $target;
if (e.keyCode === 39 || e.keyCode === 40) {
// 右鍵或下鍵:下一個
e.preventDefault();
$target = $tabs.eq((currentIndex + 1) % $tabs.length);
} else if (e.keyCode === 37 || e.keyCode === 38) {
// 左鍵或上鍵:上一個
e.preventDefault();
$target = $tabs.eq((currentIndex - 1 + $tabs.length) % $tabs.length);
} else if (e.keyCode === 36) {
// Home第一個
e.preventDefault();
$target = $tabs.first();
} else if (e.keyCode === 35) {
// End最後一個
e.preventDefault();
$target = $tabs.last();
} else {
return;
}
// 更新 roving tabindex 和 aria-selected
$tabs.attr({ 'tabindex': '-1', 'aria-selected': 'false' });
$target.attr({ 'tabindex': '0', 'aria-selected': 'true' });
$target.focus().trigger('click');
});
// 點擊頁籤時同步更新狀態
$tabs.on('click', function () {
$tabs.attr({ 'tabindex': '-1', 'aria-selected': 'false' });
$(this).attr({ 'tabindex': '0', 'aria-selected': 'true' });
});
}, 500);
}
$(document).ready(function () {
fixTabKeyboardNav();
});
function removeBareUrlLinks() {
setTimeout(function() {
$('.dataTables_wrapper a').each(function() {
var $a = $(this);
var text = $a.text().trim();
if (/^https?:\/\//i.test(text)) {
$a.replaceWith(text);
}
});
}, 500);
}
$(document).ready(function() {
removeBareUrlLinks();
});
//麵包屑無障礙
$(document).ready(function () {
$('.widget-breadcrumb .breadcrumb li:last-child a').attr('aria-current', 'page');
// 若尚未有 nav 包住,自動加上
$('.widget-breadcrumb .breadcrumb').each(function () {
if (!$(this).closest('nav').length) {
$(this).wrap('<nav aria-label="麵包屑導覽"></nav>');
}
});
}); });
// 執行 member等高計算目前改用flexbox故mark掉 by ika 20160105 // 執行 member等高計算目前改用flexbox故mark掉 by ika 20160105
// $(window).load(function() { // $(window).load(function() {

View File

@ -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;

View File

@ -17,8 +17,7 @@
<dl class="i-archive__file-list" data-list="files" data-level="2"> <dl class="i-archive__file-list" data-list="files" data-level="2">
<dd class="i-archive__file-wrap"> <dd class="i-archive__file-wrap">
<i class="fa-solid fa-file"></i> <i class="fa-solid fa-file"></i>
<a class="i-archive__file-name" href="{{file-url}}" target="{{target}}" title="{{file-name}}">{{file-name}}</a> <a class="i-archive__file-name" href="{{file-url}}" target="{{target}}" title="{{file-name}}">{{file-name}}<span class="i-archive__file-type label label-primary {{file-type}}">{{file-type}}</span></a>
<span class="i-archive__file-type label label-primary {{file-type}}">{{file-type}}</span>
</dd> </dd>
</dl> </dl>
</div> </div>

View File

@ -3,7 +3,7 @@
<span>{{album-title}}</span> <span>{{album-title}}</span>
</h1> </h1>
{{album-description}} {{album-description}}
<div data-level="0" data-list="images"> <div class="show-gallery-list" data-level="0" data-list="images">
<div class="show-content col-xs-6 col-sm-2"> <div class="show-content col-xs-6 col-sm-2">
<div class="show-content-inner"> <div class="show-content-inner">
<div class="show-pic"> <div class="show-pic">
@ -15,4 +15,28 @@
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<style>
.show-gallery-list{
display: flex;
flex-wrap: wrap;
}
.show-gallery .show-content {
@media(max-width:480px){
width:100%;
}
}
</style>
<script>
setTimeout(function() {
var albumTitle = $('.show-title span').text().trim();
$('.show-content').each(function(index) {
var $img = $(this).find('img');
if ($img.attr('alt') === 'gallery image') {
$img.attr('alt', albumTitle + (index + 1));
}
});
}, 500);
</script>

View File

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

View File

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

View File

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

View File

@ -10,7 +10,7 @@
<div class="i-member-item-inner clearfix"> <div class="i-member-item-inner clearfix">
<div class="i-member-pic-wrap"> <div class="i-member-pic-wrap">
<a href="{{link_to_show}}" title="{{name}}"> <a href="{{link_to_show}}" title="{{name}}">
<img class="i-member-pic" src="{{image}}" title="{{name}}"> <img class="i-member-pic" src="{{image}}" alt="{{name}}">
</a> </a>
</div> </div>

View File

@ -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>