Swiper水平滑动滚动导航

Swiper horizontal slide scroll navigation

我正在使用滑动条构建顶部粘性导航。 它应该为长页面提供移动友好的导航。 如果您单击一项,它会滚动到页面上引用的内容。

现在滑动器会使用 class“slideActiveClass”突出显示单击的项目。这应该保持原样。在菜单中滑动时,它也会应用此 class。

我需要改变两件事。

  1. 我想在滑动菜单时应用活动 class 摆脱它。
  2. 我希望将活动幻灯片设置为与用户视口所在位置相关的特定元素。例如。如果滚动到“div id=three”,则活动幻灯片应更改为幻灯片“三”等。

知道如何正确实施吗?

我想我需要使用“

swiper.slideTo(索引、速度、runCallbacks)

运行 过渡到索引号等于 'index' 参数的幻灯片,持续时间等于 'speed' 参数。

index - number - 幻灯片的索引编号。

速度 - 数量 - 过渡持续时间(以毫秒为单位)。

runCallbacks - 布尔值 - 将其设置为 false(默认情况下为 true)并且转换不会产生转换事件。"

取自:https://swiperjs.com/swiper-api#method-swiper-slideTo

感谢任何帮助。

我打算将完成的代码发布到 codepen,因为我找不到所需功能的示例,我认为它可能对很多项目都有用。

var swiper = new Swiper(".swiper-container", {
  slidesPerView: "auto",
  freeMode: true,
  slideToClickedSlide: true,
  spaceBetween: 10,
  mousewheel: true
});
html {
  scroll-behavior: smooth;
}
.swiper-container {
  width: 100%;
}
.swiper-slide {
   background-color: rgba(0,255,0,0.1);
   padding: 10px;
   width: 20%!important;
}
.swiper-slide-active {
  background-color: red;
}

.swiper-container ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}
.swiper-container a {
  color: black;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  width: 100%;
  height: 100%;
}
.sticky {
  position: sticky;
  top: 0px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.1/css/swiper.min.css" rel="stylesheet"/>
<div class="sticky">
<div class="swiper-container" id="scroll-tags">
  <ul class="swiper-wrapper">
    <li class="swiper-slide"><a href="#1">One</a></li>
    <li class="swiper-slide"><a href="#2">Two</a></li>
    <li class="swiper-slide"><a href="#3">Three</a></li>
    <li class="swiper-slide"><a href="#4">Four</a></li>
    <li class="swiper-slide "><a href="#5">Five</a></li>
    <li class="swiper-slide"><a href="#6">Six</a></li>
    <li class="swiper-slide"><a href="#">item 7</a></li>
    <li class="swiper-slide"><a href="#">item 8</a></li>
    <li class="swiper-slide"><a href="#">item 9</a></li>
    
    
  </ul>
</div>
</div>
<div style="height: 500vh">
  <div class="class1" style="height:50vh;background-color: rgba(255,0,0,0.1);" id="1">One</div>
  <div class="class2" style="height:50vh;background-color: rgba(255,123,32,0.1);" id="2">Two</div>
  <div class="class3" style="height:50vh;background-color: rgba(255,122,0,0.1);" id="3">Three</div>
<div class="class4" style="height:50vh;background-color: rgba(255,122,0,0.1);" id="4">Four</div>
<div class="class5" style="height:50vh;background-color: rgba(255,122,0,0.1);" id="5">Five</div>
<div class="class6" style="height:50vh;background-color: rgba(255,122,0,0.1);" id="6">Six</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.1/js/swiper.min.js"></script>

自己找到了解决方案。

不再使用“.swiper-slide-active”class 来显示活动导航,而是使用“.swiper-slide-active2”。

我向 swiper 容器中的每个元素添加了一个“alt”标签。 每个“alt”值对应于滑动器索引号(从 0 开始)。

我用观察者更改导航元素的 class 并告诉滑动器滑动到索引号。 工作正常。 欢迎改进。

Link 到代码笔:https://codepen.io/peplebe/pen/MWOJgXe

var swiper = new Swiper(".swiper-container", {
  slidesPerView: "auto",
  freeMode: {
    enabled: true,
    sticky: true,
  },

  spaceBetween: 10,
  mousewheel: true
});
//
function selectElementByClass(className) {
  return document.querySelector(`.${className}`);
}

const sections = [
  selectElementByClass("firstClass"),
  selectElementByClass("secondClass"),
  selectElementByClass("thirdClass"),
  selectElementByClass("fourthClass"),
  selectElementByClass("fifthClass"),
  selectElementByClass("sixtClass")
];

const navItems = {
  firstID: selectElementByClass("FirstNavItem"),
  secondID: selectElementByClass("SecondNavItem"),
  thirdID: selectElementByClass("ThirdNavItem"),
  fourthID: selectElementByClass("FourthNavItem"),
  fifthID: selectElementByClass("FifthNavItem"),
  sixtID: selectElementByClass("SixtNavItem")
};

// intersection observer setup
const observerOptions = {
  root: null,
  rootMargin: "0px",
  threshold: 0.1
};

function observerCallback(entries, observer) {
  entries.forEach((entry) => {
    if (entry.isIntersecting) {
      // get the nav item corresponding to the id of the section
      // that is currently in view
      const navItem = navItems[entry.target.id];
      //get the "alt" tag of section in view
      // alt tag equals slide index of swiper
      const navItemAlt = navItem.getAttribute("alt");
      // tell swiper to slide to the slide with index of "alt"
      swiper.slideTo(navItemAlt, 300, true)
      // add 'active' class on the navItem
      navItem.classList.add("swiper-slide-active2");
      // remove 'active' class from any navItem that is not
      // same as 'navItem' defined above
      Object.values(navItems).forEach((item) => {
        if (item != navItem) {
          item.classList.remove("swiper-slide-active2");
        }
      });
    }
  });
}

const observer = new IntersectionObserver(observerCallback, observerOptions);

sections.forEach((sec) => observer.observe(sec));
html {
  scroll-behavior: smooth;
}
.swiper-container {
  width: 100%;
}
.swiper-slide {
   padding: 10px;
   width: 33vw!important;
}
.swiper-slide-active2 {
  background-color: #95D5B2;
  border-radius: 25px;
}

.swiper-container ul {
  list-style-type: none;
  margin: 0;
  padding: 0;
}
.swiper-container a {
  color: black;
  text-align: center;
  text-decoration: none;
  display: inline-block;
  width: 100%;
  height: 100%;
}
.sticky {
  position: sticky;
  top: 0px;
}
section {
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 2.5rem;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.1/css/swiper.min.css" rel="stylesheet"/>
<!--Sticky wrapper-->
<div class="sticky">
<!--swiper container-->
<div class="swiper-container" id="scroll-tags">
  <ul class="swiper-wrapper">
    <a alt="0" class="swiper-slide FirstNavItem" href="#firstID">First</a>
    <a alt="1" class="swiper-slide SecondNavItem" href="#secondID">Second</a>
   <a alt="2" class="swiper-slide ThirdNavItem" href="#thirdID">Third</a>
   <a alt="3" class="swiper-slide FourthNavItem"href="#fourthID">Fourth</a>
   <a alt="4" class="swiper-slide FifthNavItem"href="#fifthID">Fifth</a>
    <a alt="5" class="swiper-slide SixtNavItem"href="#sixtID">Sixt</a>
    </ul>
</div>
</div>
<!--wrapping div to extend page below last section-->
<div style="height: 500vh">
<!--Page sections-->
   <section class="firstClass" id="firstID">
    <h1>
      First
    </h1>
  </section>
  <section class="secondClass" id="secondID">
    <h1>
      Second
    </h1>
  </section>
  <section class="thirdClass" id="thirdID">
    <h1>
      Third
    </h1>
  </section>
  <section class="fourthClass" id="fourthID">
    <h1>
      Fourth
    </h1>
  </section>
  <section class="fifthClass" id="fifthID">
    <h1>
      Fifth
    </h1>
  </section>
   <section class="sixtClass" id="sixtID">
    <h1>
      Sixt
    </h1>
  </section>
  <section></section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.1/js/swiper.min.js"></script>