问题描述
我有一些特定时间线的代码,问题是: 滚动时(顶部和底部)时间轴中的背景项目没有在正确的时间显示
当相关项垂直居中时,我需要显示背景,例如,在最后一个和倒数第二个背景中有一个显示偏移。
请看一下 GIF:https://gfycat.com/possiblesadcowbird
JS 代码(我取自:https://codepen.io/knyttneve/pen/bgvmma?editors=0010 并根据我的项目对其进行了编辑):
var fn_timeline = function() {
$.fn.timeline = function() {
var selectors = {
id: $(this),item: $(this).find(".timeline-item"),activeClass: "timeline-item--active",img: ".o-timeline__img > img"
};
selectors.item.eq(0).addClass(selectors.activeClass);
selectors.id.css("background-image","url(" + selectors.item.first().find(selectors.img).attr("src") + ")");
var itemLength = selectors.item.length;
$(window).scroll(function() {
var max,min;
var pos = $(this).scrollTop();
selectors.item.each(function(i) {
min = $(this).offset().top;
max = ($(this).height() + $(this).offset().top);
var that = $(this)
if (i == itemLength - 2 && pos > min + $(this).height() / 2) {
selectors.item.removeClass(selectors.activeClass);
selectors.id.css("background-image","url(" + selectors.item.last().find(selectors.img).attr('src') + ")");
selectors.item.last().addClass(selectors.activeClass)
} else if (pos <= max - 40 && pos >= min) {
selectors.id.css("background-image","url(" + $(this).find(selectors.img).attr('src') + ")");
selectors.item.removeClass(selectors.activeClass);
$(this).addClass(selectors.activeClass);
}
});
});
}
$("#timeline-1").timeline();
}
HTML 代码:
<div class="timeline-wrapper container-content container-content--smaller container-content--fake-col timeline1col ">
<div class="timeline-container" id="timeline-1" style="background-image: url("img/tl-3.jpg");">
<div class="timeline">
<div id="fullpage">
<div class="section timeline-item-wrapper timeline-item">
<div class="timeline-marker"></div>
<div class="timeline__content">
<div class="timeline-minature">
<div class="o-timeline__img timeline-img">
<img src="img/tl-1.jpg" style="width: 350px">
</div>
</div>
<h2 class="timeline__content-title">Le premier ordinateur</h2>
<div class="wysiwyg">
He was born in 1881 (probably in the spring) in Salonica,then an ottoman city,Now inGreece. His father Ali Riza,a customs official turned lumber merchant,died when Mustafawas still a boy. His mother Zubeyde,adevout and strong-willed woman,raised him and his sister.
</div>
<a href="#" class="a-link--border-effect timeline-link">
* Qu’est-ce que la géodésie ?
</a>
</div>
</div>
<div class="section timeline-item-wrapper timeline-item">
<div class="timeline-marker"></div>
<div class="timeline__content">
<div class="timeline-minature">
<div class="o-timeline__img timeline-img">
<img src="img/tl-2.jpg" style="width: 350px">
</div>
</div>
<p class="timeline__content-date">1991</p>
<div class="wysiwyg">
He was born in 1881 (probably in the spring) in Salonica,raised him and his sister.
</div>
</div>
</div>
<div class="section timeline-item-wrapper timeline-item timeline-item--active">
<div class="timeline-marker"></div>
<div class="timeline__content">
<div class="timeline-minature">
<div class="o-timeline__img timeline-img">
<img src="img/tl-3.jpg" style="width: 350px">
</div>
</div>
<h2 class="timeline__content-title">Le premier ordinateur</h2>
<div class="wysiwyg">
He was born in 1881 (probably in the spring) in Salonica,raised him and his sister.
</div>
<a href="#" class="a-link--border-effect timeline-link">
* Qu’est-ce que la géodésie ?
</a>
</div>
</div>
<div class="section timeline-item-wrapper timeline-item">
<div class="timeline-marker"></div>
<div class="timeline__content">
<div class="o-timeline__img timeline-bg">
<img src="img/tl-4.jpg" alt="">
</div>
<h2 class="timeline__content-title">just bg</h2>
<div class="wysiwyg">
He was born in 1881 (probably in the spring) in Salonica,raised him and his sister.
</div>
</div>
</div>
</div>
</div>
</div>
</div>
解决方法
这是数学和用户体验设计问题的结合。 (正是我喜欢的那种问题!)
首先,您必须考虑用户是向上还是向下滚动。这是关键。
根据滚动方向,您将检查 item
顶部 OR 底部的位置。
例如,如果您只比较项目的顶部,则用户必须向上滚动整个项目,直到顶部越过中间,然后它才会变得模糊。那是不行的。
所以这真的是关于用户体验方面的: 当用户向下滚动时(因此内容向上移动),他需要在“某个点”显示下一个项目。 因为他可能还在看图片下方的文字,所以我觉得“点”在视口中间有点上方......但不是太高。
当用户向上滚动时(因此内容向下移动),他当然希望从上方看到的内容在视口中间之前不模糊。
所以...您需要考虑两个不同的视口位置。之后我称这些点为“触发”。
- 中间稍上方(向下滚动)
- 在顶部下方(向上滚动)
============
所以这变得越来越复杂...
两个滚动方向和两个视口位置以与顶部或项目的底部进行比较。
所以我创建了两个变量来保存基于 4 个方面的条件结果:
- 向上或向下滚动
- 滚动像素小于项目的顶部或底部
- “触发器”大于项目的顶部
- “触发器”+ 20px 小于项目的底部(即避免闪烁...记住您在循环中)
我将两个“视口位置”定义为 5/16
和 3/16
...
但是您可能更喜欢某些百分比值,例如 0.31
和 0.19
...您可以使用它。
(function ($) {
$.fn.timeline = function () {
var selectors = {
id: $(this),item: $(this).find(".timeline-item"),activeClass: "timeline-item--active",img: ".timeline__img"
};
// Onload,set first item as active
selectors.item.eq(0).addClass(selectors.activeClass);
// The viewport height
var winHeight = $(window).height();
// For the scrolling direction
var lastPos = 0;
// Scroll event handler
$(window).scroll(function () {
var item_bottom,item_top,item_height,scrollDown,trigger_top,trigger_bottom;
// The window scrolled pixels
var pos = $(this).scrollTop();
// Scroll direction
// true: user is scrolling down
// false: user is scrolling up
scrollDown = pos > lastPos;
// items loop
selectors.item.each(function (i) {
var this_item = $(this);
item_top = this_item.offset().top;
item_height = this_item.height();
item_bottom = item_height + this_item.offset().top;
// You can play with those triggers...
trigger_top = pos + (5 / 16) * winHeight;
trigger_bottom = pos + (3 / 16) * winHeight;
// Just for the console.log
var item_date = this_item.find(".timeline__content-title").text();
// The conditions
var scroll_down_condition =
scrollDown &&
pos < item_top &&
trigger_top >= item_top &&
trigger_top + 20 <= item_bottom;
var scroll_up_condition =
!scrollDown &&
pos < item_bottom &&
trigger_bottom >= item_top &&
trigger_bottom + 20 <= item_bottom;
// If one or the other condition is true
// Unblur the item and set the background
if (scroll_down_condition || scroll_up_condition) {
console.log(
`Date ${item_date} is in view - `,`Scrolling ${scrollDown ? "down" : "up"}`
);
// Set background
selectors.id.css(
"background-image","url(" + this_item.find(selectors.img).attr("src") + ")"
);
// Remove the active class (unblur) on all items
selectors.item.removeClass(selectors.activeClass);
// Unblur
this_item.addClass(selectors.activeClass);
}
}); // END item each
// For the scrolling direction
lastPos = pos;
});
};
})(jQuery);