2017-08-15 31 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 */ 
}