创建无缝嵌套滚动翻转

时间:2015-05-27 06:42:06

标签: javascript jquery css html5 scroll

我正在尝试创建一系列窗口大小的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,for 图书馆ISCROLL5 (好吧,如果性能影响很小)

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

    对于选项2:ISCROLL5有超过15-20个滚动div的不良性能损失。

    我希望我在这里遗漏一些东西,任何解决方案,修复或建议都会非常感激。

2 个答案:

答案 0 :(得分: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>

答案 1 :(得分:1)

没有想法你为什么要这样做,但我能想到实现你想要的效果的唯一方法就是重新创建滚动条,但好消息是这不需要以失去原生的经历为代价。

可悲的是,我记不起我编写此代码的项目,但实现此目的的一种方法是使自己成为滚动条组件。这个滚动条组件确实会提供一个假滚动条,但提供一个本机类似的界面。那么,你是怎么做到的?

  1. 通过获取带有和不带overflow: scroll的元素之间的差异来确定滚动条的宽度。这是scrollWidth
  2. 您在身体右侧创建了<div> overflow: auto宽度为scrollWidthposition: fixed的{​​{1}}。让scrollTop属性为scrollPosition
  3. 在元素内添加另一个<div>,其宽度为0(这至少可以在Chrome中使用,检查其他浏览器是否有不同的处理方法)并让高度为documentLength
  4. 现在,您可以通过任意方式设置documentLengthscrollPosition来完全控制滚动条。在您的情况下,您可以将documentLength设置为每个元素的组合scrollHeights,并根据这些节点中的相对scrollPosition设置scrollTop
  5. 可以在此jsfiddle中找到概念(非实施)的基本演示(请注意,在这种情况下,滚动条的width固定为20px,并且没有任何动态代码。)