Widget:Carousel

From ChaosZeroNightmareWiki
Jump to navigation Jump to search

<style>

  1. carousel-container {
   position: relative;
   width: 100%;
   max-width: 960px;
   margin: 0 auto;
   overflow: hidden;
   border-radius: 0;
   background: #1a1a1a;

}

  1. carousel-container .carousel-wrapper {
   position: relative;
   width: 100%;
   padding-top: 56.25%;

}

  1. carousel-container .carousel-slide {
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   opacity: 0;
   transition: opacity 0.6s ease-in-out;
   cursor: pointer;
   display: block;
   text-decoration: none;
   color: inherit;

}

  1. carousel-container .carousel-slide.active {
   opacity: 1;
   z-index: 1;

}

  1. carousel-container .carousel-slide .slide-bg {
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   background-size: cover;
   background-position: center;
   background-repeat: no-repeat;

}

  1. carousel-container .carousel-slide .slide-overlay {
   position: absolute;
   top: 0;
   left: 0;
   width: 100%;
   height: 100%;
   background: linear-gradient(
       to top,
       rgba(0, 0, 0, 0.85) 0%,
       rgba(0, 0, 0, 0.5) 40%,
       rgba(0, 0, 0, 0.2) 70%,
       rgba(0, 0, 0, 0.1) 100%
   );

}

  1. carousel-container .slide-content {
   position: absolute;
   bottom: 0;
   left: 0;
   right: 0;
   padding: 24px 32px;
   z-index: 2;

}

  1. carousel-container .slide-category {
   display: inline-block;
   border: 1.5px solid #ffffff;
   color: #ffffff;
   font-size: 11px;
   font-weight: 700;
   letter-spacing: 1.5px;
   padding: 3px 10px;
   margin-bottom: 16px;
   text-transform: uppercase;
   background: transparent;

}

  1. carousel-container .slide-title {
   font-size: 24px;
   font-weight: 800;
   color: #ffffff;
   margin: 0 0 8px 0;
   line-height: 1.3;

}

  1. carousel-container .slide-desc {
   font-size: 14px;
   color: rgba(255, 255, 255, 0.85);
   margin: 0 0 16px 0;
   font-weight: 500;
   line-height: 1.5;

}

  1. carousel-container .carousel-indicators {
   display: flex;
   gap: 6px;
   align-items: center;

}

  1. carousel-container .carousel-indicator {
   width: 24px;
   height: 3px;
   background: rgba(255, 255, 255, 0.35);
   border: none;
   border-radius: 0;
   cursor: pointer;
   padding: 0;
   transition: all 0.3s ease;
   position: relative;
   overflow: hidden;

}

  1. carousel-container .carousel-indicator::after {
   content: ;
   position: absolute;
   top: 0;
   left: 0;
   height: 100%;
   width: 0%;
   background: #fb5711;
   border-radius: 0;
   transition: none;

}

  1. carousel-container .carousel-indicator.active::after {
   width: 100%;
   transition: width 5s linear;

}

  1. carousel-container .carousel-indicator.active {
   width: 32px;
   background: rgba(255, 255, 255, 0.2);

}

  1. carousel-container .carousel-indicator.visited {
   background: #fb5711;

}

  1. carousel-container .carousel-indicator.visited::after {
   width: 100%;
   transition: none;

}

  1. carousel-container .carousel-arrow {
   position: absolute;
   top: 50%;
   transform: translateY(-50%);
   z-index: 10;
   background: rgba(0, 0, 0, 0.45);
   border: none;
   color: #fff;
   width: 40px;
   height: 40px;
   border-radius: 0;
   cursor: pointer;
   font-size: 18px;
   display: flex;
   align-items: center;
   justify-content: center;
   opacity: 0;
   transition: opacity 0.3s ease, background 0.3s ease;

}

  1. carousel-container:hover .carousel-arrow {
   opacity: 1;

}

  1. carousel-container .carousel-arrow:hover {
   background: #fb5711;

}

  1. carousel-container .carousel-arrow-left {
   left: 12px;

}

  1. carousel-container .carousel-arrow-right {
   right: 12px;

}

  1. carousel-container.single-slide .carousel-arrow,
  2. carousel-container.single-slide .carousel-indicators {
   display: none !important;

}

@media (max-width: 600px) {

   #carousel-container .slide-content {
       padding: 16px 20px;
   }
   #carousel-container .slide-title {
       font-size: 18px;
   }
   #carousel-container .slide-desc {
       font-size: 12px;
   }
   #carousel-container .carousel-arrow {
       width: 32px;
       height: 32px;
       font-size: 14px;
   }

} </style>

<script> (function() {

   function initCarousel() {
       var dataEl = document.getElementById('carousel-data');
       var container = document.getElementById('carousel-container');
       if (!dataEl || !container) return;
       var count = parseInt(dataEl.getAttribute('data-count')) || 1;
       if (count > 4) count = 4;
       var slides = [];
       for (var i = 1; i <= count; i++) {
           slides.push({
               image: dataEl.getAttribute('data-banner' + i) || ,
               category: dataEl.getAttribute('data-banner' + i + '-category') || ,
               title: dataEl.getAttribute('data-banner' + i + '-title') || ,
               desc: dataEl.getAttribute('data-banner' + i + '-desc') || ,
               jump: dataEl.getAttribute('data-banner' + i + '-jump') || 
           });
       }
       if (slides.length === 0) return;
       if (slides.length === 1) container.classList.add('single-slide');
       // 构建页面跳转链接,不依赖 mw 对象
       function buildHref(pageName) {
           if (!pageName) return '#';
           // 尝试使用 mw.util.getUrl,若不可用则手动拼接
           if (typeof mw !== 'undefined' && mw.util && mw.util.getUrl) {
               return mw.util.getUrl(pageName);
           }
           if (typeof mw !== 'undefined' && mw.config && mw.config.get) {
               var path = mw.config.get('wgArticlePath');
               if (path) return path.replace('$1', encodeURIComponent(pageName));
           }
           // 最终回退:直接拼 /wiki/ 路径
           return '/wiki/' + encodeURIComponent(pageName.replace(/ /g, '_'));
       }

var html = '

';

       container.innerHTML = html;
       if (slides.length <= 1) return;
       var current = 0;
       var slideEls = container.querySelectorAll('.carousel-slide');
       var timer = null;
       var INTERVAL = 5000;
       function goTo(idx) {
           if (idx === current) return;
           slideEls[current].classList.remove('active');
           current = idx;
           slideEls[current].classList.add('active');
           updateIndicators();
           resetTimer();
       }
       function updateIndicators() {
           var allSets = container.querySelectorAll('.carousel-slide');
           for (var s = 0; s < allSets.length; s++) {
               var inds = allSets[s].querySelectorAll('.carousel-indicator');
               for (var j = 0; j < inds.length; j++) {
                   inds[j].classList.remove('active', 'visited');
                   if (j < current) {
                       inds[j].classList.add('visited');
                   } else if (j === current) {
                       void inds[j].offsetWidth;
                   }
               }
           }
           setTimeout(function() {
               var allSets2 = container.querySelectorAll('.carousel-slide');
               for (var s = 0; s < allSets2.length; s++) {
                   var inds = allSets2[s].querySelectorAll('.carousel-indicator');
                   if (inds[current]) {
                       inds[current].classList.add('active');
                   }
               }
           }, 20);
       }
       function next() {
           goTo((current + 1) % slides.length);
       }
       function prev() {
           goTo((current - 1 + slides.length) % slides.length);
       }
       function resetTimer() {
           clearInterval(timer);
           timer = setInterval(next, INTERVAL);
       }
       container.querySelector('.carousel-arrow-left').addEventListener('click', function(e) {
           e.preventDefault();
           e.stopPropagation();
           prev();
       });
       container.querySelector('.carousel-arrow-right').addEventListener('click', function(e) {
           e.preventDefault();
           e.stopPropagation();
           next();
       });
       container.addEventListener('click', function(e) {
           var btn = e.target;
           while (btn && !btn.classList.contains('carousel-indicator')) {
               if (btn === container) { btn = null; break; }
               btn = btn.parentElement;
           }
           if (btn) {
               e.preventDefault();
               e.stopPropagation();
               var idx = parseInt(btn.getAttribute('data-index'));
               if (!isNaN(idx)) goTo(idx);
           }
       });
       container.addEventListener('mouseenter', function() { clearInterval(timer); });
       container.addEventListener('mouseleave', function() { resetTimer(); });
       updateIndicators();
       resetTimer();
   }
   if (document.readyState === 'loading') {
       document.addEventListener('DOMContentLoaded', initCarousel);
   } else {
       initCarousel();
   }

})(); </script>