190 lines
5.6 KiB
Plaintext
190 lines
5.6 KiB
Plaintext
<div class="marquee-1" module="text_marquee" data-ps="">
|
||
<div class="marquee-1-controls">
|
||
<div class="controlplay">
|
||
<button type="button" class="marquee-toggle-btn" title="暫停跑馬燈" aria-label="暫停跑馬燈" aria-pressed="false">
|
||
<i class="marquee-icon" aria-hidden="true"></i>
|
||
<span class="visually-hidden">暫停跑馬燈</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<ul class="marquee" data-level="0" data-list="texts" aria-live="polite" aria-atomic="true" aria-label="跑馬燈公告">
|
||
<li>{{content}}</li>
|
||
</ul>
|
||
</div>
|
||
|
||
<script type="text/javascript">
|
||
(function(){
|
||
var main_div = $("div[data-subpart-id={{subpart-id}}]");
|
||
var total_texts = main_div.find("ul.marquee li").length - 1;
|
||
var current_text = 0;
|
||
var last_text = 0;
|
||
var isPaused = false;
|
||
var timer = null;
|
||
|
||
var $toggleBtn = main_div.find(".marquee-toggle-btn");
|
||
var $marquee = main_div.find("ul.marquee");
|
||
|
||
main_div.find("ul.marquee li").hide();
|
||
|
||
function textTransform() {
|
||
if (isPaused) return;
|
||
|
||
current_text++;
|
||
current_text = (current_text > total_texts ? 0 : current_text);
|
||
last_text = (current_text === 0 ? total_texts : current_text - 1);
|
||
|
||
var speed = main_div.find(".marquee > li > a").eq(current_text).attr("speed") || 3000;
|
||
|
||
main_div.find("ul.marquee li").eq(last_text).slideUp(500);
|
||
main_div.find("ul.marquee li").eq(current_text).slideDown(500);
|
||
|
||
if (total_texts > 0) {
|
||
timer = setTimeout(textTransform, speed);
|
||
}
|
||
}
|
||
|
||
function pause() {
|
||
isPaused = true;
|
||
clearTimeout(timer);
|
||
$marquee.attr("aria-live", "off");
|
||
|
||
// 切換按鈕狀態:aria-pressed="true" 表示目前已暫停
|
||
$toggleBtn
|
||
.attr("aria-pressed", "true")
|
||
.attr("aria-label", "繼續跑馬燈")
|
||
.attr("title", "繼續跑馬燈")
|
||
.find("span.visually-hidden").text("繼續跑馬燈");
|
||
$toggleBtn.addClass("is-paused");
|
||
|
||
// 暫停後讓目前顯示的 li 內連結可被 Tab
|
||
main_div.find("ul.marquee li").removeAttr("tabindex");
|
||
main_div.find("ul.marquee li:visible a").attr("tabindex", "0");
|
||
main_div.find("ul.marquee li:hidden a").attr("tabindex", "-1");
|
||
}
|
||
|
||
function resume() {
|
||
isPaused = false;
|
||
$marquee.attr("aria-live", "polite");
|
||
|
||
// 切換按鈕狀態:aria-pressed="false" 表示目前播放中
|
||
$toggleBtn
|
||
.attr("aria-pressed", "false")
|
||
.attr("aria-label", "暫停跑馬燈")
|
||
.attr("title", "暫停跑馬燈")
|
||
.find("span.visually-hidden").text("暫停跑馬燈");
|
||
$toggleBtn.removeClass("is-paused");
|
||
|
||
// 恢復播放,li 內連結不在 Tab 順序
|
||
main_div.find("ul.marquee li").removeAttr("tabindex");
|
||
main_div.find("ul.marquee li a").attr("tabindex", "-1");
|
||
|
||
var speed = main_div.find(".marquee > li > a").eq(current_text).attr("speed") || 3000;
|
||
timer = setTimeout(textTransform, speed);
|
||
}
|
||
|
||
// 單一切換按鈕
|
||
$toggleBtn.on("click keydown", function(e) {
|
||
if (e.type === "keydown" && e.keyCode !== 13 && e.keyCode !== 32) return;
|
||
e.preventDefault();
|
||
if (isPaused) {
|
||
resume();
|
||
} else {
|
||
pause();
|
||
}
|
||
});
|
||
|
||
// 焦點進入跑馬燈區域時自動暫停
|
||
main_div.on("focusin", function() {
|
||
if (!isPaused) pause();
|
||
});
|
||
|
||
// 焦點離開跑馬燈區域時自動恢復
|
||
main_div.on("focusout", function(e) {
|
||
setTimeout(function() {
|
||
if (!main_div[0].contains(document.activeElement)) {
|
||
if (isPaused) resume();
|
||
}
|
||
}, 50);
|
||
});
|
||
|
||
// 初始狀態:播放中
|
||
main_div.find("ul.marquee li").removeAttr("tabindex");
|
||
main_div.find("ul.marquee li a").attr("tabindex", "-1");
|
||
|
||
timer = setTimeout(textTransform, 500);
|
||
})();
|
||
</script>
|
||
|
||
<style>
|
||
.marquee-1-controls {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
.marquee-1 .controlplay {
|
||
right: 0.5em;
|
||
top: 0.6em;
|
||
display: flex;
|
||
align-items: center;
|
||
list-style: none;
|
||
margin: 0;
|
||
padding: 0;
|
||
gap: 4px;
|
||
}
|
||
|
||
.marquee-1 .controlplay button.marquee-toggle-btn {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
width: 26px;
|
||
height: 26px;
|
||
border: 1.5px solid #bbb;
|
||
border-radius: 50%;
|
||
background: #fff;
|
||
cursor: pointer;
|
||
transition: background 0.15s;
|
||
padding: 0;
|
||
}
|
||
|
||
.marquee-1 .controlplay button.marquee-toggle-btn:hover,
|
||
.marquee-1 .controlplay button.marquee-toggle-btn:focus {
|
||
background: #f0f0f0;
|
||
outline: 2px solid #005fcc;
|
||
outline-offset: 2px;
|
||
}
|
||
|
||
/* 播放中:顯示 pause icon(兩條直線) */
|
||
.marquee-1 .controlplay button.marquee-toggle-btn:not(.is-paused) .marquee-icon {
|
||
display: inline-flex;
|
||
gap: 2px;
|
||
align-items: center;
|
||
}
|
||
|
||
.marquee-1 .controlplay button.marquee-toggle-btn:not(.is-paused) .marquee-icon::before,
|
||
.marquee-1 .controlplay button.marquee-toggle-btn:not(.is-paused) .marquee-icon::after {
|
||
content: '';
|
||
display: inline-block;
|
||
width: 3px;
|
||
height: 10px;
|
||
background: #ff4500;
|
||
border-radius: 1px;
|
||
}
|
||
|
||
/* 已暫停:顯示 play icon(三角形) */
|
||
.marquee-1 .controlplay button.marquee-toggle-btn.is-paused .marquee-icon::before {
|
||
content: '';
|
||
display: inline-block;
|
||
width: 0;
|
||
height: 0;
|
||
border-style: solid;
|
||
border-width: 5px 0 5px 10px;
|
||
border-color: transparent transparent transparent #32D9C3;
|
||
margin-left: 2px;
|
||
}
|
||
|
||
.marquee-1 .controlplay button.marquee-toggle-btn.is-paused .marquee-icon::after {
|
||
display: none;
|
||
}
|
||
</style> |