使用 requestAnimationFrame 添加限制?
Adding throttling using requestAnimationFrame?
在下面的代码中,我根据 div
(shadeFinder) 在 x 轴上滚动的距离成功地更改了左右箭头的 color
。我想在此代码中添加节流。有人可以解释如何吗?我有下面 w3Schools 的示例,但发现很难将其合并到我的代码中。
//change the color of mobile arrows based on where the shadefinder is on X-axis
function changeArrowColor(){
var shadeFinder = document.querySelector('.fms-wrapper');
let leftArrow = document.querySelector('.prev');
let rightArrow = document.querySelector('.next');
let last_known_scroll_position = 0;
let ticking = false;
function doSomething(scroll_pos) {
scroll_pos = parseInt(scroll_pos/10);
leftArrow.style.color = `rgb(${scroll_pos},${scroll_pos},${scroll_pos})`;
rightArrow.style.color = `rgb(${scroll_pos},${scroll_pos},${scroll_pos})`;
}
shadeFinder.addEventListener('scroll', function(e) {
last_known_scroll_position = shadeFinder.scrollLeft;
doSomething(last_known_scroll_position);
});
}
带节流的 Mozilla 滚动事件示例:
// Reference: http://www.html5rocks.com/en/tutorials/speed/animations/
let last_known_scroll_position = 0;
let ticking = false;
function doSomething(scroll_pos) {
// Do something with the scroll position
}
window.addEventListener('scroll', function(e) {
last_known_scroll_position = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(function() {
doSomething(last_known_scroll_position);
ticking = false;
});
ticking = true;
}
});
requestAnimationFrame
API takes a callback function that returns a timestamp(此处我将使用 RAF 作为 shorthand)。如果想用JS做动画,后面可以用时间戳调用cancelAnimationFrame
。但如果仅用于节流,您暂时不需要存储此值。
因为您已经有一个名为 last_known_scroll_position
的变量,其范围在 doSomething
内使用,您不必将 scrollLeft
值传递给 RAF 函数,而是传递doSomething
作为滚动事件发生时将 last_known_scroll_position
设置为当前 scrollLeft
值后的回调。
该回调将接收一个 timestamp
参数,但您不需要它。回调可以根据 last_known_scroll_position
.
的计算更新颜色
参见下面的示例。
function changeArrowColor(){
var shadeFinder = document.querySelector('.fms-wrapper');
let leftArrow = document.querySelector('.prev');
let rightArrow = document.querySelector('.next');
let last_known_scroll_position = 0;
function doSomething(timestamp) {
let scroll_pos = parseInt(last_known_scroll_position/10);
let color = `rgb(${scroll_pos},${scroll_pos},${scroll_pos})`;
console.clear()
console.log({timestamp, color, last_known_scroll_position});
leftArrow.style.color = color;
rightArrow.style.color = color;
}
shadeFinder.addEventListener('scroll', function(e) {
last_known_scroll_position = shadeFinder.scrollLeft;
requestAnimationFrame(doSomething);
});
}
document.addEventListener("DOMContentLoaded", changeArrowColor);
body {
padding:0;
margin:20px 0;
}
.fms-wrapper {
height: 80px;
width: 100%;
max-width: 100vw;
overflow-y: hidden;
overflow-x: scroll;
position: relative;
padding: 0 30px;
margin: 0 5px;
box-sizing: border-box;
z-index:0;
margin: 0;
}
.prev, .next {
position: fixed;
z-index: 5;
width: 30px;
height: 50px;
font-size: 28px;
line-height: 50px;
box-sizing: border-box;
cursor:pointer;
color: black;
background: white;
box-shadow: 0 0 5px rgba(0,0,0,.5);
text-align: center;
pointer-events: auto;
}
.prev {
left: 5px;
}
.next {
right: 5px;
}
.fms-content {
width: 400%;
height: 50px;
background: linear-gradient(90deg, #f0f0f0 0%, #f0f0f0 25%, #919191 25%, #919191 50%, #f0f0f0 50%, #f0f0f0 75%, #919191 75%, #919191 100%);
box-sizing: border-box;
margin: 0;
padding: 0;
}
<div class="fms-wrapper">
<div class="prev" tabindex="0"><</div>
<div class="next" tabindex="0">></div>
<div class="fms-content"></div>
</div>
在下面的代码中,我根据 div
(shadeFinder) 在 x 轴上滚动的距离成功地更改了左右箭头的 color
。我想在此代码中添加节流。有人可以解释如何吗?我有下面 w3Schools 的示例,但发现很难将其合并到我的代码中。
//change the color of mobile arrows based on where the shadefinder is on X-axis
function changeArrowColor(){
var shadeFinder = document.querySelector('.fms-wrapper');
let leftArrow = document.querySelector('.prev');
let rightArrow = document.querySelector('.next');
let last_known_scroll_position = 0;
let ticking = false;
function doSomething(scroll_pos) {
scroll_pos = parseInt(scroll_pos/10);
leftArrow.style.color = `rgb(${scroll_pos},${scroll_pos},${scroll_pos})`;
rightArrow.style.color = `rgb(${scroll_pos},${scroll_pos},${scroll_pos})`;
}
shadeFinder.addEventListener('scroll', function(e) {
last_known_scroll_position = shadeFinder.scrollLeft;
doSomething(last_known_scroll_position);
});
}
带节流的 Mozilla 滚动事件示例:
// Reference: http://www.html5rocks.com/en/tutorials/speed/animations/
let last_known_scroll_position = 0;
let ticking = false;
function doSomething(scroll_pos) {
// Do something with the scroll position
}
window.addEventListener('scroll', function(e) {
last_known_scroll_position = window.scrollY;
if (!ticking) {
window.requestAnimationFrame(function() {
doSomething(last_known_scroll_position);
ticking = false;
});
ticking = true;
}
});
requestAnimationFrame
API takes a callback function that returns a timestamp(此处我将使用 RAF 作为 shorthand)。如果想用JS做动画,后面可以用时间戳调用cancelAnimationFrame
。但如果仅用于节流,您暂时不需要存储此值。
因为您已经有一个名为 last_known_scroll_position
的变量,其范围在 doSomething
内使用,您不必将 scrollLeft
值传递给 RAF 函数,而是传递doSomething
作为滚动事件发生时将 last_known_scroll_position
设置为当前 scrollLeft
值后的回调。
该回调将接收一个 timestamp
参数,但您不需要它。回调可以根据 last_known_scroll_position
.
参见下面的示例。
function changeArrowColor(){
var shadeFinder = document.querySelector('.fms-wrapper');
let leftArrow = document.querySelector('.prev');
let rightArrow = document.querySelector('.next');
let last_known_scroll_position = 0;
function doSomething(timestamp) {
let scroll_pos = parseInt(last_known_scroll_position/10);
let color = `rgb(${scroll_pos},${scroll_pos},${scroll_pos})`;
console.clear()
console.log({timestamp, color, last_known_scroll_position});
leftArrow.style.color = color;
rightArrow.style.color = color;
}
shadeFinder.addEventListener('scroll', function(e) {
last_known_scroll_position = shadeFinder.scrollLeft;
requestAnimationFrame(doSomething);
});
}
document.addEventListener("DOMContentLoaded", changeArrowColor);
body {
padding:0;
margin:20px 0;
}
.fms-wrapper {
height: 80px;
width: 100%;
max-width: 100vw;
overflow-y: hidden;
overflow-x: scroll;
position: relative;
padding: 0 30px;
margin: 0 5px;
box-sizing: border-box;
z-index:0;
margin: 0;
}
.prev, .next {
position: fixed;
z-index: 5;
width: 30px;
height: 50px;
font-size: 28px;
line-height: 50px;
box-sizing: border-box;
cursor:pointer;
color: black;
background: white;
box-shadow: 0 0 5px rgba(0,0,0,.5);
text-align: center;
pointer-events: auto;
}
.prev {
left: 5px;
}
.next {
right: 5px;
}
.fms-content {
width: 400%;
height: 50px;
background: linear-gradient(90deg, #f0f0f0 0%, #f0f0f0 25%, #919191 25%, #919191 50%, #f0f0f0 50%, #f0f0f0 75%, #919191 75%, #919191 100%);
box-sizing: border-box;
margin: 0;
padding: 0;
}
<div class="fms-wrapper">
<div class="prev" tabindex="0"><</div>
<div class="next" tabindex="0">></div>
<div class="fms-content"></div>
</div>