自动滚动(如电影演职员表),但用户只需滚动即可接管
autoscroll (like movie credits) but the user can takeover by simply scrolling
我正在考虑创建一个网站,作为音乐剧的数字传单。这个想法是有一个自动滚动的信用列表作为登陆页面。我查看了 codepen 上的示例,了解如何实现这种效果。但我也希望用户可以根据需要进行交互和滚动。当他们停止滚动时,演职员表将变回自动滚动。我没有找到任何解决这个问题的例子。你们中有人知道可以帮助我解决这个问题的脚本(JS 或普通 css…)吗?
最直接的方法是设置一个 requestAnimationFrame() 函数并相应地增加值,然后为其设置滚动位置。
然后添加 wheel 事件来检测用户何时滚动(尽管不要使用 'scroll' 事件,当您更改 body 的 scrollTop 值时它已经被调用),也不要忘记取消 requestAnimationFrame( ) 功能。代码看起来像这样:
let body = document.body,
starter = document.querySelector("h1"),
scroll_counter = 0,
scrolled,
auto_scroll_kicked = false;
starter.addEventListener("click", start_scrolling);
function start_scrolling() {
auto_scroll_kicked = true;
body.offsetHeight > scroll_counter
? (scroll_counter += 1.12)
: (scroll_counter = body.offsetHeight);
document.documentElement.scrollTop = scroll_counter;
scroller = window.requestAnimationFrame(start_scrolling);
if (scroll_counter >= body.offsetHeight) {
window.cancelAnimationFrame(scroller);
}
}
window.addEventListener("wheel", (e) => {
if (auto_scroll_kicked) {
window.cancelAnimationFrame(scroller);
scroll_counter = 0;
}
});
如果您愿意,可以使用 codepen:
https://codepen.io/SaltyMedStudent/pen/QWqVwaR?editors=0010
有许多选项可供使用:缓动函数等,但希望现在这些就足够了。
在更改位置之前的自动滚动例程中,检查之前的位置是否与当前滚动位置相同,如果不相同 - 用户滚动它:
let el = document.documentElement,
footer = document.getElementById("status").querySelectorAll("td"),
scroll_position = 0,
scroll_speed = 0,
scroll_delta = 1.12,
scroller,
status = "stopped";
el.addEventListener("click", scroll);
info();
function scroll(e)
{
if (e.type == "click")
{
window.cancelAnimationFrame(scroller);
scroll_position = el.scrollTop; //make sure we start from current position
scroll_speed++; //increase speed with each click
info("auto scroll");
}
//if previous position is different, this means user scrolled
if (scroll_position != el.scrollTop)
{
scroll_speed = 0;
info("stopped by user");
return;
}
el.scrollTop += scroll_delta * scroll_speed; //scroll to new position
scroll_position = el.scrollTop; //get the current position
//loop only if we didn't reach the bottom
if (el.scrollHeight - el.scrollTop - el.clientHeight > 0)
{
scroller = window.requestAnimationFrame(scroll); //loop
}
else
{
el.scrollTop = el.scrollHeight; //make sure it's all the way to the bottom
scroll_speed = 0;
info("auto stopped");
}
}
function info(s)
{
if (typeof s === "string")
status = s;
footer[1].textContent = el.scrollTop;
footer[3].textContent = scroll_speed;
footer[5].textContent = status;
}
//generate html demo sections
for(let i = 2, section = document.createElement("section"); i < 6; i++)
{
section = section.cloneNode(false);
section.textContent = "Section " + i;
document.body.appendChild(section);
}
//register scroll listener for displaying info
window.addEventListener("scroll", info);
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body
{
font-family: "Roboto", Arial;
user-select: none;
}
section
{
min-height: 100vh;
font-size: 3em;
font-weight: 500;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
section:nth-child(even)
{
background: #0b0d19;
}
section:nth-child(odd)
{
background: #131524;
}
#status
{
position: fixed;
bottom: 0;
color: #fff;
margin: 0.5em;
}
#status td:first-of-type
{
text-align: end;
padding-right: 0.4em;
}
#status td:last-of-type
{
font-weight: bold;
}
<section>
Click to start Scrolling
</section>
<table id="status">
<tr><td>position:</td><td></td></tr>
<tr><td>speed:</td><td></td></tr>
<tr><td>status:</td><td></td></tr>
</table>
我正在考虑创建一个网站,作为音乐剧的数字传单。这个想法是有一个自动滚动的信用列表作为登陆页面。我查看了 codepen 上的示例,了解如何实现这种效果。但我也希望用户可以根据需要进行交互和滚动。当他们停止滚动时,演职员表将变回自动滚动。我没有找到任何解决这个问题的例子。你们中有人知道可以帮助我解决这个问题的脚本(JS 或普通 css…)吗?
最直接的方法是设置一个 requestAnimationFrame() 函数并相应地增加值,然后为其设置滚动位置。 然后添加 wheel 事件来检测用户何时滚动(尽管不要使用 'scroll' 事件,当您更改 body 的 scrollTop 值时它已经被调用),也不要忘记取消 requestAnimationFrame( ) 功能。代码看起来像这样:
let body = document.body,
starter = document.querySelector("h1"),
scroll_counter = 0,
scrolled,
auto_scroll_kicked = false;
starter.addEventListener("click", start_scrolling);
function start_scrolling() {
auto_scroll_kicked = true;
body.offsetHeight > scroll_counter
? (scroll_counter += 1.12)
: (scroll_counter = body.offsetHeight);
document.documentElement.scrollTop = scroll_counter;
scroller = window.requestAnimationFrame(start_scrolling);
if (scroll_counter >= body.offsetHeight) {
window.cancelAnimationFrame(scroller);
}
}
window.addEventListener("wheel", (e) => {
if (auto_scroll_kicked) {
window.cancelAnimationFrame(scroller);
scroll_counter = 0;
}
});
如果您愿意,可以使用 codepen: https://codepen.io/SaltyMedStudent/pen/QWqVwaR?editors=0010
有许多选项可供使用:缓动函数等,但希望现在这些就足够了。
在更改位置之前的自动滚动例程中,检查之前的位置是否与当前滚动位置相同,如果不相同 - 用户滚动它:
let el = document.documentElement,
footer = document.getElementById("status").querySelectorAll("td"),
scroll_position = 0,
scroll_speed = 0,
scroll_delta = 1.12,
scroller,
status = "stopped";
el.addEventListener("click", scroll);
info();
function scroll(e)
{
if (e.type == "click")
{
window.cancelAnimationFrame(scroller);
scroll_position = el.scrollTop; //make sure we start from current position
scroll_speed++; //increase speed with each click
info("auto scroll");
}
//if previous position is different, this means user scrolled
if (scroll_position != el.scrollTop)
{
scroll_speed = 0;
info("stopped by user");
return;
}
el.scrollTop += scroll_delta * scroll_speed; //scroll to new position
scroll_position = el.scrollTop; //get the current position
//loop only if we didn't reach the bottom
if (el.scrollHeight - el.scrollTop - el.clientHeight > 0)
{
scroller = window.requestAnimationFrame(scroll); //loop
}
else
{
el.scrollTop = el.scrollHeight; //make sure it's all the way to the bottom
scroll_speed = 0;
info("auto stopped");
}
}
function info(s)
{
if (typeof s === "string")
status = s;
footer[1].textContent = el.scrollTop;
footer[3].textContent = scroll_speed;
footer[5].textContent = status;
}
//generate html demo sections
for(let i = 2, section = document.createElement("section"); i < 6; i++)
{
section = section.cloneNode(false);
section.textContent = "Section " + i;
document.body.appendChild(section);
}
//register scroll listener for displaying info
window.addEventListener("scroll", info);
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body
{
font-family: "Roboto", Arial;
user-select: none;
}
section
{
min-height: 100vh;
font-size: 3em;
font-weight: 500;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
}
section:nth-child(even)
{
background: #0b0d19;
}
section:nth-child(odd)
{
background: #131524;
}
#status
{
position: fixed;
bottom: 0;
color: #fff;
margin: 0.5em;
}
#status td:first-of-type
{
text-align: end;
padding-right: 0.4em;
}
#status td:last-of-type
{
font-weight: bold;
}
<section>
Click to start Scrolling
</section>
<table id="status">
<tr><td>position:</td><td></td></tr>
<tr><td>speed:</td><td></td></tr>
<tr><td>status:</td><td></td></tr>
</table>