Velocity正在我项目的一部分工作,但我遇到的问题在JSFiddle中可以重现(链接如下),我认为它可能与项目的GitHub上的问题#770有关。页。
(注意:我在下面有这个和其他文章的链接,但是不具备发布超过2个链接的声誉,所以我很抱歉不得不查看这些链接。)
我想知道是否有人可以:
我正在构建一个实现屏幕外推送菜单的网站,其中整个内容包装在相对DIV中,该DIV使用CSS变换向右推,以显示菜单。有几个级别的相对定位的DIV模仿我的站点标题的固定位置(必要时,它包裹在推送菜单DIV中)。
推送菜单改编自 Codrops Playground 文章(搜索"多级推送菜单"在Tympanus.net上)。该文章链接了一个演示。还有一个关于元素的虚假定位注释的链接,结合文章中的CSS变换(中途)。
我的开发网站上的菜单按预期工作。我从一些菜单项中实现了Velocity,向下滚动到内部页面部分,这也很好(从页面顶部滚动)。
然而,我还希望在页面顶部的固定位置侧边栏中使用Velocity滚动,以允许用户单击部分标题以自动滚动到该部分。 不幸的是,侧栏链接仅在页面滚动到最顶层时才起作用。从任何其他滚动位置开始,链接无法正常运行。
如果页面向下滚动,则单击任何链接仅向下滚动页面,即使click事件中请求的部分高于当前滚动位置。
在这个小提琴中最好看到这种行为: 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 :(得分:0)
好吧,经过一些测试和故障排除后,我发现了导致我问题的原因。如果使用Velocity.js的其他人在包含元素内滚动时遇到类似的问题,我在此处发布我的解决方案作为故障排除参考。
问题,如下面代码块中的注释所述,是&#34; scrollPositionCurrent&#34;被添加到新的滚动位置并丢弃返回的总数。从计算中删除它对我来说是诀窍,现在在包含元素内滚动按预期工作。
我已经在其他网站中使用了我修改过的Velocity.js文件来滚动整个页面而没有包含元素,并且它仍然可以正常工作。
下面的代码块来自几天前(2017年10月中旬)GitHub上当前版本的Velocity.js的第3171-3205行。
原始代码仍然存在于代码段中以供参考,但已被注释掉。
/* 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 */
}