向单一方向滚动:水平或垂直

时间:2013-12-02 15:09:10

标签: javascript jquery css html-table

我正在寻找一种方法,只在html表视图中滚动水平或垂直,同时保持始终可见的标题和行。我希望有类似于this的东西,但是在没有ember或coffeescript的纯Javascript中。我不喜欢使用ember-table,因为我的项目的其余部分不是基于ember而我不熟悉它。

所以我开始使用类似的here。它具有标题行和列的优点,但它在水平方向和垂直方向上滚动。此示例与第一个示例之间的区别在于,addepar表仅向一个方向滚动。这是一种更平静的用户体验。

我一直在寻找可能的方法来到达我想要的地方。第一部分似乎是检查用户滚动的方向。这样的事情可以用jQuery完成;

var previousScrollvertical = 0,
    previousScrollHorizontal = 0;

$(window).scroll(function(){

   var currentVerticalScroll = $(this).scrollTop(),
       currentHorizontalScroll = $(this).scrollLeft();

   if(currentVerticalScroll==previousScrollvertical) {
           if (currentHorizontalScroll > previousScrollHorizontal){
               console.log('Right');
           } else {
              console.log('left');
           }
   } else if(currentHorizontalScroll==previousScrollHorizontal) {
           if (currentVerticalScroll > previousScrollvertical){
               console.log('down');
           } else {
              console.log('up');
           }
   }

   previousScrollHorizontal = currentHorizontalScroll;
   previousScrollvertical =currentVerticalScroll;
});

这段代码可以在任何加载了jQuery的网站上运行。你可以从控制台试试。

但是从这里我似乎陷入困境。是否可以使用jQuery阻止滚动方向?有没有更简单的方法来实现这一目标?我应该考虑完全不同的路线吗?

1 个答案:

答案 0 :(得分:1)

简短的回答是使用jQuery的scrollTopscrollLeft来设置您想要阻止回到之前的方向的滚动。

我创建了一个快速示例,展示了在实践中如何做到这一点:

Live Demo

var $container = $('.table-container');
var $table = $container.find('table');

var previousScroll = [0, 0];
var correction = false;

// Adjust the threshold to a larger number if you'd like it
// to take longer to switch between horizontal and vertical
// scrolling
var threshold = 10;
var direction;
var directionTimeout;

$container.on('scroll', function (event) {
    if (!correction) {
        var element = event.currentTarget,
            $element = $(event.currentTarget),
            x = element.scrollLeft,
            y = element.scrollTop;

        var diff = [
            Math.abs(x - previousScroll[0]),
            Math.abs(y - previousScroll[1])
        ];

        correction = true;

        if (!direction) {
            if (diff[0] > diff[1]) {
                direction = 'horizontal';
            } else if (diff[0] < diff[1]) {
                direction = 'vertical';
            } else {
                direction = 'vertical';
            }
        }

        if (direction === 'horizontal') {
            $element.scrollTop(previousScroll[1]);
            previousScroll = [x, previousScroll[1]];
        } else {
            $element.scrollLeft(previousScroll[0]);
            previousScroll = [previousScroll[0], y];
        }

        clearTimeout(directionTimeout);
        directionTimeout = setTimeout(function () {
            direction = null;
        }, threshold);
    } else {
        correction = false;
    }
});