diff --git a/assets/javascripts/app.js b/assets/javascripts/app.js index 1632f70..022ea5c 100644 --- a/assets/javascripts/app.js +++ b/assets/javascripts/app.js @@ -3476,5 +3476,117 @@ $(document).ready(function () { // ORBITFRONT.member.equalHeight('.i-member-item-inner'); // } // }); + $(function() { + function fixLangSwitchA11y() { + setTimeout(function() { + + // ✅ 語系切換主按鈕補上 role="button" aria-haspopup aria-expanded + var $langSwitch = $('.lang-switch'); + $langSwitch.attr({ + 'role': 'button', + 'aria-haspopup': 'true', + 'aria-expanded': 'false', + 'aria-label': '語系切換,展開語言選單' + }); + + // ✅ Google Translate 旗幟語言項目:補上 role="button" aria-pressed 和 aria-label + // 取得目前語系 + function getCurrentLang() { + var cookieLang = document.cookie.match(/googtrans=\/[a-z-]+\/([a-z-]+)/i); + if (cookieLang) return cookieLang[1].toLowerCase(); + return 'zh-tw'; // 預設繁體中文 + } + + var langMap = { + 'en': 'English', + 'zh-TW': '繁體中文', + 'ja': '日本語', + 'ko': '한국어', + 'th': 'ไทย', + 'vi': 'Tiếng Việt' + }; + + // ✅ 處理 onclick="translateLang('xx')" 的 .lang-item + $('.google-translate-flags .lang-item[onclick]').each(function() { + var $item = $(this); + var onclickVal = $item.attr('onclick') || ''; + var match = onclickVal.match(/translateLang\('([^']+)'\)/); + if (!match) return; + + var langCode = match[1]; + var langName = langMap[langCode] || langCode; + var currentLang = getCurrentLang(); + var isPressed = currentLang === langCode.toLowerCase(); + + // ✅ 移除 onclick,改用 jQuery 事件,避免語音軟體誤報 + $item.removeAttr('onclick'); + + // ✅ 補上按鈕語意 + $item.attr({ + 'role': 'button', + 'tabindex': '0', + 'aria-label': langName + ',切換語系', + 'aria-pressed': isPressed ? 'true' : 'false' + }); + + // ✅ 點擊或 Enter/Space 切換語系 + $item.off('click.langA11y keydown.langA11y'); + + $item.on('click.langA11y', function() { + // 更新所有按鈕的 aria-pressed + $('.google-translate-flags .lang-item[role="button"]').attr('aria-pressed', 'false'); + $(this).attr('aria-pressed', 'true'); + // 執行語系切換 + if (typeof translateLang === 'function') { + translateLang(langCode); + } + }); + + $item.on('keydown.langA11y', function(e) { + if (e.which === 13 || e.which === 32) { + e.preventDefault(); + $(this).trigger('click.langA11y'); + } + }); + }); + + // ✅ 語系切換主按鈕展開/收合 aria-expanded + var $flagsDropdown = $('.google-translate-flags'); + + $langSwitch.off('click.langSwitchA11y').on('click.langSwitchA11y', function() { + var isExpanded = $(this).attr('aria-expanded') === 'true'; + $(this).attr('aria-expanded', isExpanded ? 'false' : 'true'); + $(this).attr('aria-label', isExpanded ? '語系切換,展開語言選單' : '語系切換,收合語言選單'); + }); + + // ✅ 焦點離開語系選單時收合 + $('.lang-switch-wrapper').on('focusout', function() { + setTimeout(function() { + if (!$('.lang-switch-wrapper').find(':focus').length) { + $langSwitch.attr('aria-expanded', 'false'); + $langSwitch.attr('aria-label', '語系切換,展開語言選單'); + } + }, 150); + }); + + // ✅ 補上旗幟圖片的 alt(避免語音報讀空值或檔名) + $('.google-translate-flags .lang-item[role="button"] img').each(function() { + var $img = $(this); + var $span = $img.siblings('span'); + var langName = $span.text().trim(); + $img.attr('alt', langName + ' 國旗'); + }); + + // ✅ GoogleTranslate 標題列不需要被聚焦 + $('.lang-item.GoogleTranslate').attr({ + 'aria-hidden': 'true', + 'tabindex': '-1' + }); + + }, 500); + } + + fixLangSwitchA11y(); +}); }(jQuery, window));