如何使用defineSetter在两个对象中正确设置scrollLeft? [英] How to properly set scrollLeft in two objects using defineSetter?

查看:32
本文介绍了如何使用defineSetter在两个对象中正确设置scrollLeft?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的页面中,我有两个宽度相同的表格,它们都可以水平滚动.当每个表滚动时,我需要将两个表设置到相同的位置.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆