81

Okay I'm using jQuery and currently getting max value of scrollbar doing this:

var $body = $('body');
$body.scrollLeft(99999); // will give me the max value since I've overshot
var max_value = $body.scrollLeft(); // returns 300
$('body').scrollLeft(0);

When I try this: $body[0].scrollWidth I just get the actual width of the contents - 1580

I'm thinking there has to be a better way I'm forgetting.

EDIT To clarify, I also tried $(window).width() and $(document).width() which gave me 1280 and 1580, respectively.

Dave Stein
  • 8,653
  • 13
  • 56
  • 104

8 Answers8

156

You can calculate the maximum value of element.scrollLeft with:

var maxScrollLeft = element.scrollWidth - element.clientWidth;

Note that there could be some browser specific quirks that I'm not aware of.

Angel Yordanov
  • 3,112
  • 1
  • 22
  • 19
  • I think for Firefox only there is a `scrollLeftMax` doing this. [See here](https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeftMax). – icl7126 Nov 02 '16 at 20:43
  • 6
    element here is HTML dom object, if you are using jQuery you can do `var maxScrollLeft = $('.classname').get(0).scrollWidth - $('.classname').get(0).clientWidth` – karmendra Nov 12 '17 at 09:50
  • 2
    I used this this to check whether a container is already scrolled to the very end by comparing it to `element.scrollLeft`. However, under some circumstances the values seem to be 1px off. – Philipp Mitterer Feb 22 '18 at 14:28
  • Note that in Firefox (tested with version 109), `scrollLeftMax` might be one pixel off compared to `scrollWidth - clientWidth` due to rounding. That is, `clientWidth` is rounded up if the viewport has subpixel resolution. – MyKey_ Jan 31 '23 at 08:31
11

First of all there is a native property that is implemented in mozilla and only mozilla scrollLeftMax (also scrollTopMax). look here: https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeftMax

Here a polyfill i wrote that will make that property available for IE8+, and all the other browsers. Just add it at the top of your js file or code.

Here the polyfill code go:

(function(elmProto){
    if ('scrollTopMax' in elmProto) {
        return;
    }
    Object.defineProperties(elmProto, {
        'scrollTopMax': {
            get: function scrollTopMax() {
              return this.scrollHeight - this.clientHeight;
            }
        },
        'scrollLeftMax': {
            get: function scrollLeftMax() {
              return this.scrollWidth - this.clientWidth;
            }
        }
    });
}
)(Element.prototype);

use example:

var el = document.getElementById('el1');
var max = el.scrollLeftMax; 

The support here depend on defineProperties() support. which is IE8+ (for IE8 the method is supported for only DOM elements which is the case for our polyfill use and methods).

Look here for the whole list of supported browsers: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#compatNote_1

mostly that will suffice.

If not you can add separate functions directly. and you get a support for IE6+ and all other browsers. (now it will depend on in operator support. which happen to be IE6+)

Here an example i choosed to add just an 'i' to the end for the name. scrollLeftMaxi() and scrollTopMaxi()

(function (elmProto) {
    elmProto.scrollTopMaxi = function () {
        return this.scrollTop - this.clientHeight;
    };
    elmProto.scrollLeftMaxi = function () {
        return this.scrollLeft - this.clientWidth;
    };
})(Element.prototype);

use example :

 var element = document.getElementById('el');
 var leftMax = element.scrollLeftMaxi();
 var topMax = element.scrollTopMaxi();
 console.log(leftMax);
 console.log(topMax);

The code above create the properties the Element prototype and assign the functions we defined. When called scrollLeftMaxi(). The prototype chain get traversed, until it Get to Element.prototype. Where it will find the property. Know that following the prototype chain. And how the properties are checked. If having two properties of same name at different place in the chain. Unexpected behavior is just to be expected. That's why a new name as scrollLeftMaxi is suited. (if i kept the same as the native mozilla one, the native one will not get override, and they are in two different place in the chain, and the native one take precedence. and the native is not of function type. An attribute that have a getter behind it, just like we did with the polyfill above, if i call it as a function. An error will trigger, saying it's not a function. and so without changing the name we will have this problem with mozilla. That was for an example).

Look here how getter works if you like : https://www.hongkiat.com/blog/getters-setters-javascript/

here is a fiddle test, it show that we get the same result as the native property in mozilla (make sure to test within mozilla)

(function(elmProto) {
  elmProto.scrollTopMaxi = function() {
    return this.scrollHeight - this.clientHeight;
  };
  elmProto.scrollLeftMaxi = function() {
    return this.scrollWidth - this.clientWidth;
  };
})(Element.prototype);



// here we will test

var container = document.getElementById('container');

// here a comparison between the native of mozilla and this one 

console.log("scrollLeftMaxi = " + container.scrollLeftMaxi());
console.log("scrollLeftMax = " + container.scrollLeftMax);
#container {
  height: 500px;
  width: 700px;
  overflow: auto;
  border: solid 1px blue;
}

#inner {
  height: 2000px;
  width: 1500px;
  background: #928ae6;
}
<!DOCTYPE html>
<html lang="en">

  <head>
    <meta charset="UTF-8">
    <title>Document</title>
  </head>

  <body>
    <div id="container">
      <div id="inner"></div>
    </div>

  </body>

</html>

What about using that with jquery:

var max = $('#element')[0].scrollLeftMax; // when using the polyfill
var max =  $('#element')[0].scrollLeftMaxi(); // when using the other alternative more support IE6+
Mohamed Allal
  • 17,920
  • 5
  • 94
  • 97
  • This gave me values between 0 - 0.24 instead of 0 - 1.00 – thinsoldier Jun 01 '18 at 11:28
  • 2
    Changed clientleft to clientWidth and now scrollLeftMax works in Chrome. – thinsoldier Jun 01 '18 at 11:30
  • Oh my bad! I don't know why i put in clientLeft. Same thing was for the first polyfill with clientHeight (not clientTop). But though it was correct in the jsFiddle snippet. (clientTop and left are borders height and width, where clientWidth is the the viewable width of an element ). I come to update the answer. Thank you a lot – Mohamed Allal Jun 01 '18 at 22:23
  • happy to be of help! And thank you! All best wishes! – Mohamed Allal Jul 08 '20 at 18:22
4

AFAIK you have to calculate the maximum scroll value yourself, it is the difference between the parent/container's width and the child/content width.

An example on how to do that with jQuery:

HTML:

<div id="container">
    <div id="content">
        Very long text or images or whatever you need
    </div>
</div>

CSS:

#container {
    overflow:   scroll;
    width:      200px;
}
#content {
    width:      400px;
}

JS:

var maxScroll = $("#content").width() - $("#container").width();
// maxScroll would be 200 in this example

In your case window is the parent/container and document the child/content.

Here is a JSFiddle with this example: http://jsfiddle.net/yP3wW/

Larzan
  • 9,389
  • 3
  • 42
  • 41
2

Simple solution is

var maxScrollLeft = $(document).width() - $(window).width();
namal
  • 1,164
  • 1
  • 10
  • 15
  • 1
    While this answer is probably correct and useful, it is preferred if you [include some explanation along with it](http://meta.stackexchange.com/q/114762/159034) to explain how it helps to solve the problem. This becomes especially useful in the future, if there is a change (possibly unrelated) that causes it to stop working and readers need to understand how it once worked. – Kevin Brown-Silva Nov 21 '15 at 22:00
1

Jquery (>1.9.1): The maximum value scrollLeft can be is:

$('#elemID').prop("scrollWidth") - $('#elemID').width();
jrbedard
  • 3,662
  • 5
  • 30
  • 34
0

You can use $(document).width() to get the full width of your document, and $(window).width() to get the width of the window/viewport.

http://api.jquery.com/width/

Tobias Cohen
  • 19,893
  • 7
  • 54
  • 51
-1

I think that you could use something like this:

this.children().width()*(this.children().length+1)-this.width()-10;

The previous line of code is going to get the width of one of the children and multiply this with by the number of chilren, finally you need to substract the width of the element minus an offteset

Luis Vargas
  • 2,466
  • 2
  • 15
  • 32
-2
var scrollContainer = $('.b-partners .b-partners__inner');
var maxScrollLeft = $(scrollContainer)[0].scrollWidth - $(scrollContainer).width();
console.log(maxScrollLeft);
Nic Wortel
  • 11,155
  • 6
  • 60
  • 79
Nehlatak
  • 1
  • 1