From 7f70c0abac7fdd1c199fa7a8254d2198d8620598 Mon Sep 17 00:00:00 2001 From: ken Date: Wed, 22 Jul 2026 17:22:51 +0800 Subject: [PATCH] update --- assets/javascripts/app.js | 280 ++++++++++++++++++ assets/stylesheets/template/base/_global.scss | 5 +- .../stylesheets/template/base/_variables.scss | 4 +- assets/stylesheets/template/modules/menu.scss | 5 +- .../template/modules/web_resource.scss | 20 +- modules/ad_banner/_ad_banner_widget2.html.erb | 4 +- 6 files changed, 300 insertions(+), 18 deletions(-) diff --git a/assets/javascripts/app.js b/assets/javascripts/app.js index 1f8c406..3221cfc 100644 --- a/assets/javascripts/app.js +++ b/assets/javascripts/app.js @@ -320,6 +320,17 @@ }, 100); } }); + // ✅ Tab 鍵跳過 .navbar-toggle 時,觸發與點擊相同的收合邏輯 + $(document).on('focusout', '.mobile-menu', function(e) { + setTimeout(function() { + var $newFocus = $(document.activeElement); + // 焦點已離開 .mobile-menu 且選單是展開狀態 + if ($('.mobile-menu').hasClass('active') && $newFocus.closest('.mobile-menu').length === 0) { + // ✅ 直接 trigger click,與按下 .navbar-toggle 執行完全相同的動作 + $('.navbar-toggle').first().trigger('click'); + } + }, 50); + }); $('.mobile-menu1 > .menu-drop').click(function(){ var $that = $(this); @@ -2423,7 +2434,276 @@ $(document).ready(function() { init(); }); +// 1. OrbitBar 基礎與搜尋選單邏輯 +$(document).ready(function() { + const isEn = document.documentElement.lang === 'en'; + const $orbitLabel = $('label[for="open-orbit-nav"]'); + const $searchArea = $('.orbit-bar-search-sign-language'); + const $firstInput = $('#q'); // 搜尋框通常是選單內第一個獲焦元素 + // 初始化屬性 + if (isEn) { + $orbitLabel.attr({ title: 'Site search and language menu', 'aria-label': 'Site search and language menu' }); + } else { + $orbitLabel.attr({ title: '全站搜尋及語言切換選單', 'aria-label': '全站搜尋及語言切換選單' }); + } + $orbitLabel.attr({ 'role': 'button', 'aria-haspopup': 'true', 'aria-expanded': 'false', 'tabindex': '0' }); + + // --- 【修正重點 1】處理 Label 的焦點與按鍵行為 --- + $orbitLabel.on('focusin', function(e) { + var relatedTarget = e.relatedTarget; + // 如果是從選單內部退回來的 (Shift+Tab) + if (relatedTarget && ($searchArea.find(relatedTarget).length > 0)) { + $searchArea.removeClass('show'); + $(this).attr('aria-expanded', 'false'); + } else { + // 正向進入 + $searchArea.addClass('show'); + $(this).attr('aria-expanded', 'true'); + } + }); + + // 強制偵測:在 Label 上按下 Shift+Tab 代表要離開這整塊,立即收合 + $orbitLabel.on('keydown', function(e) { + if (e.shiftKey && e.keyCode === 9) { // Shift + Tab + $searchArea.removeClass('show'); + $searchArea.find('ul').removeClass('show'); + $(this).attr('aria-expanded', 'false'); + } + }); + + // --- 【修正重點 2】處理選單內第一個元素的 Shift+Tab --- + $firstInput.on('keydown', function(e) { + if (e.shiftKey && e.keyCode === 9) { // 在第一個輸入框按 Shift + Tab + // 讓它自然回到 Label,Label 的 focusin 會接手處理收合 + // 這裡不做額外動作,交給上面的 focusin 邏輯 + } + }); + + // --- 【修正重點 3】處理離開大區塊(往後 Tab)的狀態清除 --- + $searchArea.on('focusout', function() { + var $thisArea = $(this); + setTimeout(function() { + if (!$thisArea.is(':focus-within') && !$(document.activeElement).is($orbitLabel)) { + $thisArea.removeClass('show'); + $thisArea.find('ul').removeClass('show'); + $orbitLabel.attr('aria-expanded', 'false'); + $('#languagebutton').attr('aria-expanded', 'false'); + } + }, 150); + }); + + // 點擊行為 + $orbitLabel.on('click', function() { + var isOpen = $searchArea.hasClass('show'); + $searchArea.toggleClass('show', !isOpen); + $(this).attr('aria-expanded', !isOpen); + }); + + // RWD 位置搬移 + function moveSearch() { + if ($(window).width() < 767) { + $searchArea.insertAfter('label[for="open-orbit-nav"]'); + } else { + $searchArea.appendTo('.orbit-bar-inner'); + } + } + moveSearch(); + $(window).resize(moveSearch); +}); + +// 2. 語言按鈕與手機版選單補強 +$(function() { + function fixLanguageA11y() { + var isEn = document.documentElement.lang === 'en'; + var correctTitle = isEn ? 'Open language menu' : '在本視窗開啟語言選單'; + var $desktopBtn = $('#languagebutton'); + var $langLi = $('#language-li'); + var $langUl = $('#language-li ul'); + + // ============================================= + // ✅ 新增 GN1210101E:繁體中文 li 補上可聚焦 + // 桌面版 + 手機版都處理 + // ============================================= + var $activeLis = $langUl.find('li.active') + .add($('#language-li-ul').find('li.active')); + + $activeLis.each(function() { + var $li = $(this); + if ($li.find('a, button').length === 0) { + var activeText = $li.text().trim(); + $li.html( + '' + + activeText + + '' + ); + } + }); + + // ============================================= + // Desktop 語言按鈕 + // ============================================= + if ($desktopBtn.length > 0) { + $desktopBtn.attr({ + 'aria-expanded': 'false', + 'role': 'button', + 'aria-haspopup': 'true', + 'title': correctTitle + }); + $desktopBtn.removeAttr('aria-label'); + + function openLangMenu() { + $langUl.addClass('show'); + $desktopBtn.attr('aria-expanded', 'true'); + $('.orbit-bar-search-sign-language').addClass('show'); + } + function closeLangMenu() { + $langUl.removeClass('show'); + $desktopBtn.attr('aria-expanded', 'false'); + } + + // 原有:focus 展開 + $desktopBtn.on('focus', function() { + openLangMenu(); + }); + + // ✅ 新增 GN1210100E:Enter / Space 切換、Escape 收合 + $desktopBtn.on('keydown', function(e) { + if (e.which === 13 || e.which === 32) { + e.preventDefault(); + $langUl.hasClass('show') ? closeLangMenu() : openLangMenu(); + } + if (e.which === 27) { + closeLangMenu(); + $desktopBtn.focus(); + } + }); + + // 原有:click 切換 + $desktopBtn.on('click', function(e) { + e.preventDefault(); + $langUl.hasClass('show') ? closeLangMenu() : openLangMenu(); + }); + + // ✅ 新增:選單內 Escape 跳回按鈕 + $langUl.find('a').on('keydown', function(e) { + if (e.which === 27) { + e.preventDefault(); + closeLangMenu(); + $desktopBtn.focus(); + } + }); + + // 原有:焦點離開整個 language-li 時收合 + $langLi.on('focusout', function() { + var $container = $(this); + setTimeout(function() { + if (!$container.is(':focus-within')) { + closeLangMenu(); + } + }, 150); + }); + } + + // ============================================= + // 手機版選單補強(原有邏輯完整保留) + // ============================================= + var $mobileBtn = $('.mobile-button'); + if ($mobileBtn.length > 0) { + $mobileBtn.attr({ 'role': 'button', 'tabindex': '0', 'aria-haspopup': 'true', 'aria-expanded': 'false' }); + $mobileBtn.on('focus', function() { + $(this).closest('li').find('ul').addClass('show'); + $(this).attr('aria-expanded', 'true'); + }); + $mobileBtn.on('keydown', function(e) { + if (e.which === 13 || e.which === 32) { + e.preventDefault(); + var $ul = $(this).closest('li').find('ul'); + $ul.toggleClass('show'); + $(this).attr('aria-expanded', $ul.hasClass('show') ? 'true' : 'false'); + } + }); + $('#language-li-ul').on('focusout', function() { + var $container = $(this); + setTimeout(function() { + if (!$container.is(':focus-within')) { + $container.find('ul').removeClass('show'); + $mobileBtn.attr('aria-expanded', 'false'); + } + }, 150); + }); + } + + // ============================================= + // 原有:MutationObserver 強制鎖定 title + // ============================================= + var target = document.getElementById('languagebutton'); + if (target) { + var observer = new MutationObserver(function() { + if (target.getAttribute('title') !== correctTitle) { + target.setAttribute('title', correctTitle); + } + }); + observer.observe(target, { attributes: true, attributeFilter: ['title'] }); + } + } + + setTimeout(fixLanguageA11y, 600); +}); +// rwd左上選單無障礙 +$(function() { + /** + * 修正:當焦點離開整個區塊(含語言選單最後一項)時,關閉大選單 + */ + function fixSearchMenuFocusOut() { + var $searchArea = $('.orbit-bar-search-sign-language'); + var $orbitLabel = $('label[for="open-orbit-nav"]'); + var $langBtn = $('#languagebutton'); + + // 使用 focusout 監聽整個搜尋/語言區域 + $searchArea.on('focusout', function(e) { + // 關鍵:使用 setTimeout 讓 document.activeElement 抓到下一個獲焦元素 + setTimeout(function() { + // 如果目前的焦點不在 $searchArea 裡面,也不是回到觸發的 $orbitLabel 上 + if (!$searchArea.is(':focus-within') && !$(document.activeElement).is($orbitLabel)) { + + // 1. 移除大區塊顯示 + $searchArea.removeClass('show'); + + // 2. 移除子層語言選單顯示 + $searchArea.find('ul').removeClass('show'); + + // 3. 狀態重置為「折疊」供語音報讀 + $orbitLabel.attr('aria-expanded', 'false'); + $langBtn.attr('aria-expanded', 'false'); + } + }, 50); + }); + + // 桌面版 Language 按鈕特殊處理:焦點移入時 + $langBtn.on('focus', function() { + // 確保父層搜尋區塊是顯示的 (針對從別處直接 tab 過來的情況) + $searchArea.addClass('show'); + $(this).attr('aria-expanded', 'true'); + }); + + // 針對手機版 mobile-button (span) 同理處理 + $('.mobile-button').on('focusout', function() { + var $mobileParent = $('#language-li-ul'); + setTimeout(function() { + if (!$mobileParent.is(':focus-within')) { + $mobileParent.find('ul').removeClass('show'); + $('.mobile-button').attr('aria-expanded', 'false'); + } + }, 50); + }); + } + + setTimeout(fixSearchMenuFocusOut, 600); +}); //post $(document).ready(function () { setTimeout(function () { diff --git a/assets/stylesheets/template/base/_global.scss b/assets/stylesheets/template/base/_global.scss index 785a518..bcc6887 100644 --- a/assets/stylesheets/template/base/_global.scss +++ b/assets/stylesheets/template/base/_global.scss @@ -3,7 +3,7 @@ @import "../initial"; @import "variables"; .fa-classic, .fa-regular, .fa-solid, .far, .fas ,.fa{ - font-family: var(--fa-style-family, "FontAwesome"); + font-family: "FontAwesome"; } #orbit-bar .orbit-bar-inner > label:focus, #orbit-bar .orbit-bar-inner > label.focus{ .orbit-bar-search-sign-language{ @@ -160,7 +160,6 @@ td { // } a.btn-primary { border-radius: 2em; - behavior: url("/assets/ie_support/PIE2/PIE.htc"); padding: 1em 1.8em; margin-bottom: 1em; font-size: 0.8125rem; @@ -177,7 +176,7 @@ a.btn-primary { &:hover { color: #fff; // box-shadow:$theme-color-third 0 0px 0px 40px inset; - background: radial-gradient(circle at 60% 90%, #dea797, transparent 60%), radial-gradient(circle at 10px 10px, #eb8467, transparent 25%), #ec6641; + background: radial-gradient(circle at 60% 90%, #ea8466, transparent 60%), radial-gradient(circle at 10px 10px, #e66c4a, transparent 25%), #cc3d00; } } .theadsearch2{ diff --git a/assets/stylesheets/template/base/_variables.scss b/assets/stylesheets/template/base/_variables.scss index ef8bd7b..22aeca1 100644 --- a/assets/stylesheets/template/base/_variables.scss +++ b/assets/stylesheets/template/base/_variables.scss @@ -17,8 +17,8 @@ $theme-blue: #003d7e; $theme-color-main: #333333; $theme-color-second:#00437c; -$theme-color-third: #ec6641; -$theme-color-green: #ec6641; +$theme-color-third: #b33e00; +$theme-color-green: #b33e00; $theme-color-hover:#00437c; // Font stacks diff --git a/assets/stylesheets/template/modules/menu.scss b/assets/stylesheets/template/modules/menu.scss index aff14ed..18674cc 100644 --- a/assets/stylesheets/template/modules/menu.scss +++ b/assets/stylesheets/template/modules/menu.scss @@ -303,7 +303,7 @@ &:hover { & > a { color:#fff; - background: radial-gradient(circle at 60% 90%, #dea797, transparent 60%), radial-gradient(circle at 10px 10px, #eb8467, transparent 25%), #ec6641; + background: radial-gradient(circle at 60% 90%, #d95c37, transparent 60%),radial-gradient(circle at 10px 10px, #e65c36, transparent 25%),#cc3d00; box-shadow:none; &:after{ width:100%; @@ -376,6 +376,7 @@ color:#fff; font-weight: bold; position: relative; + text-shadow: 2px 2px 5px #000000; } &:hover { @@ -422,7 +423,7 @@ } &:hover { - background: radial-gradient(circle at 60% 90%, #dea797, transparent 60%), radial-gradient(circle at 10px 10px, #eb8467, transparent 25%), #ec6641; + background: radial-gradient(circle at 60% 90%, #d95c37, transparent 60%),radial-gradient(circle at 10px 10px, #e65c36, transparent 25%),#cc3d00; @media(max-width: 769px){ a,i { color: #fff; diff --git a/assets/stylesheets/template/modules/web_resource.scss b/assets/stylesheets/template/modules/web_resource.scss index 29fc367..01d4c90 100644 --- a/assets/stylesheets/template/modules/web_resource.scss +++ b/assets/stylesheets/template/modules/web_resource.scss @@ -237,7 +237,7 @@ // background:linear-gradient(180deg, #ec6641 0, #e8f6ff 100%); background: radial-gradient(circle at 60% 90%, #ffe6df, transparent 60%), radial-gradient(circle at 20% 10%, #f5bfb0de, transparent 25%), #ec66418b; } - background:$theme-color-third; + background:#ff8747; -webkit-transition: .3s all ease; -o-transition: .3s all ease; transition: .3s all ease; @@ -250,11 +250,11 @@ } .link-img-wrap{ border-radius:10em; - behavior: url("/assets/ie_support/PIE2/PIE.htc"); + overflow: hidden; &:hover{ border-radius:2em; - behavior: url("/assets/ie_support/PIE2/PIE.htc"); + -webkit-transition: .3s all ease; -o-transition: .3s all ease; transition: .3s all ease; @@ -306,7 +306,7 @@ background: #f8f8f8; cursor: pointer; border-radius: 12px; - behavior: url("/assets/ie_support/PIE2/PIE.htc"); + -webkit-box-shadow: 0 30px 40px 0 #7070700f; box-shadow: 0 30px 40px 0 #7070700f; position: relative; @@ -338,11 +338,11 @@ width: 100%; height: 100%; border-radius: 12px; - behavior: url("/assets/ie_support/PIE2/PIE.htc"); + padding: 2px; background: linear-gradient(45deg, white, #E7E8EA); -pie-background: linear-gradient(45deg, white, #E7E8EA); - behavior: url("/assets/ie_support/PIE2/PIE.htc"); + -webkit-mask: -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff)) content-box, -webkit-gradient(linear, left top, left bottom, color-stop(0, #fff)); -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; @@ -377,7 +377,7 @@ overflow: hidden; &:hover{ border-radius:2em; - behavior: url("/assets/ie_support/PIE2/PIE.htc"); + -webkit-transition: .3s all ease; -o-transition: .3s all ease; transition: .3s all ease; @@ -411,7 +411,7 @@ } .link-img-wrap{ border-radius: 2em; - behavior: url("/assets/ie_support/PIE2/PIE.htc"); + overflow: hidden; &:hover{ img{ @@ -471,7 +471,7 @@ .widget-content { text-align: center; border-radius: 4px; - behavior: url("/assets/ie_support/PIE2/PIE.htc"); + padding-top: calc(.6em + 2px); padding-bottom: calc(.6em + 2px); display: block; @@ -510,7 +510,7 @@ padding: 1em; padding-left: 2em; border-radius: 15px; - behavior: url("/assets/ie_support/PIE2/PIE.htc"); + background-color: #f9f9f9ed; } .widget-content { diff --git a/modules/ad_banner/_ad_banner_widget2.html.erb b/modules/ad_banner/_ad_banner_widget2.html.erb index aaae810..82f59ed 100644 --- a/modules/ad_banner/_ad_banner_widget2.html.erb +++ b/modules/ad_banner/_ad_banner_widget2.html.erb @@ -29,7 +29,9 @@ - +