【问题标题】:Smooth horizontal scroll bound to mousewheel平滑的水平滚动绑定到鼠标滚轮
【发布时间】:2012-10-21 17:08:19
【问题描述】:

这是一个使用鼠标滚轮进行水平滚动的工作示例,但滚动不顺畅。平滑是指 Firefox 或 Opera 中的普通垂直滚动。

$(function() {
    $("html, body").mousewheel(function(event, delta) {
        this.scrollLeft -= (delta * 30);
        event.preventDefault();
    });
});

(http://brandonaaron.net/code/mousewheel/docs)

我制作了一个现场演示来演示这一点。 http://jsfiddle.net/Dw4Aj/

我希望这个滚动条像垂直滚动条一样工作,同时具有鼠标滚轮和平滑度。

有人可以帮我吗?

【问题讨论】:

  • 创建一个在 jsfiddle.net 中复制问题的现场演示
  • 就在这里! link
  • 可能不相关,我在 MacBook 触控板上(没有鼠标)记录了 delta 变量滚动,但事实证明它非常不可靠。进行自己的测试并确定这是否可能是这种方法的薄弱环节。

标签: javascript jquery scroll mousewheel


【解决方案1】:

平滑滚动是浏览器特有的功能。

如果您想要对所有人都有效的东西,那么您需要站在自己这边。 jQuery 有多种平滑滚动的实现。

实际上,您甚至可能需要所谓的动态滚动。如果是这样试试jquery.kinetic

【讨论】:

  • 谢谢,但这不是我想要的,即使不是关闭。我只希望水平滚动像 Firefox 或 Opera 中的原始垂直滚动一样工作。
  • 由于您是以编程方式进行的,它很可能不会像原生控件那样工作。
  • @Vladimir Mikhalev 正如我所说,平滑滚动是浏览器特有的功能。例如,谷歌浏览器根本不使用平滑滚动。因此,如果您想在那里和所有其他地方以相同的方式看到平滑滚动,您必须手动实现它或为此使用一些现有的库。
【解决方案2】:

第一个我认为是记住最后滚动事件的时间戳,玩缓动功能,以获得良好的结果http://jsfiddle.net/oceog/Dw4Aj/13/

$(function() {

    $("html, body").mousewheel(function(event, delta) {
        var mult = 1;
        var $this = $(this);
        if (event.timeStamp - $this.data('oldtimeStamp') < 1000) {
            //calculate easing here
            mult = 1000 / (event.timeStamp - $this.data('oldtimeStamp'));
        }
        $this.data('oldtimeStamp', event.timeStamp);
        this.scrollLeft -= (delta) * mult;
        event.preventDefault();
    });
});​

【讨论】:

  • 您是否曾在 chrome 中测试过您的演示?不适合我。
  • 无。我唯一能确定的是 scrollLeft 有时没有设置。
  • 它工作正常,但非常有问题。我认为正确的答案是使用 .animate 使其正常工作。
  • 嗯,我用FF和chrome检查过,对我来说效果很好,但可能是因为我的鼠标,
  • 我不建议使用 animation() 你会遇到一些新问题(动画停止/开始,如何在动画过程中处理新事件,如何滚动最小可能的增量)
【解决方案3】:

尝试将您的函数与 .animate() 结合使用

$(function() {
    $("html, body").mousewheel(function(event, delta) {
        var scroll_distance = delta * 30
        this.animate(function(){
           left: "-=" + scroll_distance + "px",
        });
        event.preventDefault();
    });
});

我实际上只是自己做了这个并且它有效。我在自己创建的 Web 应用程序上创建了一个 instagram 提要,而我使用的其他插件经常被破坏:

$('#add_instagram').on('mousewheel', function(e,d){
    var delta = d*10;
    $('#move_this').animate({
        top: "-=" + delta + "px"
    },3);
    e.preventDefault();
});

【讨论】:

  • 不起作用,此处显示“语法错误”:left: -= (delta * 30);
  • 尝试将其放在引号中:“-=(delta*30)px”
  • 不能双向工作,现在它说“动画不是函数”
  • 好吧...做 $(this) 而不是“this”
  • 伤心,但我什么都没有。这是您注入的脚本jsfiddle.net/Dw4Aj/17
【解决方案4】:

我找到了其他不错的解决方案-使用包装器,因此您可以将绝对滚动到与垂直滚动相同的位置,如果您只需要滚动,没有文本选择或其他(可能可以解决,但我累了) )

$(function() {

    var scroll = $('.scrollme');
    var h = scroll.parent().height();
    var w = scroll.parent().width();
    var t = scroll.offset().top;
    var l = scroll.offset().left;
    var vertscroll_wrap = $("<div>").height(h).width(10000).css('position', 'absolute').css('top', t).css('left', l).css('z-index', 10000).css('opacity', 0.5).css('overflow-y', 'scroll');
    var vertscroll = $('<div>').height(10000).css('width', '100%').css('opacity', 0.5);
    vertscroll_wrap.append(vertscroll);
    $('body').append(vertscroll_wrap);
    vertscroll_wrap.height('100%');
    vertscroll_wrap.scroll(function() {
        $(scroll).parent().scrollLeft($(this).scrollTop());
    });


});​

http://jsfiddle.net/oceog/Dw4Aj/16/

我制作了另一个示例,现在没有全屏包装,并且可以选择 http://jsfiddle.net/oceog/DcyWD/

【讨论】:

    【解决方案5】:

    我只想把它留在这里。

    http://jsfiddle.net/Dw4Aj/19/

    jQuery(document).ready(function($) {
    $("html, body").mousewheel(function(e, delta) { 
        $('html, body').stop().animate({scrollLeft: '-='+(150*delta)+'px' }, 200, 'easeOutQuint');
        e.preventDefault();
    });
    
    });
    

    【讨论】:

    • 这在 Chrome 46 上不起作用。做了一些小改动,但这是一个运行良好的更新版本。 jsfiddle.net/Dw4Aj/338
    【解决方案6】:

    只要改变这个:

    this.scrollLeft -= (delta * 30);
    

    到这里:

    this.scrollLeft -= (delta * 1);
    

    【讨论】:

      【解决方案7】:

      您可以尝试使用浏览器内置的滚动行为,只需使用 scrollBy:

      const target = document.getElementsByClassName('whatever')[0];
      target.addEventListener('wheel', event => {
          event.preventDefault();
          target.scrollBy({
          left: event.deltaY*0.5,    
          behavior: 'smooth'
      });
      

      })

      在浏览器完成平滑滚动之前滚动更多内容有点草率(因为平滑滚动需要一些时间才能完成“动画”),但在某些情况下它可以完成这项工作。

      你也可以通过设置css属性scroll-behavior: smooth,然后在元素上显式设置target.scrollLeft = ...来实现同样的效果。 这两种方法本质上都使用了浏览器的内置滚动实现(可能除了 Safari 和 IE10,因为它们迄今为止根本不支持这种流畅的行为)

      【讨论】:

        【解决方案8】:

        我修复了重新滚动到上一个滚动结尾时卡住的问题。

        纯js。

        const el = document.getElementsByClassName('whatever')[0];
        let sumDelta = 0
        let startLeft = 0
        let targetLeft = 0
        el.addEventListener('wheel', (e) => {
            if (el.scrollLeft === targetLeft) sumDelta = 0
            if (sumDelta === 0) startLeft = el.scrollLeft
            sumDelta -= e.deltaY
            const maxScrollLeft = el.scrollWidth - el.clientWidth;
            const left = Math.min(maxScrollLeft, Math.max(0, startLeft - sumDelta));
            targetLeft = left
            el.scrollTo({left, behavior: "smooth"})
            e.preventDefault();
        })
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-07-20
          • 2011-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多