如何使用defineSetter在两个对象中正确设置scrollLeft? [英] How to properly set scrollLeft in two objects using defineSetter?
问题描述
在我的页面中,我有两个宽度相同的表格,它们都可以水平滚动.当每个表滚动时,我需要将两个表设置到相同的位置.
In my page I have two tables of same width, and them both do horizontal scroll. I need to set both tables to the same position when each one scrolls.
实际上,我的代码是:
var scrollA = $('#scrollA'),
scrollB = $('#scrollB');
scrollA.on('scroll', function() {
scrollB[0].scrollLeft = scrollA[0].scrollLeft;
});
它有效.问题是有些情况下加载的数据大到足以减慢浏览器和滚动事件的速度.
It works. The problem is that there are situations where the loaded data is big enough to slow the browser and the scroll event.
然后,我正在努力改善这些情况下的用户体验.
Then, I'm trying to improve the user experience in those situations.
我做了这个片段,我尝试使用 Object
的 __defineSetter__
函数:
I did this snippet where I try to use the __defineSetter__
function of Object
:
var elementA = { scrollLeft: 30 },
elementB = { scrollLeft: 30 };
elementA.__defineSetter__('scrollLeft', val => elementB.scrollLeft = val);
elementA.scrollLeft += 5;
console.log(elementA.scrollLeft + ' == ' + elementB.scrollLeft);
但是正如您在运行代码段所看到的那样,它将 undefined
设置为 elementA.scrollLeft
并将 NaN
设置为 elementB.scrollLeft代码>.
But as you can see running the snippet, it sets undefined
to elementA.scrollLeft
and NaN
to elementB.scrollLeft
.
我需要一些指导,谢谢您的时间.
I'd like some guidance here, thanks for your time.
推荐答案
Scroll 事件可以高速触发,因此您可以通过限制 scroll 事件处理程序来获得更平滑的滚动,正如 trincot 在他的回答中所说.您可以使用 setTimeout
来限制函数.但是,在屏幕上移动物体或处理其他可见效果时,我更喜欢 requestAnimationFrame
.
Scroll events can fire at a high rate, so you may get smoother scrolling by throttling the scroll event handler, as trincot said in his answer. You can throttle a function using setTimeout
. When moving things on the screen or dealing with other visible effects, though, I prefer requestAnimationFrame
.
requestAnimationFrame
在下一次重绘之前运行回调,因此浏览器可以做一些优化.
requestAnimationFrame
runs the callback before the next repaint, so the browser can do some optimizations.
此代码将使您更接近解决方案,它基于 这个来自 MDN 的例子:
This code will get you closer to the solution, it is based on this example from MDN:
var scrollA = $('#scrollA'),
scrollB = $('#scrollB'),
running = false;
scrollA.on('scroll', function() {
// if we already requested an animation frame, do nothing
if (!running) {
window.requestAnimationFrame(function() {
// synchronize table B and table A
scrollB[0].scrollLeft = scrollA[0].scrollLeft
// we're done here and can request a new frame
running = false;
});
}
running = true;
});
您可以使用传递给回调的时间戳来进一步消除同步,但如果延迟太多,您可能会在第二个表中滚动缓慢.
You can use the timestamp passed to the callback to further debounce the synchronization, but you may end with a kinda sluggish scroll in the second table if you put too much delay.
这篇关于如何使用defineSetter在两个对象中正确设置scrollLeft?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!