diff --git a/assets/javascripts/app.js b/assets/javascripts/app.js
index 18e424e..5dfbb49 100644
--- a/assets/javascripts/app.js
+++ b/assets/javascripts/app.js
@@ -398,25 +398,8 @@
// }else{
// $('.header-buttom').appendTo($('.dropdowns'));
// }
- function forFreeGo() {
-
- setTimeout(function() {
- // 針對該特定類別進行檢查
- $('.w-annc__widget-title').each(function() {
- var $title = $(this);
-
- // 取得內部的純文字內容(移除前後空白)
- var textContent = $.trim($title.text());
-
- // 檢查是否含有具體的「內容」元素,例如圖片、iframe 或 icon
- // 排除掉掉你範例中那種用來排版的空 div 或空 span
- var hasRealContent = $title.find('img, i, svg, canvas').length > 0;
-
- // 判斷條件:如果沒有文字且沒有具體內容元素
- if (textContent === "" && !hasRealContent) {
- $title.remove();
- }
- });
+ function forFreeGo() {
+ setTimeout(function() {
$('h1, h2, h3, h4, h5, h6').each(function() {
var $heading = $(this);
@@ -425,8 +408,8 @@
$heading.remove();
}
});
- }, 500);
- //zoom
+ }, 500);
+ //zoom
$(function () {
$('.fnav a').each(function () {
const $a = $(this);
@@ -499,479 +482,688 @@
$el.remove();
}
});
- //表單legend
- $("fieldset").each(function () {
- const $fieldset = $(this);
- const hasLegend = $fieldset.children("legend").length > 0;
+ //表單legend
+ $("fieldset").each(function () {
+ const $fieldset = $(this);
+ const hasLegend = $fieldset.children("legend").length > 0;
- if (!hasLegend) {
- // 嘗試抓最上層的群組標題,例如 "Apply"
- const headingText = $fieldset.find(".form-group:first").text().trim() || "表單填寫";
+ if (!hasLegend) {
+ // 嘗試抓最上層的群組標題,例如 "Apply"
+ const headingText = $fieldset.find(".form-group:first").text().trim() || "表單填寫";
- // 插入 legend 為第一個元素
- $fieldset.prepend(``);
- }
- });
-
- // 處理「上一頁」按鈕
- $(".cmdBackward").each(function () {
- $(this)
- .attr("title", "上一頁")
- .attr("aria-label", "上一頁");
-
- if ($(this).find(".sr-only").length === 0) {
- $(this).append('上一頁');
- }
-
- $(this).find("i").attr("aria-hidden", "true");
- $(this).find(".icon").attr("aria-hidden", "true");
- });
-
- // 處理「下一頁」按鈕
- $(".cmdForward").each(function () {
- $(this)
- .attr("title", "下一頁")
- .attr("aria-label", "下一頁");
-
- if ($(this).find(".sr-only").length === 0) {
- $(this).append('下一頁');
- }
-
- $(this).find("i").attr("aria-hidden", "true");
- $(this).find(".icon").attr("aria-hidden", "true");
- });
-
- $('.pagination li.active a').attr('aria-current', 'page');
+ // 插入 legend 為第一個元素
+ $fieldset.prepend(``);
+ }
+ });
- $('path').each(function () {
+ // 處理「上一頁」按鈕
+ $(".cmdBackward").each(function () {
$(this)
- .attr('aria-hidden', 'true')
- .attr('focusable', 'false')
- .attr('tabindex', '-1');
+ .attr("title", "上一頁")
+ .attr("aria-label", "上一頁");
+
+ if ($(this).find(".sr-only").length === 0) {
+ $(this).append('上一頁');
+ }
+
+ $(this).find("i").attr("aria-hidden", "true");
+ $(this).find(".icon").attr("aria-hidden", "true");
});
- $('.controlplay a[role="radio"]').on('click', function () {
- // 取消所有的 aria-checked 並還原文字
- $('.controlplay a[role="radio"]').attr('aria-checked', 'false');
- $('.controlplay a[role="radio"] span').each(function () {
- var text = $(this).text().replace('(已選取)', '');
- $(this).text(text);
+ // 處理「下一頁」按鈕
+ $(".cmdForward").each(function () {
+ $(this)
+ .attr("title", "下一頁")
+ .attr("aria-label", "下一頁");
+
+ if ($(this).find(".sr-only").length === 0) {
+ $(this).append('下一頁');
+ }
+
+ $(this).find("i").attr("aria-hidden", "true");
+ $(this).find(".icon").attr("aria-hidden", "true");
});
-
- // 設定目前被點擊的按鈕為已選取
- $(this).attr('aria-checked', 'true');
- var selectedText = $(this).text().trim();
- $(this).find('span').text(selectedText + '(已選取)');
- });
- // 遍历所有的 .s-annc__tag-wrap 元素
- $('.s-annc__tag-wrap').each(function() {
- // 遍历 .s-annc__tag-wrap 下的每个 a 元素
- $(this).find('a').each(function() {
- // 如果 .s-annc__tag 元素为空或没有内容
- if ($(this).find('.s-annc__tag').is(':empty')) {
- // 移除该 a 元素
- $(this).remove();
- }
+
+ $('.pagination li.active a').attr('aria-current', 'page');
+
+ $('path').each(function () {
+ $(this)
+ .attr('aria-hidden', 'true')
+ .attr('focusable', 'false')
+ .attr('tabindex', '-1');
});
- });
- $('.w-ba-banner__caption li button').each(function (index) {
- const $slide = $('.w-ba-banner__slide').eq(index);
- const title = $slide.attr('data-cycle-title')?.trim();
+ $('.controlplay a[role="radio"]').on('click', function () {
+ // 取消所有的 aria-checked 並還原文字
+ $('.controlplay a[role="radio"]').attr('aria-checked', 'false');
+ $('.controlplay a[role="radio"] span').each(function () {
+ var text = $(this).text().replace('(已選取)', '');
+ $(this).text(text);
+ });
- if (title) {
- const fullText = title + '的pager';
- $(this).attr('aria-label', fullText);
- $(this).attr('title', fullText);
- }
+ // 設定目前被點擊的按鈕為已選取
+ $(this).attr('aria-checked', 'true');
+ var selectedText = $(this).text().trim();
+ $(this).find('span').text(selectedText + '(已選取)');
});
- // 當 focus 到 menu link 時,顯示對應 ul
- $('.sitemenu-item > a').on('focus', function () {
- $(this).siblings('ul').addClass('show');
- });
-
- // 當 focus 離開最後一個子選單 link 時,移除 .show
- $('.sitemenu-item').each(function () {
- const $submenuLinks = $(this).find('ul a');
-
- if ($submenuLinks.length > 0) {
- $submenuLinks.last().on('blur', function () {
- // 當最後一個子項 blur 時關閉 ul
- $(this).closest('ul').removeClass('show');
- });
- } else {
- // 若沒有子項,當主選單項 blur 也隱藏
- $(this).find('> a').on('blur', function () {
- $(this).siblings('ul').removeClass('show');
- });
- }
- });
- if (document.documentElement.lang === 'zh_tw') {
- document.documentElement.lang = 'zh-Hant';
- }
- //tab鍵按下
- $(document).on('keydown', function(e) {
- if (e.key === "Tab" || e.keyCode === 9) {
- $('.header-nav, .dropdowns').css('display', 'block');
- }
- });
-
- //li被hover
- function handleHover() {
- if ($(window).width() > 769) {
- $('li').off('mouseenter mouseleave').hover(
- function() {
- $(this).children('ul').addClass('show');
- },
- function() {
- $(this).children('ul').removeClass('show');
- }
- );
- } else {
- $('li').off('mouseenter mouseleave'); // 移除 hover 事件
- }
- }
-
- // 先執行一次
- handleHover();
-
- // 監聽視窗大小變化
- $(window).on('resize', function() {
- handleHover();
- });
- //刪除空的h1
- $('h1').each(function() {
- if ($(this).text().trim() === '') {
- $(this).remove();
- }
- });
- //refresh_btn加上aria-label
- $('#refresh_btn').each(function() {
- var $this = $(this);
-
- // 如果 button 尚未有 aria-label,則新增
- if (!$this.attr('aria-label')) {
- $this.attr('aria-label', '重新整理');
- }
- });
- //無障礙會員表格刪除沒有顯示的th
- $('.i-member-tr-head').each(function() {
- if ($(this).css('display') === 'none') {
- $(this).remove();
- }
- });
- //無障礙公告a是空的
- $('.w-annc__subtitle').each(function () {
- var $this = $(this);
- var $link = $this.find('a');
-
- // 檢查 a 是否存在,且去除空白後是否為空字串
- if ($link.length && $link.text().trim() === '') {
- $this.remove(); // 移除外層 .w-annc__subtitle
- }
- });
- //無障礙單位轉換
- $("[style*='font-size']").each(function() {
- var fontSize = $(this).css("font-size");
- if (fontSize.includes("px")) {
- var pxValue = parseFloat(fontSize); // 取得數值
- var emValue = pxValue / 16; // 假設 1em = 16px
- $(this).css("font-size", emValue + "em");
- }
- });
- $("[style*='font-size']").each(function() {
- var fontSize = $(this).css("font-size");
- if (fontSize.includes("pt")) {
- var ptValue = parseFloat(fontSize); // 取得數值
- var emValue = ptValue / 12; // 1em = 12pt(一般轉換標準)
- $(this).css("font-size", emValue + "em");
- }
- });
- $("[style*='font-size']").each(function() {
- var styleAttr = $(this).attr("style"); // 取得原始 style 屬性字串
- var match = styleAttr.match(/font-size\s*:\s*(\d+(?:\.\d+)?)pt/i);
- if (match) {
- var ptValue = parseFloat(match[1]);
- var emValue = ptValue / 12;
- // 替換 style 屬性字串中的 pt 為 em
- var newStyle = styleAttr.replace(/font-size\s*:\s*\d+(?:\.\d+)?pt/i, `font-size: ${emValue}em`);
- $(this).attr("style", newStyle);
- }
- });
- //表格scope
- $("table").each(function() {
- $(this).find("tr").each(function(rowIndex) {
- $(this).find("th").each(function(colIndex) {
- if (rowIndex === 0) {
- // 第一列的 th,適用於該欄
- $(this).attr("scope", "col");
- } else if (colIndex === 0) {
- // 其他列的第一個 th,適用於該行
- $(this).attr("scope", "row");
- }
- });
- });
- });
- $(".banner-pager button").addClass('banner-pagerbtn');
- $(".banner-pager button").attr("type","button");
- $(".banner-pager button").append('下一張');
- $("button").attr("role", "button");
- $("select").attr("title","選擇類別");
- $(".jarallax-video-audio").attr("role", "button");
- $('button').each(function() {
- var $this = $(this);
- if (!$this.attr('title') || $this.attr('title').trim() === '') {
- $this.attr('title', '按鈕');
- }
- });
- $('img').each(function() {
- var $this = $(this);
- if (!$this.attr('alt') || $this.attr('alt').trim() === '') {
- $this.attr('alt', '這是一張圖片');
- }
- });
- $('img').each(function() {
- var $this = $(this);
- if (!$this.attr('title') || $this.attr('title').trim() === '') {
- $this.attr('title', '這是一張圖片');
- }
- });
- $('img').each(function() {
- var $this = $(this);
-
- // 檢查 img 的 alt 屬性是否為 "裝飾圖片"
- if ($this.attr('alt') === "裝飾圖片" || $this.attr('title') === "裝飾圖片") {
- // 設定 alt 為空字串
- $this.attr('alt', '');
-
- // 移除 title 屬性
- $this.removeAttr('title');
+ // 遍历所有的 .s-annc__tag-wrap 元素
+ $('.s-annc__tag-wrap').each(function() {
+ // 遍历 .s-annc__tag-wrap 下的每个 a 元素
+ $(this).find('a').each(function() {
+ // 如果 .s-annc__tag 元素为空或没有内容
+ if ($(this).find('.s-annc__tag').is(':empty')) {
+ // 移除该 a 元素
+ $(this).remove();
}
});
- $(".w-annc__img-wrap a").each(function () {
- var $this = $(this);
- // 確保 內沒有文字節點 (避免重複添加)
- if ($this.text().trim() === "") {
- $this.append('公告圖片');
+ });
+
+ $('.w-ba-banner__caption li button').each(function (index) {
+ const $slide = $('.w-ba-banner__slide').eq(index);
+ const title = $slide.attr('data-cycle-title')?.trim();
+
+ if (title) {
+ const fullText = title + '的pager';
+ $(this).attr('aria-label', fullText);
+ $(this).attr('title', fullText);
}
+ });
+ // 當 focus 到 menu link 時,顯示對應 ul
+ $('.sitemenu-item > a').on('focus', function () {
+ $(this).siblings('ul').addClass('show');
});
- $(".widget-link__widget-title").each(function () {
+
+ // 當 focus 離開最後一個子選單 link 時,移除 .show
+ $('.sitemenu-item').each(function () {
+ const $submenuLinks = $(this).find('ul a');
+
+ if ($submenuLinks.length > 0) {
+ $submenuLinks.last().on('blur', function () {
+ // 當最後一個子項 blur 時關閉 ul
+ $(this).closest('ul').removeClass('show');
+ });
+ } else {
+ // 若沒有子項,當主選單項 blur 也隱藏
+ $(this).find('> a').on('blur', function () {
+ $(this).siblings('ul').removeClass('show');
+ });
+ }
+ });
+ if (document.documentElement.lang === 'zh_tw') {
+ document.documentElement.lang = 'zh-Hant';
+ }
+ //tab鍵按下
+ $(document).on('keydown', function(e) {
+ if (e.key === "Tab" || e.keyCode === 9) {
+ $('.header-nav, .dropdowns').css('display', 'block');
+ }
+ });
+
+ function handleHover() {
+ // 先統一移除舊事件,避免重複綁定
+ $('li').off('mouseenter mouseleave focusin focusout');
+
+ if ($(window).width() > 769) {
+ // 1. 處理滑鼠 Hover
+ $('li').hover(
+ function() { $(this).children('ul').addClass('show'); },
+ function() { $(this).children('ul').removeClass('show'); }
+ );
+
+ // 2. 處理鍵盤 Tab 聚焦 (關鍵修正)
+ $('li').on('focusin', function() {
+ // 當焦點進入 li 或其子元素時,顯示選單
+ $(this).children('ul').addClass('show');
+ });
+
+ $('li').on('focusout', function() {
+ var $this = $(this);
+ // 延遲偵測焦點是否真的「離開」了這個 li 區塊
+ setTimeout(function() {
+ // 如果新的焦點不在當前這個 li 裡面,才移除 show
+ if ($this.find(':focus').length === 0) {
+ $this.children('ul').removeClass('show');
+ }
+ }, 10);
+ });
+ }
+ }
+
+ // 初始化與 Resize 監聽保持不變
+ handleHover();
+ $(window).on('resize', function() {
+ handleHover();
+ });
+ //刪除空的h1
+ $('h1').each(function() {
+ if ($(this).text().trim() === '') {
+ $(this).remove();
+ }
+ });
+ //refresh_btn加上aria-label
+ $('#refresh_btn').each(function() {
+ var $this = $(this);
+
+ // 如果 button 尚未有 aria-label,則新增
+ if (!$this.attr('aria-label')) {
+ $this.attr('aria-label', '重新整理');
+ }
+ });
+ //無障礙會員表格刪除沒有顯示的th
+ $('.i-member-tr-head').each(function() {
+ if ($(this).css('display') === 'none') {
+ $(this).remove();
+ }
+ });
+ //無障礙公告a是空的
+ $('.w-annc__subtitle').each(function () {
+ var $this = $(this);
+ var $link = $this.find('a');
+
+ // 檢查 a 是否存在,且去除空白後是否為空字串
+ if ($link.length && $link.text().trim() === '') {
+ $this.remove(); // 移除外層 .w-annc__subtitle
+ }
+ });
+ //無障礙單位轉換
+ $(function() {
+ $('style:contains("font-size")').each(function() {
+ let css = $(this).html();
+ css = css.replace(/font-size\s*:\s*([\d.]+)px\s*;?/gi, (_, px) =>
+ `font-size: ${(parseFloat(px) / 16).toFixed(3)}em;`
+ );
+ $(this).html(css);
+ });
+ });
+
+ $("[style*='font-size']").each(function() {
+ var fontSize = $(this).css("font-size");
+ if (fontSize.includes("px")) {
+ var pxValue = parseFloat(fontSize); // 取得數值
+ var emValue = pxValue / 16; // 假設 1em = 16px
+ $(this).css("font-size", emValue + "em");
+ }
+ });
+ $("[style*='font-size']").each(function() {
+ var fontSize = $(this).css("font-size");
+ if (fontSize.includes("pt")) {
+ var ptValue = parseFloat(fontSize); // 取得數值
+ var emValue = ptValue / 12; // 1em = 12pt(一般轉換標準)
+ $(this).css("font-size", emValue + "em");
+ }
+ });
+ $("[style*='font-size']").each(function() {
+ var styleAttr = $(this).attr("style"); // 取得原始 style 屬性字串
+ var match = styleAttr.match(/font-size\s*:\s*(\d+(?:\.\d+)?)pt/i);
+ if (match) {
+ var ptValue = parseFloat(match[1]);
+ var emValue = ptValue / 12;
+ // 替換 style 屬性字串中的 pt 為 em
+ var newStyle = styleAttr.replace(/font-size\s*:\s*\d+(?:\.\d+)?pt/i, `font-size: ${emValue}em`);
+ $(this).attr("style", newStyle);
+ }
+ });
+ //表格scope
+ $("table").each(function() {
+ $(this).find("tr").each(function(rowIndex) {
+ $(this).find("th").each(function(colIndex) {
+ if (rowIndex === 0) {
+ // 第一列的 th,適用於該欄
+ $(this).attr("scope", "col");
+ } else if (colIndex === 0) {
+ // 其他列的第一個 th,適用於該行
+ $(this).attr("scope", "row");
+ }
+ });
+ });
+ });
+ $(".banner-pager button").addClass('banner-pagerbtn');
+ $(".banner-pager button").attr("type","button");
+ $(".banner-pager button").append('下一張');
+ $("button").attr("role", "button");
+ $("select").attr("title","選擇類別");
+ $(".jarallax-video-audio").attr("role", "button");
+ $('button').each(function() {
+ var $this = $(this);
+ if (!$this.attr('title') || $this.attr('title').trim() === '') {
+ $this.attr('title', '按鈕');
+ }
+ });
+ //img無障礙
+$(function() {
+ /**
+ * 圖片無障礙 AA 級補強 (人工檢測優化版)
+ * 1. 處理裝飾性圖片:清空 alt 並移除 title。
+ * 2. 解決資訊冗餘:若 alt 與 title 內容相同,移除 title,避免重複朗讀。
+ * 3. 自動補強缺失 alt:從父層 title 或鄰近標題文字擷取。
+ */
+ function fixImageAccessibility() {
+ $('img').each(function() {
+ var $img = $(this);
+ var currentAlt = ($img.attr('alt') || '').trim();
+ var currentTitle = ($img.attr('title') || '').trim();
+
+ // --- 1. 處理「裝飾性圖片」標註 (最高優先權) ---
+ if (currentAlt === "裝飾圖片" || currentTitle === "裝飾圖片") {
+ $img.attr('alt', '');
+ $img.removeAttr('title');
+ return; // 跳過此圖
+ }
+
+ // --- 2. 解決【alt 與 title 相同】的問題 (人工檢測重點) ---
+ // 只要兩者內容一致且不為空,就移除 title,保留 alt
+ if (currentAlt !== '' && currentAlt === currentTitle) {
+ $img.removeAttr('title');
+ // 重新更新變數值供後續邏輯使用
+ currentTitle = '';
+ }
+
+ // --- 3. 處理「缺失 alt」或「空的 alt」補強邏輯 ---
+ if (currentAlt === '') {
+ let finalAlt = "";
+
+ // A. 嘗試從父層 (如 ) 的 title 抓取描述
+ var parentTitle = $img.parent().attr('title');
+
+ // B. 嘗試抓取同區域內的標題文字
+ var nearbyTitle = $img.closest('a').find('h1, h2, h3, h4, h5, h6').first().text().trim();
+
+ if (parentTitle && parentTitle.trim() !== '') {
+ finalAlt = parentTitle.trim();
+ } else if (nearbyTitle !== '') {
+ finalAlt = nearbyTitle;
+ }
+
+ // 寫入最終 alt 結果
+ // 如果 finalAlt 仍為空,則設為 "" (符合 AA 規範,視為裝飾圖)
+ $img.attr('alt', finalAlt);
+
+ // --- 4. 二次清理:補強後的 alt 如果又跟原本的 title 一樣,則移除 title ---
+ if (currentTitle !== '' && currentTitle === finalAlt) {
+ $img.removeAttr('title');
+ }
+ }
+ });
+ }
+
+ // 延遲執行確保圖片與動態內容已渲染
+ setTimeout(fixImageAccessibility, 500);
+});
+ $(".w-annc__img-wrap a").each(function () {
+ var $this = $(this);
+ // 確保 內沒有文字節點 (避免重複添加)
+ if ($this.text().trim() === "") {
+ $this.append('公告圖片');
+ }
+ });
+ $(".widget-link__widget-title").each(function () {
+ if ($(this).text().trim() === "") {
+ $(this).append('公告標題');
+ }
+ });
+ $(".sitemenu-title").each(function () {
if ($(this).text().trim() === "") {
- $(this).append('公告標題');
+ $(this).append('次選單');
}
});
- $(".sitemenu-title").each(function () {
- if ($(this).text().trim() === "") {
- $(this).append('次選單');
- }
- });
- $(".annc-title").each(function () {
- if ($(this).text().trim() === "") {
- $(this).append('內頁公告標題');
- }
- });
- $(".event-annc-title").each(function () {
- if ($(this).text().trim() === "") {
- $(this).append('內頁活動公告標題');
- }
- });
- $(".show-title").each(function () {
- if ($(this).text().trim() === "") {
- $(this).append('內頁活動公告標題');
- }
- });
- $(".w-annc__widget-title").each(function () {
- if ($(this).text().trim() === "") {
- $(this).append('公告標題');
- }
- });
- $(".widget-title").each(function () {
- if ($(this).text().trim() === "") {
- $(this).append('網路資源標題');
- }
- });
- $(".widget-title").each(function () {
- if ($(this).text().trim() === "") {
- $(this).append('網路資源標題');
- }
- });
- $('input').each(function() {
- var $this = $(this);
- if (!$this.attr('title') || $this.attr('title').trim() === '') {
- $this.attr('title', '網內搜尋');
- }
- });
- $('.rucaptcha-image').each(function() {
- var $button = $(this).next('button'); // 取得緊接在 .rucaptcha-image 之後的 button
- if ($button.length && !$button.attr('aria-label')) {
- $button.attr('aria-label', '播放驗證碼語音');
- }
- });
+ $(".annc-title").each(function () {
+ if ($(this).text().trim() === "") {
+ $(this).append('內頁公告標題');
+ }
+ });
+ $(".event-annc-title").each(function () {
+ if ($(this).text().trim() === "") {
+ $(this).append('內頁活動公告標題');
+ }
+ });
+ $(".show-title").each(function () {
+ if ($(this).text().trim() === "") {
+ $(this).append('內頁活動公告標題');
+ }
+ });
+ $(".w-annc__widget-title").each(function () {
+ if ($(this).text().trim() === "") {
+ $(this).append('公告標題');
+ }
+ });
+ $(".widget-title").each(function () {
+ if ($(this).text().trim() === "") {
+ $(this).append('網路資源標題');
+ }
+ });
+ $(".widget-title").each(function () {
+ if ($(this).text().trim() === "") {
+ $(this).append('網路資源標題');
+ }
+ });
+ $('input').each(function() {
+ var $this = $(this);
+ if (!$this.attr('title') || $this.attr('title').trim() === '') {
+ $this.attr('title', '網內搜尋');
+ }
+ });
+ $('.rucaptcha-image').each(function() {
+ var $button = $(this).next('button'); // 取得緊接在 .rucaptcha-image 之後的 button
+ if ($button.length && !$button.attr('aria-label')) {
+ $button.attr('aria-label', '播放驗證碼語音');
+ }
+ });
//有連結目的之所有a標籤加上aria-label和title
- $('a').each(function () {
- var $a = $(this);
- var href = $a.attr('href');
- if (!href) return;
-
- var hasSrOnly = $a.find('.sr-only').length > 0;
-
- // 若有 .sr-only,移除 aria-label 和 title 避免重複朗讀
- if (hasSrOnly) {
- $a.removeAttr('aria-label');
- $a.removeAttr('title');
- return; // 有 .sr-only 就不做其他處理
- }
-
- // ----- aria-label 邏輯 -----
- if (!$a.attr('aria-label')) {
- let ariaLabel = '';
-
- // 加入開啟方式
- if ($a.attr('target') === '_blank') {
- ariaLabel += '在新視窗開啟 ';
- } else if ($a.attr('target') === '_self') {
- ariaLabel += '在本視窗開啟 ';
+$(function() {
+ /**
+ * 無障礙 AA 級補強最終整合版 (人工檢測完全合格)
+ * 1. 修正語言選單:Tab 到達時顯示「在本視窗開啟語言選單」。
+ * 2. 智慧 Title 策略:
+ * - 長文字:僅保留動作提示 (如: (在本視窗開啟)),避免重複讀取。
+ * - 短文字/標籤:組合 [文字內容] + [動作提示],增強目的識別。
+ * 3. 圖文並存處理:符合 HM1240402E,當有文字時,圖片 alt 設為空值。
+ * 4. 清理無效描述:攔截「這是一張圖片」等不合格內容。
+ */
+ function fixAccessibilityAll() {
+ // --- Part 1: 語言選單修正 (Language Button) ---
+ var $langBtn = $('#languagebutton');
+ if ($langBtn.length > 0) {
+ $langBtn.attr('title', '在本視窗開啟語言選單');
+ $langBtn.removeAttr('aria-label');
}
- // 如果包含圖片且有圖片 title
- if ($a.find('img').length) {
- const imgTitle = $a.find('img').attr('title');
- if (imgTitle) ariaLabel = imgTitle;
- } else {
- const text = $a.text().trim();
- if (text) {
- ariaLabel += text;
- } else if ($a.children('span').length === 1) {
- ariaLabel += $a.children('span').text().trim();
- }
- }
+ // --- Part 2: 全站連結補強 (Links) ---
+ $('a').each(function() {
+ var $a = $(this);
+ var href = $a.attr('href');
+
+ // 基礎攔截
+ if (!href || href.startsWith('javascript:')) return;
- if (ariaLabel) {
- $a.attr('aria-label', ariaLabel);
- }
- }
+ // 1. 獲取內容資訊
+ var linkText = $a.text().replace(/\u00a0/g, '').trim();
+ var $img = $a.find('img');
+ var rawAlt = ($img.length > 0) ? ($img.attr('alt') || '').trim() : '';
+ var forbiddenTexts = ['這是一張圖片', '圖片', 'image', 'photo', '圖示'];
+ var imgAlt = forbiddenTexts.includes(rawAlt) ? '' : rawAlt;
- // ----- title 邏輯 -----
- if (!$a.attr('title')) {
- let titleStr = '';
+ var hasSrOnly = $a.find('.sr-only').length > 0 && $a.find('.sr-only').text().trim().length > 0;
+ var srOnlyText = hasSrOnly ? $a.find('.sr-only').text().trim() : '';
- if ($a.attr('target') === '_blank') {
- titleStr += '在新視窗開啟 ';
- } else if ($a.attr('target') === '_self') {
- titleStr += '在本視窗開啟 ';
- }
+ // 2. 移除空連結
+ if (linkText === '' && $img.length === 0 && !hasSrOnly && !($a.attr('aria-label'))) {
+ $a.remove();
+ return;
+ }
- if ($a.find('img').length) {
- titleStr = '這是一張照片';
- } else {
- const text = $a.text().trim();
- if (text) {
- titleStr += text;
- } else if ($a.children('span').length === 1) {
- titleStr += $a.children('span').text().trim();
- }
- }
+ // 3. 準備視窗提示
+ let windowTask = ($a.attr('target') === '_blank') ? '(在新視窗開啟)' : '(在本視窗開啟)';
- if (titleStr) {
- $a.attr('title', titleStr);
- }
- }
- });
- if (location.href.search('editmode=on') === -1){
- $('a').each(function () {
- const $link = $(this);
- const linkText = $link.text().trim();
+ // 4. 核心邏輯判定
+
+ // 【情況 A:純圖片連結 (無文字)】
+ if (linkText === "" && !hasSrOnly) {
+ if (imgAlt !== "") {
+ // 名字讓圖片 alt 說,title 只放動作提示 (避免重複)
+ $a.attr('title', windowTask);
+ $img.attr('alt', imgAlt);
+ } else {
+ let fallback = $a.attr('aria-label') || '連結';
+ $a.attr('title', (fallback + ' ' + windowTask).trim());
+ $img.attr('alt', fallback);
+ }
+ }
+
+ // 【情況 B:有文字連結】
+ else {
+ /**
+ * 智慧 Title 判斷:
+ * 1. 如果是標籤 (Class 含 label 或 tag) 或文字很短 (<= 6 字)
+ * -> Title 顯示:[文字內容] (動作提示)
+ * 2. 如果是長文章標題或一般長連結
+ * -> Title 僅顯示:(動作提示) 以避免重複朗讀
+ */
+ var isTag = $a.hasClass('label') || $a.hasClass('tag') || $a.find('[class*="tag"]').length > 0 || $a.find('[class*="label"]').length > 0;
+
+ if (linkText.length <= 6 || isTag) {
+ // 短文字或標籤:補全語意
+ $a.attr('title', linkText + " " + windowTask);
+ } else {
+ // 長文字:精簡語意
+ $a.attr('title', windowTask);
+ }
- $link.find('img').each(function () {
+ // 符合規範:圖文並存時,圖片 alt 應為空值
+ if ($img.length > 0) {
+ $img.attr('alt', '');
+ }
+ }
+
+ // 5. 最終清理
+ $a.removeAttr('aria-label');
+ $a.removeAttr('alt'); // a 標籤不應有 alt
+
+ if ($img.length > 0 && forbiddenTexts.includes($img.attr('alt'))) {
+ $img.attr('alt', '');
+ }
+ });
+ }
+
+ // 延遲執行
+ setTimeout(fixAccessibilityAll, 500);
+});
+
+ if (location.href.search('editmode=on') === -1) {
+ // 1. 處理圖片 alt 重複問題 (保持原邏輯但優化)
+ $('a').has('img').each(function () {
+ const $link = $(this);
+ const linkText = $link.text().trim();
+
+ $link.find('img').each(function () {
const $img = $(this);
const altText = $img.attr('alt')?.trim();
- // 如果圖片 alt 是空的,就略過(已符合)
- if (altText === '') return;
-
- // 如果圖片 alt 等於文字內容,就將 alt 清空,避免重複
- if (altText === linkText) {
- $img.attr('alt', '');
+ if (altText && altText === linkText) {
+ $img.attr('alt', '');
}
- });
- });
- $('a').each(function () {
- const $a = $(this);
-
- // 取得可見文字(去掉空白)
- const text = $a.text().replace(/\u00a0/g, '').trim();
-
- // 是否有圖片
- const hasImg = $a.find('img').length > 0;
-
- // 若沒有文字、也沒有圖片 → 移除
- if (text === '' && !hasImg) {
- $a.remove();
- }
});
+ });
}
+ $(function() {
+ function smartFixIcons() {
+ $('i').each(function() {
+ var $icon = $(this);
+ var $parent = $icon.parent();
- // 刪除banner-slide的空連結和空連結目標
- for(var i=0;i<$('.w-ba-banner__slide a').length;i++){
- if($('.w-ba-banner__slide a').eq(i).attr('href')=="")
- $('.w-ba-banner__slide a').eq(i).removeAttr('href');
- if($('.w-ba-banner__slide a').eq(i).attr('target') == "")
- $('.w-ba-banner__slide a').eq(i).removeAttr('target');
- };
- // 幫無標題之iframe加上title
- for(var i=0;i<$('iframe').length;i++)
- if($('iframe').eq(i).attr('title')=="" || $('iframe').eq(i).attr('title')== undefined ){
- if($('iframe').eq(i).attr('src').search('facebook') != -1 )
- $('iframe').eq(i).attr('title','facebook');
- else if($('iframe').eq(i).attr('src').search('google') != -1 )
- $('iframe').eq(i).attr('title','google');
- else if($('iframe').eq(i).attr('src').search('youtube') != -1 )
- $('iframe').eq(i).attr('title','youtube');
- else if($('iframe').eq(i).attr('src').search('twitframe') != -1 )
- $('iframe').eq(i).attr('title','twitter');
- else
- $('iframe').eq(i).attr('title','unknown');
- };
- //button是空的就加上內容
- $('button').each(function() {
- var $this = $(this);
- var titleText = $this.attr('title') || '';
+ // 1. 基本安全:所有圖示先對螢幕閱讀器隱藏 (避免讀出 Unicode 亂碼)
+ $icon.attr('aria-hidden', 'true');
- // 檢查 button 是否是空的(沒有可見文字或子元素)
- if ($this.text().trim() === '' && !$this.children().length && titleText) {
- // 新增隱藏的 span,內容為 title
- $this.append('' + titleText + '');
+ // 2. 檢查:如果已經有 aria-label 或旁邊已有 sr-only,就不重複處理
+ if ($icon.attr('aria-label') || $icon.next('.sr-only').length > 0 || $parent.find('.sr-only').length > 0) {
+ return;
+ }
+
+ var cls = ($icon.attr('class') || '').toLowerCase();
+ var labelText = '';
+
+ // --- 策略 A:常見資訊型圖示 (自動識別內容意義) ---
+ if (cls.includes('calendar')) labelText = '日期:';
+ else if (cls.includes('user') || cls.includes('male')) labelText = '發布者:';
+ else if (cls.includes('tag')) labelText = '標籤:';
+ else if (cls.includes('clock') || cls.includes('time')) labelText = '時間:';
+ else if (cls.includes('map-marker') || cls.includes('location')) labelText = '地點:';
+ else if (cls.includes('phone')) labelText = '電話:';
+ else if (cls.includes('envelope') || cls.includes('mail')) labelText = '信箱:';
+ else if (cls.includes('folder')) labelText = '分類:';
+ else if (cls.includes('eye')) labelText = '瀏覽次數:';
+ else if (cls.includes('download')) labelText = '下載檔案:';
+
+ // --- 策略 B:功能性按鈕 (如果 i 放在 或