'js'
This commit is contained in:
parent
b69db30a4e
commit
e64d5ffc4f
|
|
@ -729,97 +729,37 @@
|
|||
$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; // 跳過此圖
|
||||
}
|
||||
function removeEmptyTitles() {
|
||||
// 定義所有需要檢查的 class
|
||||
const targetClasses = [
|
||||
'.w-annc__widget-title',
|
||||
'.widget-title',
|
||||
'.show-title',
|
||||
'.event-annc-title',
|
||||
'.annc-title',
|
||||
'.sitemenu-title',
|
||||
'.widget-link__widget-title'
|
||||
];
|
||||
|
||||
// --- 2. 解決【alt 與 title 相同】的問題 (人工檢測重點) ---
|
||||
// 只要兩者內容一致且不為空,就移除 title,保留 alt
|
||||
if (currentAlt !== '' && currentAlt === currentTitle) {
|
||||
$img.removeAttr('title');
|
||||
// 重新更新變數值供後續邏輯使用
|
||||
currentTitle = '';
|
||||
}
|
||||
// 將陣列轉換為 jQuery 選擇器字串
|
||||
const selector = targetClasses.join(', ');
|
||||
|
||||
// --- 3. 處理「缺失 alt」或「空的 alt」補強邏輯 ---
|
||||
if (currentAlt === '') {
|
||||
let finalAlt = "";
|
||||
$(selector).each(function() {
|
||||
// 使用 $.trim 移除空格、換行符號
|
||||
// 然後檢查裡面是否完全沒有文字
|
||||
const textContent = $.trim($(this).text());
|
||||
|
||||
// A. 嘗試從父層 (如 <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);
|
||||
if (textContent === "") {
|
||||
// 如果沒有文字,則將整個元素刪除
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
// 執行 function
|
||||
$(document).ready(function() {
|
||||
removeEmptyTitles();
|
||||
});
|
||||
function removeEmptyTitles() {
|
||||
// 定義所有需要檢查的 class
|
||||
const targetClasses = [
|
||||
'.w-annc__widget-title',
|
||||
'.widget-title',
|
||||
'.show-title',
|
||||
'.event-annc-title',
|
||||
'.annc-title',
|
||||
'.sitemenu-title',
|
||||
'.widget-link__widget-title'
|
||||
];
|
||||
|
||||
// 將陣列轉換為 jQuery 選擇器字串
|
||||
const selector = targetClasses.join(', ');
|
||||
|
||||
$(selector).each(function() {
|
||||
// 使用 $.trim 移除空格、換行符號
|
||||
// 然後檢查裡面是否完全沒有文字
|
||||
const textContent = $.trim($(this).text());
|
||||
|
||||
if (textContent === "") {
|
||||
// 如果沒有文字,則將整個元素刪除
|
||||
$(this).remove();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 執行 function
|
||||
$(document).ready(function() {
|
||||
removeEmptyTitles();
|
||||
});
|
||||
$(".w-annc__img-wrap a").each(function () {
|
||||
var $this = $(this);
|
||||
// 確保 <a> 內沒有文字節點 (避免重複添加)
|
||||
|
|
@ -879,99 +819,181 @@
|
|||
$button.attr('aria-label', '播放驗證碼語音');
|
||||
}
|
||||
});
|
||||
//有連結目的之所有a標籤的無障礙處理
|
||||
$(function() {
|
||||
|
||||
/**
|
||||
* 全站無障礙 AA 級補強 (多語系偵測版)
|
||||
* 支援功能:語系自動偵測、HM1240404E 修正、檔案預知類型、圖片替代文字
|
||||
*/
|
||||
function fixAccessibilityAll() {
|
||||
// 1. 偵測目前頁面語系 (優先抓取 html lang,若無則預設為 zh-Hant)
|
||||
var pageLang = $('html').attr('lang') || 'zh-Hant';
|
||||
var isEn = pageLang.toLowerCase().startsWith('en');
|
||||
|
||||
// 2. 定義語系對應字典
|
||||
var i18n = {
|
||||
langBtn: isEn ? 'Open language menu in this window' : '在本視窗開啟語言選單',
|
||||
newWin: isEn ? '(Open in new window)' : '(在新視窗開啟)',
|
||||
selfWin: isEn ? '(Open in this window)' : '(在本視窗開啟)',
|
||||
link: isEn ? 'Link' : '連結'
|
||||
};
|
||||
|
||||
// --- Part 1: 語言選單修正 ---
|
||||
var $langBtn = $('#languagebutton');
|
||||
if ($langBtn.length > 0) {
|
||||
$langBtn.attr('title', i18n.langBtn);
|
||||
$langBtn.removeAttr('aria-label');
|
||||
}
|
||||
|
||||
// --- Part 2: 全站連結與檔案類型自動標示 ---
|
||||
$('a').each(function() {
|
||||
var $a = $(this);
|
||||
var href = ($a.attr('href') || '').toLowerCase();
|
||||
if (!href || href.startsWith('javascript:')) return;
|
||||
|
||||
var linkText = $a.text().replace(/\u00a0/g, '').trim();
|
||||
var $img = $a.find('img');
|
||||
var currentTitle = ($a.attr('title') || '').trim();
|
||||
|
||||
// A. 視窗動作規範 (動態語系)
|
||||
var isNewWindow = ($a.attr('target') === '_blank');
|
||||
var windowTask = isNewWindow ? i18n.newWin : i18n.selfWin;
|
||||
|
||||
// B. 偵測檔案類型
|
||||
var fileExt = "";
|
||||
var fileMatches = href.match(/\.(pdf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odp|zip|rar|jpg|png|csv)$/);
|
||||
if (fileMatches) {
|
||||
fileExt = fileMatches[1].toLowerCase();
|
||||
}
|
||||
|
||||
// C. 智慧修正與標題補充 (解決 HM1240404E 不明符號問題)
|
||||
// 檢查是否包含括號 () 或 中英文的另開視窗關鍵字
|
||||
var hasBadSymbol = currentTitle.includes('()') ||
|
||||
currentTitle.includes('另開新視窗') ||
|
||||
currentTitle.includes('Open in new window');
|
||||
|
||||
if (linkText === "" && $img.length > 0) {
|
||||
// 【純圖片連結】
|
||||
var rawAlt = ($img.attr('alt') || '').trim();
|
||||
var forbidden = ['這是一張圖片', '圖片', 'image', 'photo', '图', ''];
|
||||
var imgAlt = forbidden.some(function(txt) { return rawAlt.toLowerCase() === txt; })
|
||||
? ($a.attr('aria-label') || i18n.link) : rawAlt;
|
||||
// img無障礙
|
||||
$(function() {
|
||||
/**
|
||||
* 圖片無障礙 AA 級補強 (人工檢測優化版)
|
||||
*/
|
||||
function fixImageAccessibility() {
|
||||
$('img').each(function() {
|
||||
var $img = $(this);
|
||||
var $parentA = $img.closest('a'); // 取得父層連結
|
||||
var currentAlt = ($img.attr('alt') || '').trim();
|
||||
var currentTitle = ($img.attr('title') || '').trim();
|
||||
|
||||
var fileInfo = fileExt ? '[' + fileExt.toUpperCase() + '] ' : '';
|
||||
$a.attr('title', (fileInfo + windowTask).trim());
|
||||
$img.attr('alt', imgAlt);
|
||||
}
|
||||
else if (linkText !== "") {
|
||||
// 【有文字連結】
|
||||
if (fileExt !== "" || hasBadSymbol || currentTitle === "") {
|
||||
var isTag = $a.hasClass('label') || $a.hasClass('tag') || $a.find('[class*="tag"]').length > 0;
|
||||
// 判定該連結是否「僅靠圖片傳達目的」(連結內無文字)
|
||||
var isLinkImage = $parentA.length > 0 && $parentA.text().replace(/\u00a0/g, '').trim() === "";
|
||||
|
||||
// --- 1. 處理「裝飾性圖片」標註 ---
|
||||
if (currentAlt === "裝飾圖片" || currentTitle === "裝飾圖片") {
|
||||
$img.attr('alt', '');
|
||||
$img.removeAttr('title');
|
||||
return;
|
||||
}
|
||||
|
||||
// --- 2. 解決【alt 與 title 相同】的問題 ---
|
||||
if (currentAlt !== '' && currentAlt === currentTitle) {
|
||||
$img.removeAttr('title');
|
||||
currentTitle = '';
|
||||
}
|
||||
|
||||
// --- 3. 處理「缺失 alt」或「空的 alt」補強邏輯 ---
|
||||
// 修改點:若是具有連結用途的圖片,alt 不可為空
|
||||
if (currentAlt === '') {
|
||||
let finalAlt = "";
|
||||
|
||||
// A. 優先嘗試從父層 (<a>) 的 title 抓取
|
||||
var parentATitle = $parentA.attr('title');
|
||||
|
||||
if (fileExt !== "") {
|
||||
// 檔案下載:連結文字 + .副檔名 + 動作 (語系化)
|
||||
$a.attr('title', linkText + " ." + fileExt + " " + windowTask);
|
||||
} else if (linkText.length <= 6 || isTag) {
|
||||
// 短文字:補充完整語意
|
||||
$a.attr('title', linkText + " " + windowTask);
|
||||
} else {
|
||||
// 長文字:僅動作提示
|
||||
$a.attr('title', windowTask);
|
||||
// B. 嘗試抓取同區域內的標題文字
|
||||
var nearbyTitle = $parentA.find('h1, h2, h3, h4, h5, h6').first().text().trim();
|
||||
|
||||
if (parentATitle && parentATitle.trim() !== '') {
|
||||
// 移除 title 內的視窗提示字眼,只取純文字作為 alt
|
||||
finalAlt = parentATitle.replace(/\(在本視窗開啟\)|\(在新視窗開啟\)/g, '').trim();
|
||||
} else if (nearbyTitle !== '') {
|
||||
finalAlt = nearbyTitle;
|
||||
} else if (isLinkImage) {
|
||||
// 如果是連結圖片且都抓不到文字,給予預設值「連結」避免檢測失敗
|
||||
finalAlt = "連結";
|
||||
}
|
||||
|
||||
$img.attr('alt', finalAlt);
|
||||
|
||||
// --- 4. 二次清理 ---
|
||||
if (currentTitle !== '' && currentTitle === finalAlt) {
|
||||
$img.removeAttr('title');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(fixImageAccessibility, 500);
|
||||
});
|
||||
// 有連結目的之所有a標籤的無障礙處理
|
||||
$(function() {
|
||||
/**
|
||||
* 全站無障礙 AA 級補強 (多語系偵測版)
|
||||
*/
|
||||
function fixAccessibilityAll() {
|
||||
// --- 0. 網址參數判斷 ---
|
||||
var urlParams = new URLSearchParams(window.location.search);
|
||||
var isEditMode = urlParams.get('editmode') === 'on';
|
||||
|
||||
var pageLang = $('html').attr('lang') || 'zh-Hant';
|
||||
var isEn = pageLang.toLowerCase().startsWith('en');
|
||||
|
||||
var i18n = {
|
||||
langBtn: isEn ? 'Open language menu in this window' : '在本視窗開啟語言選單',
|
||||
newWin: isEn ? '(Open in new window)' : '(在新視窗開啟)',
|
||||
selfWin: isEn ? '(Open in this window)' : '(在本視窗開啟)',
|
||||
link: isEn ? 'Link' : '連結'
|
||||
};
|
||||
|
||||
// --- Part 1: 語言選單修正 ---
|
||||
var $langBtn = $('#languagebutton');
|
||||
if ($langBtn.length > 0) {
|
||||
$langBtn.attr('title', i18n.langBtn);
|
||||
$langBtn.removeAttr('aria-label');
|
||||
}
|
||||
|
||||
// D. 最終清理
|
||||
$a.removeAttr('aria-label');
|
||||
if (linkText !== "" && $img.length > 0) { $img.attr('alt', ''); }
|
||||
});
|
||||
}
|
||||
// --- Part 2: 全站連結處理 ---
|
||||
$('a').each(function() {
|
||||
var $a = $(this);
|
||||
var href = ($a.attr('href') || '').toLowerCase();
|
||||
if (!href || href.startsWith('javascript:')) return;
|
||||
|
||||
setTimeout(function() {
|
||||
fixAccessibilityAll();
|
||||
}, 600);
|
||||
});
|
||||
// 清理 與 空白
|
||||
var linkText = $a.text().replace(/\u00a0/g, '').trim();
|
||||
var $img = $a.find('img');
|
||||
var currentTitle = ($a.attr('title') || '').trim();
|
||||
|
||||
// --- 【新增修正:隱藏空連結】 ---
|
||||
// 若網址沒有 editmode=on 時,判定 a 裡面文字為空且沒有圖片,則隱藏
|
||||
if (!isEditMode && linkText === "" && $img.length === 0) {
|
||||
$a.hide();
|
||||
return; // 跳過後續處理
|
||||
}
|
||||
|
||||
// A. 視窗動作規範
|
||||
var isNewWindow = ($a.attr('target') === '_blank');
|
||||
var windowTask = isNewWindow ? i18n.newWin : i18n.selfWin;
|
||||
|
||||
// B. 偵測檔案類型
|
||||
var fileExt = "";
|
||||
var fileMatches = href.match(/\.(pdf|doc|docx|xls|xlsx|ppt|pptx|odt|ods|odp|zip|rar|jpg|png|csv)$/);
|
||||
if (fileMatches) {
|
||||
fileExt = fileMatches[1].toLowerCase();
|
||||
}
|
||||
|
||||
// C. 智慧修正與標題補充
|
||||
var hasBadSymbol = currentTitle.includes('()') ||
|
||||
currentTitle.includes('另開新視窗') ||
|
||||
currentTitle.includes('Open in new window');
|
||||
|
||||
if (linkText === "" && $img.length > 0) {
|
||||
// 【純圖片連結】替代文字邏輯
|
||||
var rawAlt = ($img.attr('alt') || '').trim();
|
||||
var forbidden = ['這是一張圖片', '圖片', 'image', 'photo', '圖', ''];
|
||||
var imgAlt = forbidden.some(function(txt) { return rawAlt.toLowerCase() === txt; })
|
||||
? ($a.attr('aria-label') || i18n.link) : rawAlt;
|
||||
|
||||
var fileInfo = fileExt ? '[' + fileExt.toUpperCase() + '] ' : '';
|
||||
|
||||
// 確保具備標題與圖片 alt
|
||||
$a.attr('title', (fileInfo + imgAlt + " " + windowTask).trim());
|
||||
$img.attr('alt', imgAlt);
|
||||
}
|
||||
else if (linkText !== "") {
|
||||
// 【有文字連結】
|
||||
if (fileExt !== "" || hasBadSymbol || currentTitle === "") {
|
||||
var isTag = $a.hasClass('label') || $a.hasClass('tag') || $a.find('[class*="tag"]').length > 0;
|
||||
|
||||
if (fileExt !== "") {
|
||||
$a.attr('title', linkText + " ." + fileExt + " " + windowTask);
|
||||
} else if (linkText.length <= 6 || isTag) {
|
||||
$a.attr('title', linkText + " " + windowTask);
|
||||
} else {
|
||||
$a.attr('title', windowTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- 修正後的 Part D 最終清理 ---
|
||||
$a.removeAttr('aria-label');
|
||||
|
||||
// 只有當「真正可見的文字」存在時,才將圖片設為裝飾性
|
||||
// 使用 clone() 移除隱藏元件後再計算文字,確保準確度
|
||||
var visibleText = $a.clone().find(':hidden, style, script').remove().end().text().replace(/\u00a0/g, '').trim();
|
||||
|
||||
if (visibleText !== "" && $img.length > 0) {
|
||||
$img.attr('alt', '');
|
||||
} else {
|
||||
// 如果文字是隱藏的 (如你的範例),則必須保留或補強圖片 alt
|
||||
var rawAlt = ($img.attr('alt') || '').trim();
|
||||
if (rawAlt === "") {
|
||||
// 如果連圖片 alt 都沒寫,就從 a 的 title 抓
|
||||
var cleanTitle = currentTitle.replace(/\(在本視窗開啟\)|\(在新視窗開啟\)/g, '').trim();
|
||||
$img.attr('alt', cleanTitle || i18n.link);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(function() {
|
||||
fixAccessibilityAll();
|
||||
}, 600);
|
||||
});
|
||||
|
||||
// if (location.href.search('editmode=on') === -1) {
|
||||
// // 1. 處理圖片 alt 重複問題 (保持原邏輯但優化)
|
||||
|
|
@ -1189,15 +1211,20 @@
|
|||
setTimeout(fixJPlayerAccessibility, 500);
|
||||
});
|
||||
|
||||
// 移除 .navbar-brand 內部 display:none 元素的補強
|
||||
function removeHiddenElementsInsideBrand() {
|
||||
// 選取 .navbar-brand 內部所有隱藏的元素
|
||||
$('.navbar-brand *').filter(function() {
|
||||
// 同時判定 inline style 與 CSS class 造成的 display: none
|
||||
return $(this).css('display') === 'none';
|
||||
}).remove(); // 徹底從 DOM 中移除該標籤
|
||||
}).remove(); // 徹底從 DOM 中移除該標籤,避免無障礙檢測工具誤判
|
||||
}
|
||||
|
||||
// 執行 function
|
||||
removeHiddenElementsInsideBrand();
|
||||
// 使用 setTimeout 確保內容渲染後執行
|
||||
// 建議設定 500~800 毫秒,避開大部分動態載入的時間差
|
||||
setTimeout(function() {
|
||||
removeHiddenElementsInsideBrand();
|
||||
}, 600);
|
||||
//修正 Alt+M 定位點位置
|
||||
$(function() {
|
||||
function fixAccessKeyM() {
|
||||
|
|
|
|||
Loading…
Reference in New Issue