2017-08-15 24 views
0

Velocity在我的项目中有部分工作,但我遇到的问题在JSFiddle(下面的链接)中是可重现的,我认为它可能以某种方式与项目的GitHub上的问题#770相关页。VelocityJS相对容器中的滚动错误

(注:我有联系这一点,下面的其他物品,但没有信誉后超过2个链接,所以我的道歉不必看这些了。)

我会想知道如果有人能:

  • 确认这是一个已知的bug,
  • 看到一个修复此问题,
  • 我在执行查找错误,或
  • 提供替代解决方案。

我正在构建一个网站实现一个屏幕推菜单,其中整个内容被包装在一个相对DIV中,该DIV使用CSS变换来显示菜单。有几个级别相对定位的DIV模拟我站点标题的固定位置(必要时,它包含在推送菜单DIV中)。

推菜单从一个Codrops游乐场文章适于(搜索上Tympanus.net“多电平推菜单”)。有一篇文章链接了一个演示。还有一个链接,指向元素的虚假固定位置以及文章内CSS转换(半路向下)。

我的开发网站上的菜单按预期工作。我从一些菜单项中实现Velocity以向下滚动到内部页面部分,这也可以正常工作(从页面顶部滚动)。

但是,我还想使用Velocity从页面顶部的固定位置侧边栏滚动,以允许用户点击部分标题自动滚动到该部分。 不幸的是,侧边栏链接只有在页面滚动到最上方时才有效。从其他滚动位置,链接无法正常工作。

如果页面向下滚动,则单击任何链接只会向下滚动页面,即使点击事件中请求的部分高于当前滚动位置。

行为最能在这个小提琴可以看出: http://jsfiddle.net/Josefism/j4dLhssc/

基本站点结构

<div class="site-container"> 
    <div class="menu-pusher"> 
    <div class="scroller"> 
     <div class="scroller-inner"> 
     <div class="site-inner"> 
      <div class="content-sidebar-wrap"> 
      <main class="content"> 
       <article class="page"> 
       <div class="entry-content"> 
        <div id="section-1" class="section-1"> 
        <p>Spicy jalapeno bacon ipsum.</p>  
        <p>Cupim aliqua culpa bacon.</p>  
        <p>Aliqua irure qui chicken.</p> 
        </div><!-- End Section 1 --> 

        <div id="section-2" class="section-2"> 
        <p>Spicy jalapeno bacon ipsum.</p>  
        <p>Cupim aliqua culpa bacon.</p>  
        <p>Aliqua irure qui chicken.</p> 
        </div><!-- End Section 2 --> 

        <div id="section-3" class="section-3"> 
        <p>Spicy jalapeno bacon ipsum.</p>  
        <p>Cupim aliqua culpa bacon.</p>  
        <p>Aliqua irure qui chicken.</p> 
        </div><!-- End Section 3 --> 

        <div id="section-4" class="section-4"> 
        <p>Spicy jalapeno bacon ipsum.</p>  
        <p>Cupim aliqua culpa bacon.</p>  
        <p>Aliqua irure qui chicken.</p> 
        </div><!-- End Section 4 --> 

       </div><!-- End Entry Content --> 
       </article> 
      </main> 
      <aside class="sidebar"> 
       <section class="widget"> 
       <div class="widget-wrap"> 
        <div class="text-widget"> 
        <ul class="sidebar-menu"> 
         <li class="section-1-link">Section 1</li> 
         <li class="section-2-link">Section 2</li> 
         <li class="section-3-link">Section 3</li> 
         <li class="section-4-link">Section 4</li> 
        </ul> 
        </div><!-- End Text Widget --> 
       </div><!-- End Widget Wrap --> 
       </section> 
      </aside> 
      </div><!-- End Content Sidebar Wrap --> 
     </div><!-- End Site Inner --> 
     </div><!-- End Scroller Inner --> 
    </div><!-- End Scroller --> 
    </div><!-- End Menu Pusher --> 
</div><!-- End Site Container --> 

CSS(仅在修改,以适应问题的jsfiddle再现)

body { 
    font-family: Helvetica; 
    width: 95%; 
    margin: 0 auto; 
    color: white; 
    background: red; 
    height: 100%; 
    overflow: hidden; 
} 

.site-container { 
    position: relative; 
    overflow: hidden; 
    height: 100%; 
    margin-top: 90px; 
} 

.menu-pusher { 
    position: relative; 
    left: 0; 
    height: 100%; 
} 

.scroller { 
    position: relative; 
    overflow-y: scroll; 
    height: 400px; 
} 

.scroller-inner { 
    position: relative; 
} 

.site-inner { 
    position: relative; 
} 

main { 
    display: block; 
} 

.content { 
    float: right; 
} 

.content-sidebar-wrap .content { 
    width: 100%; 
} 

.sidebar { 
    float: left; 
    width: 100%; 
    top: 0px; 
    position: fixed; 
    display: block; 
} 

.sidebar .widget { 
    padding: 20px; 
    display: block; 
    background-color: #CCC; 
    color: #FFF; 
} 

.sidebar-menu { 
    text-align: center; 
} 

.sidebar-menu li { 
    list-style-type: none; 
    padding: 0 1%; 
    cursor: pointer; 
    display: inline-block; 
} 

.sidebar-menu li:hover, 
.sidebar-menu li.hovered { 
    color: green; 
} 

.page { 
    display: block; 
} 

.section-1 { 
    background-color: #ddd; 
    color: #000; 
    padding: 20px 20px 100px 20px; 
} 

.section-2 { 
    background-color: #FFF; 
    color: #000; 
    padding: 20px 20px 100px 20px; 
} 

.section-3 { 
    background-color: #AAA; 
    color: #FFF; 
    padding: 20px 20px 100px 20px; 
} 

.section-4 { 
    background-color: #555; 
    color: #FFF; 
    padding: 20px 20px 100px 20px; 
    margin-bottom: 100px; 
} 

jQuery Velocity Implementation(不包括我的Velocity实现菜单项,因为那些已经工作。)

$(document).ready(function(e) { 

    // Add Velocity scrolling to the internal section sidebar links 
    $(".section-1-link").on("click", function() { 
    $("#section-1").velocity("stop", true).velocity("scroll", { 
     container: $(".scroller"), 
     duration: 1000, 
     easing: "easeInOutSine", 
     delay: 300, 
     offset: 1 
    }); 
    }); 
    $(".section-2-link").on("click", function() { 
    $("#section-2").velocity("stop", true).velocity("scroll", { 
     container: $(".scroller"), 
     duration: 1000, 
     easing: "easeInOutSine", 
     delay: 300, 
     offset: 1 
    }); 
    }); 
    $(".section-3-link").on("click", function() { 
    $("#section-3").velocity("stop", true).velocity("scroll", { 
     container: $(".scroller"), 
     duration: 1000, 
     easing: "easeInOutSine", 
     delay: 300, 
     offset: 1 
    }); 
    }); 
    $(".section-4-link").on("click", function() { 
    $("#section-4").velocity("stop", true).velocity("scroll", { 
     container: $(".scroller"), 
     duration: 1000, 
     easing: "easeInOutSine", 
     delay: 300, 
     offset: 1 
    }); 
    }); 

    // Callback to section menu in primary sidebar to indicate scroll position 
    $(".scroller").on("scroll", function() { 
    var scrollerTop = $(".scroller").scrollTop(); 
    var section1TopDist = $("#section-1").offset().top; 
    var section2TopDist = $("#section-2").offset().top; 
    var section3TopDist = $("#section-3").offset().top; 
    var section4TopDist = $("#section-4").offset().top; 
    if (section4TopDist < 90) { 
     $(".section-2-link, .section-3-link, .section-1-link").removeClass("hovered"); 
     $(".section-4-link").addClass("hovered"); 
    } else if (section3TopDist < 90) { 
     $(".section-2-link, .section-1-link, .section-4-link").removeClass("hovered"); 
     $(".section-3-link").addClass("hovered"); 
    } else if (section2TopDist < 90) { 
     $(".section-1-link, .section-3-link, .section-4-link").removeClass("hovered"); 
     $(".section-2-link").addClass("hovered"); 
    } else if (section1TopDist < 90) { 
     $(".section-2-link, .section-3-link, .section-4-link").removeClass("hovered"); 
     $(".section-1-link").addClass("hovered"); 
    } else { 
     $(".section-1-link, .section-2-link, .section-3-link, .section-4-link").removeClass("hovered"); 
    } 
    }); 

}); 

回答

0

那么,经过一些测试和故障排除后,我想通了什么导致了我的问题。如果使用Velocity.js的其他人遇到类似的问题,那么我在这里发布我的解决方案作为疑难解答参考。

问题如下面代码块中的注释所述,“scrollPositionCurrent”被添加到新的滚动位置并抛出返回的总数。从计算中移除它对我来说确实有窍门,现在在一个包含元素中滚动可以按预期工作。

我已经在其他站点中使用我修改的Velocity.js文件来滚动整个页面,但没有包含元素,并且仍然可以正常工作。

以下代码块来自GitHub上当前版本的Velocity.js的行3171-3205,前几天(2017年10月中旬)。

原始代码仍然存在于代码片段中供参考,但已被注释掉。

/* Scroll also uniquely takes an optional "container" option, which indicates the parent element that should be scrolled -- 
as opposed to the browser window itself. This is useful for scrolling toward an element that's inside an overflowing parent element. */ 
if (opts.container) { 
    /* Ensure that either a jQuery object or a raw DOM element was passed in. */ 
    if (Type.isWrapped(opts.container) || Type.isNode(opts.container)) { 
     console.log("GOT IT!"); 
     /* Extract the raw DOM element from the jQuery wrapper. */ 
     opts.container = opts.container[0] || opts.container; 
     /* Note: Unlike other properties in Velocity, the browser's scroll position is never cached since it so frequently changes 
     (due to the user's natural interaction with the page). */ 
     scrollPositionCurrent = opts.container["scroll" + scrollDirection]; /* GET */ 

     /* $.position() values are relative to the container's currently viewable area (without taking into account the container's true dimensions 
     -- say, for example, if the container was not overflowing). Thus, the scroll end value is the sum of the child element's position *and* 
     the scroll container's current scroll position. */ 
     /* scrollPositionEnd = (scrollPositionCurrent + $(element).position()[scrollDirection.toLowerCase()]) + scrollOffset; */ /* GET */ 
     /* CORRECTION - Applied by Josef Cook 
      Scroll position of element within a containing element was incorrect. Adding current scroll position blows out the total. 
      Had to remove current scroll position addition (commented out above) to make this work correctly. */ 
     scrollPositionEnd = ($(element).position()[scrollDirection.toLowerCase()]) + scrollOffset; 
     /* If a value other than a jQuery object or a raw DOM element was passed in, default to null so that this option is ignored. */ 
    } else { 
     opts.container = null; 
    } 
} else { 
    /* If the window itself is being scrolled -- not a containing element -- perform a live scroll position lookup using 
    the appropriate cached property names (which differ based on browser type). */ 
    scrollPositionCurrent = Velocity.State.scrollAnchor[Velocity.State["scrollProperty" + scrollDirection]]; /* GET */ 
    /* When scrolling the browser window, cache the alternate axis's current value since window.scrollTo() doesn't let us change only one value at a time. */ 
    scrollPositionCurrentAlternate = Velocity.State.scrollAnchor[Velocity.State["scrollProperty" + (scrollDirection === "Left" ? "Top" : "Left")]]; /* GET */ 

    /* Unlike $.position(), $.offset() values are relative to the browser window's true dimensions -- not merely its currently viewable area -- 
    and therefore end values do not need to be compounded onto current values. */ 
    scrollPositionEnd = $(element).offset()[scrollDirection.toLowerCase()] + scrollOffset; /* GET */ 
}