user7978965
user7978965

Reputation:

Horizontal scroll on mousewheel

Is where a way to scroll div horizontally by mousewheel, without holding shift?

I know method with mousewheel plugin:

$("#test").mousewheel(function(event, delta) {
   var current = $(this).scrollLeft();
   $(this).scrollLeft(current - (delta * 80));
});

I tried to scroll it with $(this).animate... but it still looks ugly.

I don't need to simulate browser built-in smoothness while scroll because it's not cross-browser way, I need to scroll it naturally.

Maybe simulate shift holding on mouseenter event?

Upvotes: 2

Views: 3668

Answers (3)

Jan Zabłocki
Jan Zabłocki

Reputation: 49

so okay i was struggling with implementing that feature recently and i found out that as long as mousewheel event seems to be no longer supported, probably the best solution working with current browsers is this:

    $(window).on('wheel', function(e){
    if ($.browser.mozilla) {
        e.preventDefault();
        var delta = -500*(parseInt(e.originalEvent.deltaY)/33);
        var scto = $(this).scrollLeft() - delta;
        $(this).scrollLeft(scto);}
    else{
        e.preventDefault();
        var delta = -50*(parseInt(e.originalEvent.deltaY)/33);
        var scto = $(this).scrollLeft() - delta;
        $(this).scrollLeft(scto);}
});`

Upvotes: 2

messinismarios
messinismarios

Reputation: 190

I know it's a bit late, but I was looking for an answer to this myself and, playing around with Louys' code I found something that seemed to work a bit better.

$("#test").on("mousewheel", function(e) {
  e.preventDefault();
  var delta = 40*(parseInt(e.originalEvent.deltaY)/33);
  var scto = $(this).scrollLeft() - delta;
  $(this).scrollLeft(scto);
});

It basically does not need a variable to keep track of the scroll_to position since it's getting the value from scrollLeft() and just subtracting the delta, essentially solving both problems that occur with the previous version, one being that the function now does not scroll past the total width of the element and doesn't go negative, and second being that if you now change the scroll position using the scrollbar, it doesn't mess up the code like it would before.

(I also removed ScrollX_pixelPer as I don't think you need a whole variable for a simple number)

Upvotes: 1

Louys Patrice Bessette
Louys Patrice Bessette

Reputation: 33933

The trick is to retreive the .deltaY form the .originalEvent... Then use jQuery .scrollLeft().

Since the delta always is 33.33333206176758 or -33.33333206176758... You can parseInt() and divide by 33. You'll then always get 1 or -1, which you can multiply by the amount of pixel you wish to be scrolled, on the X axis, per wheel spin.

// Variable to store current X scrolled position.
var current = 0;
// Pixel increment you wish on each wheel spin.
var ScrollX_pixelPer = 40;

// Event handler.
$("#test").on("mousewheel", function(e) {
  e.preventDefault();
  
  // Get the deltaY (always +/- 33.33333206176758) and multiply by the pixel increment you wish.
  var delta = ScrollX_pixelPer*(parseInt(e.originalEvent.deltaY)/33);
  
  // Increment/decrement current.
  current += delta;
  //console.log(current);
  
  // Apply the new position.
  $(this).scrollLeft(current);
  
});
#test{
  height:2.5em;
  overflow-y:scroll;
  white-space:nowrap;
}
.spacer{
  height:400px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class="spacer"></div>

<div id="test">
  Lorem ipsum dolor sit amet, no mel volutpat consequat. Doctus sanctus nec no, mea ei augue appellantur. Pro doming vocibus accusam at, eum ut alii debet temporibus. No qui suas utinam splendide, essent fastidii invidunt est et, cum an brute explicari neglegentur. Nihil putant invenire ea vix. Quis congue epicuri sed cu, ad errem nusquam mel. Commune fabellas rationibus te mea, vim ne justo illum sensibus.
</div>

<div class="spacer"></div>

Upvotes: 3

Related Questions