diff --git a/assets/javascripts/app.js b/assets/javascripts/app.js index 56af029..c3ac759 100644 --- a/assets/javascripts/app.js +++ b/assets/javascripts/app.js @@ -3377,138 +3377,259 @@ $(document).ready(function() { // ORBITFRONT.member.equalHeight('.i-member-item-inner'); // } // }); +//banner英文 +$(function() { + function fixBannerA11yByLang() { + setTimeout(function() { + var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase(); + var isEn = pageLang.startsWith('en'); - //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 ? '' : ' 張投影片' + }; - 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); - $('.w-ba-banner').each(function() { - var $banner = $(this); + $banner.find('.controlplay').attr('aria-label', i18n.playControls); - // ✅ 播放控制選項 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('.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('.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); - // ✅ 上一張按鈕 - $banner.find('.prev-button').attr('aria-label', i18n.prev); + 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 }); + }); + }); - // ✅ 下一張按鈕 - $banner.find('.next-button').attr('aria-label', i18n.next); + // ✅ Cycle2 初始化後重新處理 Pager + 切換後播報當前圖片資訊 + $('.w-ba-banner .cycle-slideshow').on('cycle-post-initialize cycle-after', function(event) { + var $slideshow = $(this); + var $banner = $slideshow.closest('.w-ba-banner'); + var $slides = $banner.find('.w-ba-banner__slide'); - // ✅ 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 - }); - }); - }); + // 更新 Pager aria-label + $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 - }); - }); - }); + // ✅ 問題1:cycle-after 時用 live region 播報當前圖片資訊 + if (event.type === 'cycle-after') { + var opts = $slideshow.data('cycle.opts'); + if (opts) { + var currentIndex = opts.currSlide; + var $currentSlide = $slides.eq(currentIndex); + var currentTitle = $currentSlide.data('cycle-title') || ''; + var currentAlt = $currentSlide.find('img').attr('alt') || ''; + var announceText = isEn + ? 'Slide ' + (currentIndex + 1) + ' of ' + $slides.length + (currentTitle ? ': ' + currentTitle : (currentAlt ? ': ' + currentAlt : '')) + : '第 ' + (currentIndex + 1) + ' 張,共 ' + $slides.length + ' 張' + (currentTitle ? ':' + currentTitle : (currentAlt ? ':' + currentAlt : '')); - }, 800); - } + var $announcer = $banner.find('.banner-announcer'); + if ($announcer.length === 0) { + $announcer = $('
'); + $banner.append($announcer); + } + $announcer.text(''); + setTimeout(function() { + $announcer.text(announceText); + }, 100); + } + } + }); + + }, 800); + } + + fixBannerA11yByLang(); +}); - fixBannerA11yByLang(); - }); //bannercontrolplay $(function() { - function fixBannerPlayPauseA11y() { - setTimeout(function() { - var pageLang = ($('html').attr('lang') || 'zh-Hant').toLowerCase(); - var isEn = pageLang.startsWith('en'); + 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' : '暫停播放' - }; + var i18n = { + resume: isEn ? 'Play' : '繼續播放', + pause: isEn ? 'Pause' : '暫停播放' + }; - $('.w-ba-banner').each(function() { - var $banner = $(this); - var $controlplay = $banner.find('.controlplay'); + $('.w-ba-banner').each(function() { + var $banner = $(this); + var $controlplay = $banner.find('.controlplay'); + var $slideshow = $banner.find('.cycle-slideshow'); - // ✅ 把 radiogroup 改為一般容器 - $controlplay.removeAttr('role aria-label'); + $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 $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'); + 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'); - }); + $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'); - }); - }); + $pause.off('click.bannerA11y').on('click.bannerA11y', function() { + $pause.attr('aria-pressed', 'true'); + $resume.attr('aria-pressed', 'false'); + }); - }, 800); - } + // ✅ 問題2:focus 時動態讀出當前播放狀態 + $resume.off('focus.bannerStatus').on('focus.bannerStatus', function() { + var isPlaying = !$slideshow.hasClass('cycle-paused'); + var statusText = isEn + ? 'Play button. Current status: ' + (isPlaying ? 'Playing' : 'Paused') + : '繼續播放按鈕。目前狀態:' + (isPlaying ? '播放中' : '已暫停'); + $(this).attr('aria-label', statusText); + }); + $resume.off('blur.bannerStatus').on('blur.bannerStatus', function() { + $(this).attr('aria-label', i18n.resume); + }); - fixBannerPlayPauseA11y(); + $pause.off('focus.bannerStatus').on('focus.bannerStatus', function() { + var isPlaying = !$slideshow.hasClass('cycle-paused'); + var statusText = isEn + ? 'Pause button. Current status: ' + (isPlaying ? 'Playing' : 'Paused') + : '暫停播放按鈕。目前狀態:' + (isPlaying ? '播放中' : '已暫停'); + $(this).attr('aria-label', statusText); + }); + $pause.off('blur.bannerStatus').on('blur.bannerStatus', function() { + $(this).attr('aria-label', i18n.pause); + }); + + }); + + }, 800); + } + + fixBannerPlayPauseA11y(); +}); +//banner進入自動暫停 +$(function() { + function fixBannerFocusPauseA11y() { + setTimeout(function() { + $('.w-ba-banner').each(function() { + var $banner = $(this); + var $slideshow = $banner.find('.cycle-slideshow'); + var $pauseBtn = $banner.find('.pause-slide'); + var $resumeBtn = $banner.find('.resume-slide'); + + var manuallyPaused = false; + + // ✅ 焦點進入輪播區域時自動暫停 + $banner.on('focusin', function() { + $slideshow.cycle('pause'); + $pauseBtn.addClass('active').attr('aria-checked', 'true'); + $resumeBtn.removeClass('active').attr('aria-checked', 'false'); + }); + + // ✅ 若使用者手動按下暫停,焦點離開後不自動恢復 + $pauseBtn.on('click', function() { + manuallyPaused = true; + }); + + $resumeBtn.on('click', function() { + manuallyPaused = false; + }); + + // ✅ 覆寫 focusout 加入 manuallyPaused 判斷 + $banner.off('focusout').on('focusout', function() { + setTimeout(function() { + if (!$banner.find(':focus').length && !manuallyPaused) { + $slideshow.cycle('resume'); + $resumeBtn.addClass('active').attr('aria-checked', 'true'); + $pauseBtn.removeClass('active').attr('aria-checked', 'false'); + } + }, 150); + }); + + }); + }, 800); + } + + fixBannerFocusPauseA11y(); +}); +//googlemap加title +function fixGoogleMapIframeTitle(){ + setTimeout(function(){ + var pageLang = (document.documentElement.getAttribute('lang') || '').toLowerCase(); + var isEnglish = pageLang.indexOf('en') === 0; // lang="en"、"en-us" 都算英文頁 + + $('iframe[src*="google.com/maps/embed"]').each(function(){ + var $iframe = $(this); + var currentTitle = ($iframe.attr('title') || '').trim(); + + // 只處理明顯是佔位文字、空白、或沒有 title 的 iframe, + // 已經有具體地點名稱的(例如「紅館」)不會被動到 + if (currentTitle !== '' && currentTitle.toLowerCase() !== 'googleoauth') { + return; + } + + // 優先找上層容器上手動標記的地點名稱 + var name = $iframe.closest('[data-map-name]').data('map-name'); + + // 找不到的話,往上找最接近的標題文字(h1~h6 或粗體)當地點名稱 + if (!name) { + var $context = $iframe.closest('section, div').prevAll('h1,h2,h3,h4,h5,h6,strong').first(); + name = $context.length ? $context.text().trim() : ''; + } + + var newTitle; + if (isEnglish) { + newTitle = name ? ('Google Map: location of ' + name) + : 'Google Map (embedded map, please manually confirm and fill in the actual location name)'; + } else { + newTitle = name ? ('Google地圖:' + name + ' 位置') + : 'Google地圖(嵌入地圖,請人工確認並填寫實際地點名稱)'; + } + + $iframe.attr('title', newTitle); + }); + }, 800); +} +$(document).ready(function(){ + fixGoogleMapIframeTitle(); }); }(jQuery, window)); diff --git a/assets/stylesheets/template/modules/event_news.scss b/assets/stylesheets/template/modules/event_news.scss index c30b4c3..61b7f3a 100644 --- a/assets/stylesheets/template/modules/event_news.scss +++ b/assets/stylesheets/template/modules/event_news.scss @@ -492,7 +492,6 @@ .i-annc__list { display: flex; flex-wrap: wrap; - justify-content: center; } .i-annc__title { font-family: $main-font;