最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Smooth horizontal scroll bound to mousewheel - Stack Overflow

programmeradmin2浏览0评论

Here is a working example of horizontal scroll with mousewheel, but it does not scroll smoothly. By smoothly I mean like ordinary vertical scroll in Firefox or Opera.

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

()

I've made a live demo to demonstrate this. /

I want this scroll to work like the vertical one, both with mousewheel and smoothness.

Can someone help me?

Here is a working example of horizontal scroll with mousewheel, but it does not scroll smoothly. By smoothly I mean like ordinary vertical scroll in Firefox or Opera.

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

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

I've made a live demo to demonstrate this. http://jsfiddle.net/Dw4Aj/

I want this scroll to work like the vertical one, both with mousewheel and smoothness.

Can someone help me?

Share Improve this question edited Mar 16, 2019 at 13:07 Douglas Reid 3,7885 gold badges33 silver badges49 bronze badges asked Oct 21, 2012 at 17:08 Vladimir WoodVladimir Wood 1011 gold badge1 silver badge9 bronze badges 3
  • create a live demo that replicates issue in jsfiddle.net – charlietfl Commented Oct 21, 2012 at 18:05
  • here is it! link – Vladimir Wood Commented Oct 22, 2012 at 4:32
  • Possibly unrelated, I logged the delta variable scrolling on a MacBook trackpad (no mouse), and it proved pretty unreliable. Conduct your own tests and determine if that might be the weak link of this approach. – Jan Commented Oct 22, 2012 at 7:26
Add a comment  | 

8 Answers 8

Reset to default 3

Smooth scrolling is a browser specific feature.

If you want something that works on all of them then you need to do it on your side. There are multiple implementations of smooth scrolling for jQuery.

And actually you may even need so called kinetic scrolling. If so try jquery.kinetic

1st i think about it is to remember last scroll event timestamp, play with easing function, to get good result 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();
    });
});​

Try to use your function in conjunction with .animate()

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

I just actually did this myself and it works. I created an instagram feed on the web application that I created, and the other plugins that I was using were breaking all too often:

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

I found other nice solution - to use wrapper, so you scroll absolute to same position as you would to scroll vertical, it works if you just need scroll, no text selection or other(may be can work arounded, but i tired)

$(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/

i made another sample, now without wholescreen wrapper, and possibility to select http://jsfiddle.net/oceog/DcyWD/

I'm just going to leave this here.

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();
});

});

Just change this:

this.scrollLeft -= (delta * 30);

to this:

this.scrollLeft -= (delta * 1);

You could try to utilize the browser built in scroll behavior, by using simply scrollBy:

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

})

It is a bit sloppy when you scroll more before the browser finished the smooth scroll (as smooth scrolling takes some time to finish the "animation"), but for some scenarios it does the job.

You can also achieve the same essentially by settings the css property scroll-behavior: smooth, and then explicitly setting target.scrollLeft = ... on the element. Both approaches essentially use the bult-in scroll implementation of the browsers (except Safari and IE10 maybe, as those don't support this smooth behavior at all to date)

I fixed the stuck when re-scrolling to the end of the previous scroll.

pure 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();
})
发布评论

评论列表(0)

  1. 暂无评论