Carousel

シームレス型のスライダー

CSSに関しては一部CSSライブラリを採用しているので併用してください。

使い方

カルーセルにしたい要素の親に+-sliderMod-+のクラスを付与するだけでカルーセル化します。
内部要素が親要素の幅以下(スクロールが発生しない場合)時と、スマホサイズの時はカルーセル化しません。

[data-scrollber="set"]属性を追加することでスクロールバーを追加します。
*-ul class="sliderMod" data-scrollber="set"-*

[data-drag="set"]属性を追加することでドラッグでのスクロールが可能になります。
*-ul class="sliderMod" data-drag="set"-*

カルーセル化は関数で実行しているので、必ず[sliderSet()]を実行してください。
基本はページ読み込み字の実行で大丈夫ですが、別途イベントに絡めることもできます。
  • HTML
  • CSS
  • Script
.sliderMod {
    width: 100%;
    margin: 0 0 24px;
    display: flex;
    gap: 16px;
    overflow-x: auto;
    scrollbar-width: none;
    -ms-overflow-style: none;
    -webkit-overflow-scrolling: touch;
  }
  .sliderMod[data-scrollber="set"] {padding: 0 0 24px;}

  .sliderMod-wrap {position: relative;}
  .slider-nav {
    opacity: 0;
    transition: .2s;
  }
  .slider-nav-btn {
    width: 32px;
    height: 32px;
    margin: auto;
    border-radius: 50% 50%;
    background: var(--bg-overlay);
    color: #fff;
    display: flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    position: absolute;
    top: 0;
    bottom: 0;
    transition: .2s;
  }
  .slider-nav-btn:hover {background: rgba(0,0,0,0.9);}
  .slider-nav-btn.prev {left: 0px;}
  .slider-nav-btn.next {right: 0px;}
  .slider-nav-btn.prev .ico-mui::before {content: '\e408';}
  .slider-nav-btn.next .ico-mui::before {content: '\e409';}
  .slider-scrollbar ,
  .slider-scrollbar-btn {
    height: 16px;
    border-radius: 16px;
  }
  .slider-scrollbar {
    width: 100%;
    background: #d0d0d0;
    position: absolute;
    bottom: 0;
    transform: scale(0.5);
  }
  .slider-scrollbar-btn {
    background: var(--txt-secondary);
    cursor: pointer;
  }
  .sliderMod-wrap:hover .slider-nav {opacity: 1;}
  .sliderMod-wrap:hover .slider-nav-btn.prev {left: 8px;}
  .sliderMod-wrap:hover .slider-nav-btn.next {right: 8px;}
  .moveing .sliderMod {user-select: none;}
  .moveing .slider-nav {opacity: 1;}
  .moveing .slider-nav-btn.prev {left: 8px;}
  .moveing .slider-nav-btn.next {right: 8px;}
var frag_slider = false;
  var frag_scroll = false;
  var frag_resize = false;

  function sliderSet(){
    let $slider = $('.sliderMod');
    $slider.each(function(){
      let w = $win.width();
      let $li = $(this).children('li');
      let i = $li.size();
      $li.addClass('slider-li');
      if(($li.width() + 8) * i > $(this).parent().width() && w > 769 && !$(this).hasClass('set')){
        let obj = '
'; if($(this).data('scrollber') === 'set'){ obj = '
'; } $(this).addClass('set').wrap('
').parent('.sliderMod-wrap').append(obj).find('.slider-scrollbar-btn').width(100 / i + '%'); } }); } // 戻る $bd.on({ 'mousedown': function(){ let $slider = $(this).parents('.slider-nav').prev('.sliderMod'); frag_slider=setInterval(function(){ $slider.scrollLeft($slider.scrollLeft() - 12); },1); }, 'mouseup': function(){ let $slider = $(this).parents('.slider-nav').prev('.sliderMod'); $slider.animate({ scrollLeft: $slider.scrollLeft() - 24 },200, 'swing'); clearInterval(frag_slider); } }, '.slider-nav-btn.prev'); // 進む $bd.on({ 'mousedown': function(){ let $slider = $(this).parents('.slider-nav').prev('.sliderMod'); frag_slider=setInterval(function(){ $slider.scrollLeft($slider.scrollLeft() + 12); },1); }, 'mouseup': function(){ let $slider = $(this).parents('.slider-nav').prev('.sliderMod'); $slider.animate({ scrollLeft: $slider.scrollLeft() + 24 },200, 'swing'); clearInterval(frag_slider); } }, '.slider-nav-btn.next'); // スクロール同期 $('.sliderMod').scroll(function(){ let $slideWrap = $(this).parents('.sliderMod-wrap'); let $slide = $slideWrap.find('.sliderMod'); let $barBtn = $slideWrap.find('.slider-scrollbar-btn'); let disp_width = $slide.width(); // スクロールバー移動可能量(スライダー表示幅 - スライダー幅) / スクロール可能量(スライダー全幅 - スライダー表示幅) let offset = $(this).scrollLeft() * (disp_width - $barBtn.width()) / ($slide.get(0).scrollWidth - disp_width); $barBtn.css('transform', 'translateX(' + offset + 'px)'); }); // スクロールバードラッグ $bd.on({ 'mousedown': function(e){ tar = $(this); frag_scroll = true; scrollbar_x = (e.pageX - tar.offset().left) * 4; tar.parents('.sliderMod-wrap').addClass('moveing'); } }, '.slider-scrollbar-btn'); $bd.on('mousemove', function(e){ if(!frag_scroll) return; let $slideWrap = tar.parents('.sliderMod-wrap'); let $slide = $slideWrap.find('.sliderMod'); let $bar = tar.parents('.slider-scrollbar'); let bar_left = $bar.offset().left; let disp_width = $slide.width(); let scrollbar_track = disp_width - tar.width(); // スクロールバー移動可能量 let scroll_move = ((e.pageX - bar_left) * 4 / scrollbar_track * scrollbar_track) - scrollbar_x; if (scroll_move < 0) {scroll_move = 0;} else if (scroll_move > scrollbar_track * 2) {return;} tar.css('transform', 'translateX(' + scroll_move + 'px)'); $slide.scrollLeft(((tar.offset().left - bar_left) / scrollbar_track * ($slide.get(0).scrollWidth - disp_width))); }); $bd.on('mouseup', function(){ frag_scroll = false; $('.sliderMod-wrap').removeClass('moveing'); }); // リストドラッグ $.prototype.mousedragscrollable = function(){ let target; $(this).each(function(i, e){ $(e).mousedown(function (event) { event.preventDefault(); target = $(e); $(e).data({ down: true, move: false, x: event.clientX, y: event.clientY, scrollleft: $(e).scrollLeft(), scrolltop: $(e).scrollTop(), }); return false; }); $(e).click(function(event){ if($(e).data('move')){return false;} }); }); $(document) .mousemove(function(event){ if($(target).data('down')){ event.preventDefault(); let move_x = $(target).data('x') - event.clientX; let move_y = $(target).data('y') - event.clientY; if(move_x !== 0 || move_y !== 0){ $(target).data('move', true); } else { return; } $(target).scrollLeft($(target).data('scrollleft') + move_x); $(target).scrollTop($(target).data('scrolltop') + move_y); return false; } }) .mouseup(function(){ $(target).data('down', false); return false; }); }; $('.sliderMod[data-drag]').mousedragscrollable(); $win.on('orientationchange , resize', function(){ if (frag_resize !== false) {clearTimeout(frag_resize);} frag_resize = setTimeout(function(){ sliderSet(); }, 300); });