用鼠标滚轮切换元素

12

我想要做什么

*滚动时显示图片
看右边的移动句子。
switch scroll
就像这样,我想每次滚动时突出显示<p>元素。
也就是说,通常它的opacity: 0.3;,当它滚动时,从顶部逐个切换到opacity: 1;

like this

我认为我可以使用swiper.js来实现这一点。

now
我现在感觉是这样的,请也看看右侧的那个。
如果此滑块包装达到每个<p>的高度并停止滚动使用preventDefault(), 我认为实现会如预期。


我尝试过的

jQuery(未完成,这不起作用)

$(function() {
  $(".mai").scroll(function() {
    onScroll();
  });
  onScroll();
});

function onScroll() {
  $(".main-p p").each(function(i) {
    $(".main-p p").eq(i).removeClass("hl");    // mean highlight

  var scrPos = $(".main-p p:nth-last-child(2)");
  // I want to be second from the bottom of the "visible range" of .mai, not of <p>

  if(scrPos < active) {
    // If hl (= active) is above the second from the bottom of the range seen in .mai

    $('.mai').scroll(function(e) {
      e.preventDefault();
    });
  } else {
    $('.mai').scroll();
    // I want to return the scroll, but is this correct?
  }

  // I want to put processing to highlight with <p>, next <p>, next <p>..
  $('.main-p .active').addClass('hl');

  });
}

添加:当前状态

like this
请看右侧。
当图像在左侧位置滚动时,会应用高亮。
但是,如果滚动到右侧句子位置,则不会应用高亮。
并且,如果按照上方左侧的幻灯片导航,图像将正确移动到该幻灯片,但我也想突出显示句子。(Swiper设置为同步图像和文本)

我在这个问题的第二张图片中发现了一个看起来还不错的东西(实际上 "the middle of the frame" 不错..)。-> scrollama.js
我想保持这个“Basic”。
它正在设置 nth-child(2),但我想将其更改为 scrollama 的“Basic”。

换句话说,我想要:
1) 当滚动到右侧的句子时突出显示
2) 左右同步
3) 将 nth-child(2) 更改为 scrollama 的“Basic”

我创建了一个分支,将最新答案添加了一张图像和 scrollama。请 fork 这个-> JSFiddle

变得更长了..
很抱歉,请务必谅解!


代码

JSFiddle
↑由于某种原因,代码片段不能很好地工作,请查看 JSFiddle。
全屏 Fiddle 在此处此处

↓ 这里是仅代码部分。

$(function() {
  $(".mai").scroll(function() {
    onScroll();
  });
  onScroll();
});

function onScroll() {
  $(".main-p p").each(function(i) {
    $(".main-p p").eq(i).removeClass("hl");    // mean highlight

  var scrPos = $(".main-p p:nth-last-child(2)");
  // I want to be second from the bottom of the "visible range" of .mai, not of <p>

  if(scrPos < active) {
    // If hl (= active) is above the second from the bottom of the range seen in .mai

    $('.mai').scroll(function(e) {
      e.preventDefault();
    });
  } else {
    $('.mai').scroll();
    // I want to return the scroll, but is this correct?
  }

  // I want to put processing to highlight with <p>, next <p>, next <p>..
  $('.main-p .active').addClass('hl');

  });
}



// Processing of left & right sync with swiper
var swiperCnt = new Swiper('.swiperCnt', {
  direction: 'vertical',
  pagination: {
    el: '.swiper-pagination',
    type: 'bullets',
    clickable: 'true',
  },
  keyboard: {
    enabled: true,
  },
  mousewheel: {
    forceToAxis: true,
    invert: true,
  },
  renderBullet: function (index, className) {
    return '<span class="' + className + '">' + (index + 1) + '</span>';
  },
});

var swiperP = new Swiper('.swiperP', {
  direction: 'vertical',
  keyboard: {
    enabled: true,
  },
  mousewheel: {
    forceToAxis: true,
    invert: true,
  },
});

swiperCnt.controller.control = swiperP;
swiperP.controller.control = swiperCnt;
/* The corresponding part is at the bottom too. (It is faster to count from the bottom)
(There is a mark in the comment) */
html {
  font-size: 62.5%;
}

body {
  font-size: 1.5rem;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  background-color: #c6d2dd;
  color: white;
}

.wrap {
  height: 100vh;
  display: flex;
}

.left {
  padding: 0 0 0 2.4rem;
}

.right {
  padding: 0 4.7rem 0 6.5rem;
  position: relative;
}

h2,h3,h4,h5,h6 {
  display: inline;
}

.mission,
.m-p,
.concept,
.c-p,
.what,
.target,.t-p,.main-p,.nb,.nb-p,.period,.p-p,.category,.cg-p,.class,.cl-p,.release,.r-p,.nbb,.per,.cat,.cla,.rel {
  display: inline-block;
}

.title {
  font-size: 1.8rem;
  padding: 1.8rem 0 1.7rem 0;
}

.solid-ti {
  border-bottom: .1rem solid white;
  margin: 0 -56.3rem 0 -2.4rem;
}

.solid-mc {
  border-bottom: .1rem solid white;
  margin-left: -2.4rem;
}

.solid-tm {
  border-bottom: .1rem solid white;
  margin-right: -4.7rem;
}

.swiper-pagination {
  top: 6rem;
}

.swiper-container {
  width: 69.3rem;
  height: 49.6rem;
}

.swiper-slide {
  display: flex;
  align-items: center;
}
.swiper-slide img {
  width: 69.3rem;
}

.swiper-pagination-bullet {
  background: none;
  font-size: 1rem;
  margin-right: .5rem;
  opacity: .3;
}
.swiper-pagination-bullet::before {
  content: '0';
  font-weight: bold;
}
.swiper-pagination-bullet:hover::before {
  content: '1';
  font-weight: bold;
}

.swiper-pagination-bullet-active {
  background: none;
  transform: scale(1);
  transition-duration: .16s;
  opacity: .7;
}
.swiper-pagination-bullet-active::before {
  content: '1';
  font-weight: bold;
}

.mis {
  padding: 2.6rem 0 0.7rem 0;
}

.mission {
  padding-right: 2rem;
}

.con {
  padding-top: 0.7rem;
}

.concept {
  padding-right: 2rem;
}

.what {
  margin: 2rem 1.5rem 2.1rem 0;
  display: flex;
  align-items: center;
}
.what > img {
  height: 2rem;
  margin-right: .3rem;
}
.what > img:last-child {
  margin-right: 1rem;
}
.what span {
  font-size: 1.4rem;
  border: .1rem solid white;
  border-radius: .3rem;
  margin-right: 1rem;
  padding: .5rem .4rem .4rem;
}

.tar {
  padding: 2.2rem 0 2rem 0;
  flex-grow: 1;
}

.target {
  padding-right: 1.2rem;
}

.t-p {
  white-space: pre-wrap;
  vertical-align: top;
}

.heartbox {
  display: flex;
  align-items: center;
}
.heartbox div:last-child {
  user-select: none;
}

input {
  opacity: 0;
}

@keyframes rubberBand {
  from {
    transform: scale(1, 1, 1);
  }
  30% {
    transform: scale3d(1.15, 0.75, 1);
  }
  40% {
    transform: scale3d(0.75, 1.15, 1);
  }
  50% {
    transform: scale3d(1.1, 0.85, 1);
  }
  65% {
    transform: scale3d(0.95, 1.05, 1);
  }
  75% {
    transform: scale3d(1.05, 0.95, 1);
  }
  to {
    transform: scale3d(1, 1, 1);
  }
}
.heart {
  cursor: pointer;
  width: auto;
  height: 25px;
  fill: #E2E2E2;
}

#fav:checked + label .heart {
  fill: #e23b3b;
  animation: rubberBand 0.8s;
}





/*
 * from here
 */
.mai {
  margin: 2.8rem 0 0 0;
  height: 37.8rem;
  overflow-y: scroll;
  overflow-x: hidden;
  -ms-overflow-style: none;
}
.mai::-webkit-scrollbar {
  display: none;
}

.main-p {
  white-space: pre-wrap;
  opacity: 0.3;
}

.hl {
  opacity: 1;
}

/*
 * to here
 */





.▼ {
  float: right;
  margin-right: 1.5rem;
}

.under {
  text-align: right;
  position: absolute;
  right: 4.7rem;
  bottom: 2.7rem;
}

.nbb {
  padding-right: 4.8rem;
}

.nb {
  padding-right: .8rem;
}

.period {
  padding-right: 1.6rem;
}

.top {
  font-size: 1.1rem;
  padding: 2.1rem 0 2rem;
  text-align: right;
}

.cat {
  padding-right: 1.4rem;
}

.category {
  padding-right: 1.4rem;
}

.cla {
  padding-right: 1.4rem;
}

.class {
  padding-right: 1.4rem;
}

.rel {
  padding-right: 1.4rem;
}

.release {
  padding-right: 1.4rem;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/css/swiper.css" rel="stylesheet"/>

<!-- The corresponding part is at the bottom. (It is faster to count from the bottom)
(There is a mark in the comment) -->

<body class="wrap">

  <div class="left">
    <h1 class="title">title</h1>

    <div class="solid-ti"></div>

    <div class="swiper-pagination"></div>
    <div class="swiper-container swiperCnt">
      <section class="swiper-wrapper imgs">
        <div class="swiper-slide"><img class="work" src="http://placehold.jp/45/1920a6/ffffff/693x350.png?text=1" /></div>
        <div class="swiper-slide"><img class="work" src="http://placehold.jp/45/199fa6/ffffff/693x350.png?text=2" alt="Rollse-killer" /></div>
        <div class="swiper-slide"><img class="work" src="http://placehold.jp/45/a61972/ffffff/693x350.png?text=3" alt="Rollse-data" /></div>
        <div class="swiper-slide"><img class="work" src="http://placehold.jp/45/a6a619/ffffff/693x350.png?text=4" alt="Rollse-image" /></div>
      </section>
    </div>

    <div class="mis">
      <h3 class="mission">MISSION:</h3>
      <p class="m-p">sample sample sample sample sample sample sample sample </p>
    </div>

    <div class="solid-mc"></div>

    <div class="con">
      <h2 class="concept">CONCEPT:</h2>
      <p class="c-p">sample sample sample </p>
    </div>

    <div class="what">
      <img src="http://placehold.jp/45/d4d4d4/d4d4d4/28x20.png?text=_" alt="2nd" /><img src="http://placehold.jp/45/d4d4d4/d4d4d4/20x20.png?text=_" alt="ai" /><img src="http://placehold.jp/45/d4d4d4/d4d4d4/20x20.png?text=_" alt="vw" />

      <span>sample</span>
      <span>sample</span>
      <span>sample</span>
      <span>sample</span>
      <span>sample</span>
    </div>
  </div>

  <div class="right">
    <div class="top">
      <div class="cat">
        <h5 class="category">CATEGORY:</h5>
        <p class="cg-p">sample sample </p>
      </div>

      <div class="cla">
        <h5 class="class">CLASS:</h5>
        <p class="cl-p">sample </p>
      </div>

      <div class="rel">
        <h5 class="release">RELEASE:</h5>
        <p class="r-p">sample </p>
      </div>
    </div>
    <div class="heartbox">
      <div class="tar">
        <h3 class="target">TARGET:</h3>
        <p class="t-p">sample sample sample sample sample sample sample sample sample sample sample 
        </p>
      </div>
      <div>
        <input type="checkbox" name="fav" id="fav">
        <label for="fav">
            <svg class="heart" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
            viewBox="0 0 37 32" style="enable-background:new 0 0 37 32;" xml:space="preserve">
            <path class="st0" d="M27,0c-2.5,0-4.9,0.9-6.7,2.6C19.6,3.2,19,4,18.5,4.7C18,4,17.4,3.2,16.7,2.6C14.9,0.9,12.5,0,10,0
            C4.5,0,0,4.5,0,10c0,3.7,1.2,6.7,3.9,9.8c3.9,4.6,13.9,11.6,14.3,11.9c0.1,0.1,0.2,0.1,0.3,0.1s0.2,0,0.3-0.1
            c0.4-0.3,10.4-7.3,14.3-11.9c2.7-3.2,3.9-6.1,3.9-9.8C37,4.5,32.5,0,27,0z"/></svg>
          </label>
      </div>
    </div>

    <div class="solid-tm"></div>





    <!--
from here
-->
    <div class="mai swiper-container swiperP">
    <section class="main-p swiper-wrapper"><p class="active swiper-slide">Here is the relevant part. It can scroll.</p>

<p class="swiper-slide">sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample </p>

<p class="swiper-slide">sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample </p>

<p class="swiper-slide">sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample </p>
<p class="swiper-slide">sample sample sample sample sample sample sample sample sample sample sample sample sample sample </p>


<p class="swiper-slide">sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample </p>

<p class="swiper-slide">sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample </p>

<p class="swiper-slide">sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample sample </p>
<p class="swiper-slide">sample sample sample sample sample sample sample </p>
</section>
    </div>
    <!-- 
to here
-->





    <img src="http://placehold.jp/45/d4d4d4/d4d4d4/14x12.png?text=_" alt="▼" class="▼" width="14" />

    <div class="under">
      <div class="nbb">
        <h4 class="nb">N.B.:</h4>
        <p class="nb-p">sample </p>
      </div>

      <div class="per">
        <h4 class="period">PERIOD:</h4>
        <p class="p-p">sample </p>
      </div>
    </div>
  </div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.0/js/swiper.js"></script>

你能帮我一下吗?

1个回答

4
另一更新: 代码分支完整屏幕演示 要查看先前的帖子更新,请单击此处
右侧(文本)滚动的核心代码:
  var that;
  var i = 0;
  var j = $(".main-p > p").length - 1;
  $('.mai').bind('mousewheel', function(e) {
    if (e.originalEvent.wheelDelta < 0) {
      //scroll down
      i++;
      if (i >= j) {
        i = j;
      }
      if (i <= j) {
        $(".main-p > p").each(function(i) {
          if ($(this).hasClass('active')) {
            if ($(this).hasClass(i)) {
              if (i < j) {
                that = $(this).next();
              } else {
                that = $(this);
              }
            }
          }
          $(this).removeClass('active');
        });
        $(that).addClass('active');
      }
    } else {
      //scroll up
      i--;
      if (i <= 0) {
        i = 0;
      }
      if (i >= 0) {
        $(".main-p > p").each(function(i) {
          if ($(this).hasClass('active')) {
            if (i > 0) {
              that = $(this).prev();
            } else {
              that = $(this);
            }
          }
          $(this).removeClass('active');
        });
        $(that).addClass('active');
      }
    }
    swiperCnt.slideTo(i);
    //prevent page fom scrolling
    return false;
  });

解释:在向下 / 向上滚动时,使用 if >= / ><= / <i++i-- 用于检测是否越界,并作出相应响应。使用.next().prev在滚动时用于突出显示前一个或后一个元素。
对于左侧(img)滚动:
swiperCnt.on('scroll', function() {
  onScroll();
});

执行 onScroll() 函数的代码。


@POP,您能否检查一下更新是否是您想要的?谢谢。 - Mukyuu
你是想要像这个 https://jsfiddle.net/9b3acfq5/ 这样吗?还是你希望文本也可以滚动?需要与左侧部分同步吗? - Mukyuu
是的,这两者都是。我忘记让文本可以滚动。我已经在先前的代码片段中实现了滚动功能。-> 点击这里 - POP
我编辑了JSFiddle。1)在CSS中删除main-p {white-space: pre-wrap;}。2)在HTML中添加一些<br>。-> [JSFiddle](https://jsfiddle.net/__R2D2/cxeh6t3z/6/)但是,即使代码与我的本地代码完全相同,`<br>`在JSFiddle中也能正常工作。所以,我上传了我的实际本地情况[here](https://mqs2.com/broblem/br.html)。就像这样... - POP
我可以使用 pre-line 来留空行。但是在研究时,找到了根本原因。似乎文本的 line-height<br> 重叠,导致 <br> 看起来像消失了一样。 因此,通过将 <br> 添加到与文本相同的 line-height: 1.8; 中,我成功地实现了正确的留空行。 非常感谢您的帮助!! x) - POP
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接