问题
Assuming the following code (current state can be viewed here):
function scrollTopFromEvent(evt) {
return $(evt.target).scrollTop();
}
function scrollDirection(evt) {
return -evt.originalEvent.wheelDelta / 120 || evt.originalEvent.detail / 3;
}
function pageNumber(previous, next) {
return previous + next;
}
function scrollToPage(pageNumber) {
var container = $('.parallax');
TweenLite.to(container, 1, {
scrollTop: container.height() * (pageNumber)
});
}
function inRange(pageNumber) {
var totalPages = $('.parallax').find('div[id^="group"]').length;
return pageNumber >= 0 || pageNumber <= totalPages;
}
var scroll = $('.parallax')
.asEventStream('mousewheel DOMMouseScroll')
.doAction('.preventDefault').flatMap(scrollDirection);
var page = scroll
.scan(0, pageNumber)
.filter(inRange)
.log()
.onValue(scrollToPage);
I want to be able to limit the values emitted by the page
stream from 0 to n, n
being the totalPages
(defined in the inRange
method). In that particular case, there are 7 groups, so the range would be from 0 to 7
If a user scroll down to '7', and continues scrolling, no values would be emitted from the scroll stream.
Ideas?
Thanks
回答1:
I think what you actually want is to limit the value of scroll.scan(0, pageNumber)
to a certain range, not to maintain a "virtual" scroll position and display that only when it currently is in the range.
Try
var totalPages = $('.parallax').find('div[id^=group]').length; // static, right?
function pageNumber(previous, next) {
return Math.max(0, Math.min(totalPages, previous + next));
}
scroll.scan(0, pageNumber).onValue(scrollToPage);
回答2:
These are the changes I made:
In your pageNumber
function:
return previous + next >= $('.parallax__group').length ? previous : previous + next;
And in your inRange
function:
return pageNumber >= 0 && pageNumber < totalPages;
Here is a fiddle containing your code with my changes.
来源:https://stackoverflow.com/questions/25755267/bacon-js-ignoring-certain-values-in-a-stream