nfu_new2_bo5/modules/announcement/_annc_widget16.html.erb

153 lines
5.4 KiB
Plaintext

<div class="w-annc widget-announcement-16">
<h2 class="w-annc__widget-title">
<span>{{widget-title}}</span>
</h2>
<div class="slide-button">
<button class="cycle-prev btn btn-warning" title="上一張" aria-label="上一張"> <i class="fa fa-angle-left"></i></button>
<button class="cycle-next btn btn-warning" title="下一張" aria-label="下一張"> <i class="fa fa-angle-right"></i></button>
<a class="w-annc__more btn btn-primary pull-right" href="{{more_url}}"><%= (I18n.locale.to_s =="zh_tw") ? "更多+" : "More NEWS" %></a>
</div>
<div class="w-annc__wrap "
data-level="0"
data-list="announcements"
>
<div class="w-annc__item">
<div class="w-annc__img-wrap">
<img class="w-annc__img" src="{{img_src}}" alt="{{img_description}}" title="{{img_description}}">
</div>
<div class="w-annc__content-wrap">
<div class="w-annc__meta">
<span class="w-annc__status-wrap" data-list="statuses" data-level="1">
<span class="w-annc__status label {{status-class}}">{{status}}</span>
</span>
<span class="w-annc__postdate-wrap" date-format="%Y-%m-%d">
<span class="w-annc__postdate">{{postdate}}</span>
</span>
</div>
<h3 class="w-annc__entry-title">
<a class="w-annc__title" href="{{link_to_show}}">{{title}}</a>
</h3>
</div>
</div>
</div>
</div>
<script>
$(function(){
// initialize all widgets (scoped)
$('.w-annc').each(function(){
var $widget = $(this);
var $wrap = $widget.find('.w-annc__wrap').first();
if (!$wrap.length) return;
// prepare markup: add class, create track and move slides in
$wrap.addClass('custom-carousel');
var $items = $wrap.children('.w-annc__item');
if ($items.length <= 1) {
// nothing to carousel
$items.attr('aria-hidden', 'false');
return;
}
// create track and move items into it
var $track = $('<div class="w-annc__track" aria-live="polite"></div>');
$items.each(function(){
// ensure each item is block-level and has aria-hidden
$(this).attr('aria-hidden', 'true').appendTo($track);
});
$wrap.empty().append($track);
var count = $track.children('.w-annc__item').length;
var idx = 0;
var animating = false;
// controls - scoped in widget
var $prev = $widget.find('.cycle-prev').first();
var $next = $widget.find('.cycle-next').first();
// optional pager
var $pager = $('<div class="w-annc__pager" aria-hidden="true"></div>');
for (var i=0;i<count;i++){
var $btn = $('<button type="button" aria-label="第 '+(i+1)+' 則"></button>');
(function(i, $b){ $b.on('click', function(){ goTo(i, true); }); }) (i, $btn);
$pager.append($btn);
}
$widget.append($pager);
function updateUI(){
// transform track
$track.css('transform', 'translateX(-' + (idx * 100) + '%)');
// aria-hidden mark
$track.children('.w-annc__item').each(function(i){
$(this).attr('aria-hidden', i===idx? 'false' : 'true');
});
// pager active
$pager.find('button').removeClass('active').attr('aria-pressed','false');
$pager.find('button').eq(idx).addClass('active').attr('aria-pressed','true');
}
function goTo(i, animate){
if (animating) return;
i = (i + count) % count; // wrap
if (i === idx) return;
animating = true;
idx = i;
updateUI();
// allow transition to finish
setTimeout(function(){ animating = false; }, 360);
}
// prev/next handlers (stopPropagation to avoid other handlers)
$prev.on('click', function(e){ e.preventDefault(); e.stopPropagation(); goTo(idx - 1, true); });
$next.on('click', function(e){ e.preventDefault(); e.stopPropagation(); goTo(idx + 1, true); });
// keyboard support when widget focused
$widget.attr('tabindex', -1).on('keydown', function(e){
if (e.key === 'ArrowLeft') { e.preventDefault(); goTo(idx - 1, true); }
if (e.key === 'ArrowRight') { e.preventDefault(); goTo(idx + 1, true); }
});
// touch / swipe support
(function(){
var startX = null, startY = null, distX = 0, isTouch = false;
var threshold = 30; // required min px for swipe
$wrap.on('touchstart mousedown', function(e){
var ev = e.originalEvent.touches ? e.originalEvent.touches[0] : e;
startX = ev.clientX; startY = ev.clientY; distX = 0; isTouch = true;
});
$wrap.on('touchmove mousemove', function(e){
if (!isTouch || startX === null) return;
var ev = e.originalEvent.touches ? e.originalEvent.touches[0] : e;
distX = ev.clientX - startX;
});
$wrap.on('touchend mouseup mouseleave', function(e){
if (!isTouch) return;
isTouch = false;
if (Math.abs(distX) > threshold) {
if (distX < 0) { // swipe left -> next
goTo(idx + 1, true);
} else { // swipe right -> prev
goTo(idx - 1, true);
}
}
startX = null; distX = 0;
});
})();
// pause-on-hover (if you add autoplay later)
$wrap.on('mouseenter', function(){ /* placeholder if needed */ });
$wrap.on('mouseleave', function(){ /* placeholder if needed */ });
// initial UI
updateUI();
// ensure images responsive inside
$track.find('img').css({ 'max-width': '100%', 'height': 'auto', 'display': 'block' });
});
});
</script>