javascript - 如何在滚动时显示时间线的背景
问题描述
我有一些特定时间轴的代码,问题是:滚动时时间轴中的背景项目没有在正确的时间显示(顶部和底部)
当相关项目垂直居中时,我需要显示背景,例如,在最后一个和倒数第二个背景中有一个显示偏移量。
请看一下 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, 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>
</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, 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="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, 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>
</div>
</div>
</div>
</div>
</div>
</div>
解决方案
这是数学和用户体验设计问题的混合。(正是我喜欢的那种问题!)
首先,你要考虑的是用户是向上还是向下滚动。那是关键。
根据滚动方向,您将检查item
.
例如,如果您只比较项目的顶部,则用户必须向上滚动整个项目,直到顶部穿过中间,然后它才会变得模糊。那是不行的。
所以这真的是关于用户体验方面:当用户向下滚动时(所以内容向上移动),他需要在“某个点”显示下一个项目。因为他可能还在看图片下方的文字,所以我觉得那个“点”在视口中间有点高……但不要太高。
当用户向上滚动时(因此内容向下移动),他当然希望在视口中间之前让来自上方的内容不模糊。
所以...您需要考虑两个不同的视口位置。此后我将这些点称为“触发点”。
- 略高于中间(向下滚动)
- 略低于顶部(向上滚动)
============
这变得越来越复杂......
两个滚动方向和两个视口位置与项目的顶部或底部进行比较。
所以我做了两个变量来保存基于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);
推荐阅读
- google-sheets-query - 如何在查询中使用单元格值?
- windows-server-2012 - 无法使 Windows 服务在 Windows Server 2012 上正确调用子进程
- java - 当我尝试更改指定数组索引中的对象时,它会使用该对象更改整个数组。有什么理由吗?
- windows - 来自远程 Perforce 存储库的 git-p4 克隆给了我空文件夹
- shell - 如果我们知道列需要放置在文件中的位置,如何使用默认值填充文件?
- android - 如何在谷歌地图中绘制多个地理点之间的路线(注意:这是公交车站路线)?
- ssis - 在数据转换任务期间我必须为 DB2 Varchar1000 列使用什么数据类型到 Excel
- c# - c#- 将DataTable转换为List,并将特定列计数为Linq形式
- laravel - Laravel 会话终身问题
- python - 我如何解决:字典和列表工作