diff --git a/assets/javascripts/app.js b/assets/javascripts/app.js index 57d3db0..6127288 100644 --- a/assets/javascripts/app.js +++ b/assets/javascripts/app.js @@ -928,7 +928,7 @@ 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; @@ -1778,17 +1778,32 @@ $(function() { var key = getTabKey($currentTab); var $visibleItems = getVisibleItems($scope, key); - // Shift+Tab:若是第一個連結,跳回對應頁籤 + // 找出當前類別的 .w-annc__more + var $more = $scope.find('.w-annc__more-wrap a, .w-annc__more').filter(':visible').first(); + + // Shift+Tab:若在第一個連結,跳回對應頁籤 if (e.which === 9 && e.shiftKey) { if ($currentLink.is($visibleItems.find('a').first())) { e.preventDefault(); $currentTab.focus(); } + // Shift+Tab:若在 .w-annc__more,跳回最後一個公告連結 + if ($more.length && $currentLink.is($more)) { + e.preventDefault(); + $visibleItems.find('a').last().focus(); + } } - // Tab:若是最後一個連結,跳到下一個頁籤並切換 + // Tab:若在最後一個連結,跳到 .w-annc__more if (e.which === 9 && !e.shiftKey) { if ($currentLink.is($visibleItems.find('a').last())) { + if ($more.length) { + e.preventDefault(); + $more.focus(); + } + } + // Tab:若在 .w-annc__more,才跳到下一個頁籤 + if ($more.length && $currentLink.is($more)) { var $nextTab = $currentTab.next('.filter_tab'); if ($nextTab.length > 0) { e.preventDefault(); @@ -2948,13 +2963,139 @@ $(document).ready(function () { } }); }); +//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 () { - 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() { @@ -3336,4 +3477,82 @@ $(function() { // } // }); + //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)); diff --git a/assets/stylesheets/template/base/_global.scss b/assets/stylesheets/template/base/_global.scss index 9faf981..1de3a4a 100644 --- a/assets/stylesheets/template/base/_global.scss +++ b/assets/stylesheets/template/base/_global.scss @@ -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 diff --git a/modules/ad_banner/_ad_banner_widget11.html.erb b/modules/ad_banner/_ad_banner_widget11.html.erb index d2a6d28..fd1ac11 100644 --- a/modules/ad_banner/_ad_banner_widget11.html.erb +++ b/modules/ad_banner/_ad_banner_widget11.html.erb @@ -8,7 +8,6 @@ data-cycle-auto-height="{{base_image}}" data-cycle-speed="{{speed}}" data-cycle-timeout="{{timeout}}" - data-cycle-pager=".banner_caption_{{subpart-id}}" data-pager-template="" data-pager-active-class="active-slide" diff --git a/modules/ad_banner/_ad_banner_widget2.html.erb b/modules/ad_banner/_ad_banner_widget2.html.erb index 70ef492..6cc584d 100644 --- a/modules/ad_banner/_ad_banner_widget2.html.erb +++ b/modules/ad_banner/_ad_banner_widget2.html.erb @@ -49,20 +49,23 @@