代码之家  ›  专栏  ›  技术社区  ›  Dave Merwin

通过在不需要使用普通Javascript滚动的对象上滚动来触发另一个dom对象的滚动

  •  0
  • Dave Merwin  · 技术社区  · 7 年前

    我有一个小的滚动互动,在需要滚动的元素中工作得很好。但我希望当我在一个不需要滚动的对象上滚动时,其他对象的滚动行为也会发生。

    例如,在下面的代码中,我希望allScroll事件触发其他dom对象的滚动。

      <script>
        var isSyncingTopScroll = false;
        var isSyncingBottomScroll = false;
        var isSyncingLogoScroll = false;
        var topPhrase = document.getElementById('top-phrase');
        var bottomPhrase = document.getElementById('bottom-phrase');
        var logo = document.getElementById('logo');
        var allScroll = document.getElementById('scroll-landing');
    
        allScroll.onscroll = function() {
          if (!isSyncingTopScroll || !isSyncingBottomScroll || !isSyncingLogoScroll) {
            isSyncingTopScroll = true;
            isSyncingBottomScroll = true;
            isSyncingLogoScroll = true;
            topPhrase.scrollTop = this.scrollTop;
            bottomPhrase.scrollTop = this.scrollTop;
            logo.scrollTop = this.scrollTop;
          }
          isSyncingBottomScroll = false;
        }
    
        topPhrase.onscroll = function() {
          if (!isSyncingTopScroll) {
            isSyncingBottomScroll = true;
            isSyncingLogoScroll = true;
            bottomPhrase.scrollTop = this.scrollTop;
            logo.scrollTop = this.scrollTop;
          }
          isSyncingBottomScroll = false;
        }
    
        bottomPhrase.onscroll = function() {
          if (!isSyncingBottomScroll) {
            isSyncingTopScroll = true;
            isSyncingLogoScroll = true;
            topPhrase.scrollTop = this.scrollTop;
            logo.scrollTop = this.scrollTop;
          }
          isSyncingTopScroll = false;
        }
    
        logo.onscroll = function() {
          if (!isSyncingLogoScroll) {
            isSyncingTopScroll = true;
            isSyncingBottomScroll = true;
            topPhrase.scrollTop = this.scrollTop;
            bottomPhrase.scrollTop = this.scrollTop;
          }
          isSyncingLogoScroll = false;
        }
    
        allScroll.dispatchEvent(new Event('scroll'));
    
      </script>
    

    所以,当我滚动allScroll时,其他对象应该滚动。然而,什么都没有发生,我也没有犯任何错误。

    有人吗?

    以下是HTML:

    <section id="scroll-landing">
      <div id="scroll-display">
        <div id="we">Lorem</div>
        <div id="top-phrase">
          <ul id="top-phrase-scroll">
            <li>Lorem</li>
            <li>Lorem lorem lrem</li>
            <li>Lorem lorem lrem</li>
          </ul>
        </div>
        <div id="logo">
          <div id="logo-display">
            Lorem lorem lrem
          </div>
        </div>
        <div id="bottom-phrase">
          <ul id="bottom-phrase-scroll">
            <li>Lorem lorem lrem</li>
            <li></li>
            <li class="hc">Lorem lorem lrem</li>
            <li class="sd">Lorem lorem lrem</li>
            <li class="ed">Lorem lorem lrem</li>
            <li class="dt">Lorem lorem lrem</li>
          </ul>
        </div>
        <div id="design"></div>
        <div id="pop-out"></div>
      </div>
    </section>
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   traktor    7 年前

    发送事件是同步处理的,因此在 allScroll 不会做任何事,因为 allScroll 对象)在调度事件时没有事件侦听器。

    试着搬家

    allScroll.dispatchEvent(new Event('scroll'));
    

    到代码的底部。


    使现代化 :

    首先是同步顶部短语、徽标和底部短语的垂直滚动偏移的示例:

    "use strict";
    let synchedElements = [
        document.getElementById("top-phrase"),
        document.getElementById("logo"),
        document.getElementById("bottom-phrase")
    ];
    
    function syncScroll( event) {
         let target = event.target;
         synchedElements.forEach( function ( element) {
             if( element != target) {
                 element.scrollTop = target.scrollTop;
             }
          });
    }
    synchedElements.forEach( function( element) {
        element.addEventListener("scroll", syncScroll, false);
    });
    
    function scrollAll( scrollTop) {
        syncScroll( {target: {scrollTop}});
    }
         
    #top-phrase, #logo, #bottom-phrase {
         border: thin solid grey;  /* testing */
         max-height: 3em;
         overflow-x: hidden;
         overflow-y: scroll;
    }
    <section id="scroll-landing">
      <div id="scroll-display">
        <div id="we">Lorem</div>
        <div id="top-phrase">
          <ul id="top-phrase-scroll">
            <li>Lorem</li>
            <li>Lorem lorem lrem</li>
            <li>Lorem lorem lrem</li>
          </ul>
        </div>
        <div id="logo">
          <div id="logo-display">
            Lorem lorem lrem
          </div>
        </div>
        <div id="bottom-phrase">
          <ul id="bottom-phrase-scroll">
            <li>Lorem lorem lrem</li>
            <li></li>
            <li class="hc">Lorem lorem lrem</li>
            <li class="sd">Lorem lorem lrem</li>
            <li class="ed">Lorem lorem lrem</li>
            <li class="dt">Lorem lorem lrem</li>
          </ul>
        </div>
        <div id="design"></div>
        <div id="pop-out"></div>
      </div>
    </section>
    <hr>
    <button type="button" onclick="scrollAll(0)">scrollAll(0)</button>
    <button type="button" onclick="scrollAll(30)">scrollAll(30)</button>

    写下这段话后,有些事情变得更清楚了:

    • scroll事件是一个通知事件,它不传递元素的滚动程度。

    • 滚动事件不会将DOM从一个元素冒泡到另一个元素,滚动文档除外 body 元素确实会起泡到 window .

    • 如果所有元素最初都有 scrollTop 值为零,将滚动事件发送到 allScroll 在发布的代码中,在初始状态下不会执行任何操作。

    • 滚动事件的调度速度很快,处理每一个事件都会降低显示更新的速度。请在Stack Overflow和web上搜索限制已处理事件数量的潜在方法。

    上面的代码是为了看到同步滚动的效果,并提供给大家以供参考,希望它能有所帮助——它可能不会(也可能不会)实现您的所有需求。

    推荐文章