【问题标题】:Creating Seamless nested scroll rollover创建无缝嵌套滚动翻转
【发布时间】:2015-08-09 02:19:40
【问题描述】:

我正在尝试创建一系列窗口大小的 div,其内部 div 大小可变 > 窗口大小。问题是它需要滚动,就好像没有嵌套的 div 一样。

简而言之,我想要这个:

css{
     block{ height:100wh; }
     innerBlockSmall{ height:100wh; }
     innerBlockLarge{ height:200wh; }
}


<div class="block">
    <div class="innerBlockLarge"></div>
</div>
<div class="block">
    <div class="innerBlockSmall"></div>
</div>

https://jsfiddle.net/cbuh8psd/

像这样行事

css{
     innerBlockSmall{ height:100wh; }
     innerBlockLarge{ height:200wh; }
}

    <div class="innerBlockLarge"></div>
    <div class="innerBlockSmall"></div>

https://jsfiddle.net/t6zrvo7u/1/

不幸的是,滚动“焦点”是由hover在可滚动元素上触发的。在这种情况下,这是一种不良行为。

目前我知道有两种可能的解决方案。

  1. 通过 javascript 手动分配滚动“焦点”。 (最佳)

  2. 完全覆盖默认的 HTML 滚动 javascript,用于 例如库 ISCROLL5。
    (好的,如果性能影响很小)

不幸的是,在浏览了 developer.mozilla 的 HTML5 文档后,我没有遇到任何通过 javascript 来“聚焦”滚动到元素的方法。

至于选项 2:ISCROLL5 在超过 15-20 个滚动 div 的情况下对性能造成了不良影响。

我希望我在这里遗漏了一些东西,任何解决方案、修复或建议将不胜感激。

【问题讨论】:

  • .sbRemover 中删除overflow: auto 会禁用悬停时的滚动。
  • 遗憾的是,这种行为并不是那么简单。删除 overflow: auto 会导致元素根本不滚动。所需的行为是嵌套的 &lt;div class="block"&gt;scrolls 溢出到 &lt;body&gt; 滚动,就好像它们没有嵌套一样。请参阅第二个 JS 小提琴以了解所需的行为
  • @DigitalDouble 感谢您的快速回复。任何和所有建议都是有帮助的。
  • 我没完全理解,我的英语不太好:)。 div不能滚动?而是溢出:自动使用溢出:隐藏?

标签: javascript jquery css html scroll


【解决方案1】:

知道你为什么要这样做,但我能想到实现你想要的效果的唯一方法是重新创建滚动条,但好消息是这不必以失去您的母语经验为代价。

遗憾的是,我不记得我为哪个项目编写了此代码,但实现此目的的一种方法是让自己成为滚动条组件。这个滚动条组件确实会提供一个假滚动条,但会提供类似原生的界面。那么,你是怎么做到的呢?

  1. 您可以通过计算带有和不带有overflow: scroll 的元素之间的差异来确定滚动条的宽度。让它成为scrollWidth
  2. 您创建了一个&lt;div&gt;,其宽度为overflow: autoscrollWidthposition: fixed 位于主体右侧。让scrollTop 属性为scrollPosition
  3. 在元素内添加另一个宽度为0&lt;div&gt;(这至少在Chrome 中有效,请检查其他浏览器是否有不同的处理方式)并将高度设为documentLength
  4. 现在,您可以通过任意设置documentLengthscrollPosition 来完全控制滚动条。在您的情况下,您可以根据这些节点中的相对 scrollTopdocumentLength 设置为每个元素的组合滚动高度和 scrollPosition

可以在jsfiddle 中找到一个非常基本的概念演示(不是实现)(注意滚动条的width 在这种情况下固定为20px,并且没有任何动态代码)。

【讨论】:

    【解决方案2】:

    此解决方案允许滚动整个文档,同时保留使用鼠标滚动每个嵌套 div 的可能性。希望我理解正确。

    这只是一个概念,它不会阻止嵌套元素随着窗口滚动。但可以改进。

    Array.prototype.slice.call( document.getElementsByClassName('sbRemover') )
    .forEach(function (div) {
        var scroll = 0,
            mousedown = false,
            mouseBtnHandler = function (e) {
                mousedown = e.type == 'mousedown';
            }
        
        div.addEventListener('scroll', function (e) {
            // Change of div's scrollTop. Negative when scrolling down
            var diff = scroll - e.target.scrollTop;
            // Save new scroll value to be able to compare with it later
            scroll = e.target.scrollTop;
            // Do nothing when div is scrolled by dragging the scrollbar
            if (!mousedown) {
                // Scroll the window to the same amount of pixels the div was scrolled
                window.scrollTo(window.pageXOffset, window.pageYOffset - diff);
            }
        });
        div.addEventListener('mouseup', mouseBtnHandler);
        div.addEventListener('mousedown', mouseBtnHandler);
    });
    body, div {
        margin: 0;
        padding: 0;
    }
    .block{
        position: relative;
        width:100vw;
        height:100vh;
        overflow: hidden;
        z-index: 1;
        opacity: 100;
    }
    .sbRemover{
        width:100%;
        height:100%;
        padding-right:15px;
        overflow: auto;
    }
    .largeContent{
        height:225vh;
    }
    .smallContent{
        height:100vh;
    }
    <div id="simpleCanvas">
      <div class="block" style="background-color: blue">
        <div class="sbRemover">
          <div id="ok" class="largeContent" style="background-image: url('http://silviahartmann.com/background-tile-art/images/grey-repeating-background-8.jpg');"></div>
        </div>
      </div>
      <div class="block" style="background-color: red;">
        <div class="sbRemover">
          <div class="largeContent" style="background-image: url('http://a1star.com/images/star--background-seamless-repeating9.jpg');"></div>
        </div>
      </div>
      <div class="block" style="background-color: green">
        <div class="sbRemover">
          <div class="smallContent"></div>
        </div>
      </div>
      <div class="block" style="background-color: blue">
        <div class="sbRemover">
          <div class="smallContent"></div>
        </div>
      </div>
      <div class="block" style="background-color: red;">
        <div class="sbRemover">
          <div class="largeContent" style="background-image: url('http://people.stfx.ca/x2011/x2011ane/info102/assignment1/11500341-abstract-colorful-repeating-background.jpg');"></div>
        </div>
      </div>
      <div class="block" style="background-color: green">
        <div class="sbRemover">
          <div class="smallContent"></div>
        </div>
      </div>
    </div>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-04
      • 1970-01-01
      • 2018-12-29
      • 2011-07-07
      • 1970-01-01
      • 1970-01-01
      • 2012-07-17
      • 1970-01-01
      相关资源
      最近更新 更多