update
This commit is contained in:
parent
0db139d6d3
commit
0ec89e42ab
|
|
@ -1101,56 +1101,59 @@ $(function() {
|
|||
}
|
||||
}
|
||||
|
||||
// E. 重新計算標題 (關鍵邏輯:若 hasOriginalTitle 為真,則不進入此區塊)
|
||||
if (!hasOriginalTitle) {
|
||||
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() + '] ' : '';
|
||||
$a.attr('title', (fileInfo + imgAlt + " " + windowTask).trim());
|
||||
$img.attr('alt', imgAlt);
|
||||
}
|
||||
else if (linkText !== "") {
|
||||
if (fileExt !== "" || hasBadSymbol || currentTitle === "" || currentTitle.includes('/uploads/')) {
|
||||
if (fileExt !== "") {
|
||||
$a.attr('title', linkText + " ." + fileExt + " " + windowTask);
|
||||
} else {
|
||||
$a.attr('title', windowTask);
|
||||
}
|
||||
// E. 重新計算標題 (關鍵邏輯:若 hasOriginalTitle 為真,則不進入此區塊)
|
||||
if (!hasOriginalTitle) {
|
||||
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() + '] ' : '';
|
||||
$a.attr('title', (fileInfo + imgAlt + " " + windowTask).trim());
|
||||
$img.attr('alt', imgAlt);
|
||||
}
|
||||
else if (linkText !== "") {
|
||||
if (fileExt !== "" || hasBadSymbol || currentTitle === "" || currentTitle.includes('/uploads/')) {
|
||||
if (fileExt !== "") {
|
||||
$a.attr('title', linkText + " ." + fileExt + " " + windowTask);
|
||||
} else {
|
||||
$a.attr('title', windowTask);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ✅ 符合 HM1240404E:title 不應與連結文字或圖片 alt 重複
|
||||
if (hasOriginalTitle && currentTitle !== "") {
|
||||
var titleWithoutWindow = currentTitle
|
||||
.replace('(在本視窗開啟)', '')
|
||||
.replace('(在新視窗開啟)', '')
|
||||
.replace('Open in this window', '')
|
||||
.replace('Open in new window', '')
|
||||
.replace('另開新視窗前往', '')
|
||||
.replace('另開新視窗', '')
|
||||
.trim();
|
||||
// ✅ 符合 HM1240404E:title 不應與連結文字或圖片 alt 重複
|
||||
if (hasOriginalTitle && currentTitle !== "") {
|
||||
var titleWithoutWindow = currentTitle
|
||||
.replace('(在本視窗開啟)', '')
|
||||
.replace('(在新視窗開啟)', '')
|
||||
.replace('Open in this window', '')
|
||||
.replace('Open in new window', '')
|
||||
.replace('另開新視窗前往', '')
|
||||
.replace('另開新視窗', '')
|
||||
.trim();
|
||||
|
||||
// ✅ title 去掉開窗字串後,若與連結文字或圖片原始 alt 相同,則只保留開窗提示
|
||||
if (
|
||||
(titleWithoutWindow === linkText && linkText !== i18n.link) ||
|
||||
(imgAltOriginal !== '' && titleWithoutWindow === imgAltOriginal)
|
||||
) {
|
||||
$a.attr('title', windowTask);
|
||||
}
|
||||
|
||||
// ✅ 最終清理:若 title 出現空括號 () 則移除並補上正確開窗提示
|
||||
var finalTitle = ($a.attr('title') || '').trim();
|
||||
if (finalTitle.includes('()')) {
|
||||
finalTitle = finalTitle.replace(/\(\)/g, '').trim();
|
||||
$a.attr('title', finalTitle + ' ' + windowTask);
|
||||
}
|
||||
// ✅ title 去掉開窗字串後,若與連結文字或圖片原始 alt 相同,則只保留開窗提示
|
||||
// ✅ 新增:若 linkText 包含副檔名且 title 也是同樣檔名,也只保留開窗提示
|
||||
if (
|
||||
(titleWithoutWindow === linkText && linkText !== i18n.link) ||
|
||||
(imgAltOriginal !== '' && titleWithoutWindow === imgAltOriginal) ||
|
||||
(fileExt !== '' && linkText.toLowerCase().endsWith('.' + fileExt) && titleWithoutWindow === linkText)
|
||||
) {
|
||||
$a.attr('title', windowTask);
|
||||
return; // ✅ 加上 return,避免繼續執行後面的清理邏輯造成二次污染
|
||||
}
|
||||
|
||||
// ✅ 最終清理:若 title 出現空括號 () 則移除並補上正確開窗提示
|
||||
var finalTitle = ($a.attr('title') || '').trim();
|
||||
if (finalTitle.includes('()')) {
|
||||
finalTitle = finalTitle.replace(/\(\)/g, '').trim();
|
||||
$a.attr('title', finalTitle + ' ' + windowTask);
|
||||
}
|
||||
}
|
||||
|
||||
// F. 最終清理:移除冗餘 label,避免螢幕閱讀器唸兩次
|
||||
$a.removeAttr('aria-label');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
// Widget
|
||||
// ## gerenral styles
|
||||
ul.button-mid{
|
||||
z-index: 200;
|
||||
.prev-button{
|
||||
height: 2em !important;
|
||||
width: 2em !important;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
// ## Gerneral styles for widgets
|
||||
.i-annc__category{
|
||||
white-space: nowrap;
|
||||
color: #fff;
|
||||
color:#000;
|
||||
border-radius: 1em;
|
||||
padding: 1px 5px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-ad-banner__pager-2 w-ba-banner__caption banner-pager banner_caption_{{subpart-id}}" data-list="images" data-level="0">
|
||||
<div class="w-ad-banner__pager-2 w-ba-banner__caption banner-pager banner_caption_{{subpart-id}}" data-list="images" data-level="0">
|
||||
<li><button title="Slide {{slide_number}}" aria-label="Pager"><span style="display: none;">Slide {{slide_number}}</span></button></li>
|
||||
</div>
|
||||
<ul class="controlplay" role="radiogroup" aria-label="播放控制選項">
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
data-cycle-timeout="{{timeout}}"
|
||||
data-cycle-fx="{{ad_fx}}"
|
||||
data-pager=".banner_caption_{{subpart-id}}"
|
||||
data-cycle-pager-template="<li><img src='{{src}}' alt='thumbnail'></li>"
|
||||
data-cycle-pager-template="<li role='tab' tabindex='0' aria-selected='false' aria-label='{{title}}'><img src='{{src}}' alt='' aria-hidden='true'></li>"
|
||||
data-pager-active-class="active-slide"
|
||||
data-cycle-youtube="true"
|
||||
data-cycle-youtube-autostart="false"
|
||||
|
|
@ -457,7 +457,8 @@
|
|||
if (match && pagerItems[i]) {
|
||||
const videoId = match[1];
|
||||
pagerItems[i].src = `https://img.youtube.com/vi/${videoId}/hqdefault.jpg`;
|
||||
pagerItems[i].alt = "YouTube thumbnail";
|
||||
// alt 已在 pager template 由 {{title}} 提供,此處清空避免輔具重複唸
|
||||
pagerItems[i].alt = "";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -556,18 +557,27 @@ function fixBannerPagerA11y($pager) {
|
|||
if (!$pager || $pager.length === 0) return;
|
||||
|
||||
// 外層補 tablist role
|
||||
$pager.attr('role', 'tablist').attr('aria-label', '輪播圖片選擇');
|
||||
$pager.attr('role', 'tablist').attr('aria-label', '輪播影片選擇');
|
||||
|
||||
// 每個 li 補 role/tabindex/aria-label/aria-selected
|
||||
$pager.find('li').each(function(i) {
|
||||
var $li = $(this);
|
||||
// 避免重複初始化
|
||||
if ($li.attr('role') === 'tab') return;
|
||||
|
||||
// 取得影片標題:優先用 template 已帶入的 aria-label,其次用 img alt,最後 fallback 第N張
|
||||
var existingLabel = ($li.attr('aria-label') || '').trim();
|
||||
var imgAlt = ($li.find('img').attr('alt') || '').trim();
|
||||
var label = (existingLabel && existingLabel !== '第' + (i + 1) + '張')
|
||||
? existingLabel
|
||||
: (imgAlt ? imgAlt : '第' + (i + 1) + '張影片');
|
||||
|
||||
$li
|
||||
.attr('role', 'tab')
|
||||
.attr('tabindex', '0')
|
||||
.attr('aria-selected', $li.hasClass('active-slide') ? 'true' : 'false')
|
||||
.attr('aria-label', '第' + (i + 1) + '張');
|
||||
.attr('aria-label', label);
|
||||
|
||||
// 縮圖圖片本身為裝飾性,alt 清空並加 aria-hidden
|
||||
$li.find('img').attr('alt', '').attr('aria-hidden', 'true');
|
||||
});
|
||||
|
||||
// 鍵盤 Enter/Space 觸發點擊(用 on 綁定避免重複)
|
||||
|
|
|
|||
|
|
@ -26,7 +26,9 @@
|
|||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="w-ba-banner__pager-3 banner-pager banner_caption_{{subpart-id}}"></ul>
|
||||
<div class="w-ad-banner__pager-2 w-ba-banner__caption banner-pager banner_caption_{{subpart-id}}" data-list="images" data-level="0">
|
||||
<li><button title="Slide {{slide_number}}" aria-label="Pager"><span style="display: none;">Slide {{slide_number}}</span></button></li>
|
||||
</div>
|
||||
<ul class="controlplay" role="radiogroup" aria-label="播放控制選項">
|
||||
<a role="radio" aria-checked="true" href="javascript:;" class="resume-slide active" title="繼續播放" aria-label="繼續播放" aria-live="assertive">
|
||||
<i aria-hidden="true"></i>
|
||||
|
|
@ -38,10 +40,10 @@
|
|||
<p style="display: none;"><%= I18n.t("ad_banner.pause") %></p>
|
||||
</a>
|
||||
</ul>
|
||||
<ul class="button-mid">
|
||||
<button class="prev-button" title = "<%= (I18n.locale.to_s =="zh_tw") ? "上一張" : "prev" %>" aria-label="Pager"></button>
|
||||
<button class="next-button" title = "<%= (I18n.locale.to_s =="zh_tw") ? "下一張" : "next" %>" aria-label="Pager"></button>
|
||||
</ul>
|
||||
<ul class="button-mid">
|
||||
<i class="fa fa-angle-left prev-button" aria-label="<%= I18n.t("ad_banner.prev") %>"></i>
|
||||
<i class="fa fa-angle-right next-button" aria-label="<%= I18n.t("ad_banner.next") %>"></i>
|
||||
</ul>
|
||||
</div>
|
||||
<script>
|
||||
var flag = 1;
|
||||
|
|
@ -67,5 +69,20 @@
|
|||
})
|
||||
$('.prev-button').off('click').on('click',function(){
|
||||
$(this).parent("ul").parent('.w-ba-banner').find(".cycle-slideshow").cycle("prev");
|
||||
})
|
||||
});
|
||||
/* 修正點:處理 Pager 無障礙朗讀文字 */
|
||||
$('.cycle-slideshow').on('cycle-post-initialize', function(event, optionHash) {
|
||||
var $container = $(this).closest('.w-ba-banner');
|
||||
var $slides = $(this).find('.w-ba-banner__slide');
|
||||
var $pagerButtons = $container.find(".banner-pager button");
|
||||
|
||||
$pagerButtons.each(function(index) {
|
||||
var slideTitle = $slides.eq(index).data('cycle-title') || "";
|
||||
var ariaLabel = "第 " + (index + 1) + " 張投影片 " + slideTitle;
|
||||
$(this).attr({
|
||||
"aria-label": ariaLabel,
|
||||
"title": ariaLabel
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Reference in New Issue