如何获取scrollLeft的最大值?

84

好的,我正在使用jQuery,目前通过以下方式获取滚动条的最大值:

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);
当我尝试这样做:$body[0].scrollWidth 我只得到了内容的实际宽度 - 1580。
我想肯定有更好的方法,只是我现在没想起来。
编辑: 为了澄清,我还尝试了 $(window).width()$(document).width(),它们分别给出了1280和1580。

遗憾的是,只有 Firefox 支持 scrollLeftMax 属性... - vsync
$(this).css("width") 将返回宽度,我认为这将是最大滚动宽度。 - Arjun
8个回答

159

您可以使用以下代码计算element.scrollLeft的最大值:

var maxScrollLeft = element.scrollWidth - element.clientWidth;

请注意,可能存在我不知道的特定于浏览器的问题。


我认为只有 Firefox 才有一个名为 scrollLeftMax 的功能可以实现这个。请参见此处 - icl7126
6
这里的元素是HTML DOM对象,如果你正在使用jQuery,你可以这样做: var maxScrollLeft = $('.classname').get(0).scrollWidth - $('.classname').get(0).clientWidth - karmendra
2
我使用这个方法来检查容器是否已经滚动到底部,通过将其与element.scrollLeft进行比较。然而,在某些情况下,这些值似乎会偏离1像素。 - Philipp Mitterer
请注意,在Firefox浏览器中(已测试版本109),由于四舍五入的原因,scrollLeftMax可能会比scrollWidth - clientWidth少一个像素。也就是说,如果视口具有亚像素分辨率,则clientWidth会向上取整。 - MyKey_

11

首先,有一个本地属性仅在 Mozilla 中实现 scrollLeftMax(还有 scrollTopMax),请参见:https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollLeftMax

这里是我编写的一个polyfill,可以使该属性在IE8+和其他所有浏览器中可用。只需将其添加到您的js文件或代码的顶部。

以下是 polyfill 代码:

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

使用示例:

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

这里的支持取决于 defineProperties() 的支持。该方法在IE8+中受支持(对于IE8,该方法仅支持DOM元素,在我们的polyfill使用和方法的情况下也是如此)。

查看完整支持浏览器列表:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty#compatNote_1

大多数情况下,这就足够了。

如果不行,您可以直接添加单独的函数。这样您就可以获得IE6+和所有其他浏览器的支持。 (现在它将依赖于in运算符支持,IE6+恰好支持)

这里有一个示例,我选择只向名称末尾添加“i”。scrollLeftMaxi()scrollTopMaxi()

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

使用示例:

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

以上代码创建了元素原型的属性,并分配我们定义的函数。当调用scrollLeftMaxi()时,原型链被遍历,直到它到达Element.prototype,在那里它会找到该属性。要知道以下原型链以及如何检查属性。如果在链中的不同位置具有相同名称的两个属性,则可以预期出现意外行为。这就是为什么新名称scrollLeftMaxi很合适的原因。 (如果我使用与原生Mozilla相同的名称,那么原生的将不会被覆盖,它们位于链中的两个不同位置,并且原生的优先级更高。原生的类型不是函数类型。像上面的填充一样,具有getter的属性,如果我将其作为函数调用,将触发错误,说明它不是函数。因此,在不更改名称的情况下,我们将在Mozilla上遇到此问题。这是一个示例)。

如果您想了解getter的工作方式,请单击此处

这是一个fiddle测试,它展示了我们在Mozilla中获得与原生属性相同的结果(请确保在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>

那么如何将它与jquery一起使用:

var max = $('#element')[0].scrollLeftMax; // when using the polyfill
var max =  $('#element')[0].scrollLeftMaxi(); // when using the other alternative more support IE6+

这给了我 0-0.24 之间的值,而不是 0-1.00。 - thinsoldier
2
将clientleft更改为clientWidth,现在scrollLeftMax在Chrome中有效。 - thinsoldier
哦,我的错!我不知道为什么会放进去clientLeft。同样的事情也发生在第一个polyfill中,当时是clientHeight而非clientTop。但在jsFiddle片段中是正确的。(clientTop和left是边框的高度和宽度,而clientWidth是元素可见的宽度)。我来更新答案。非常感谢。 - Mohamed Allal
很高兴能够提供帮助!谢谢您!祝一切顺利! - Mohamed Allal

4
据我所知,您需要自己计算最大滚动值,即父容器/容器的宽度与子内容的宽度之间的差异。

以下是使用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

在您的情况下,window是父/容器,document是子/内容。

这里有一个JSFiddle示例:http://jsfiddle.net/yP3wW/


2
简单的解决方案是:
var maxScrollLeft = $(document).width() - $(window).width();

1
虽然这个答案可能是正确和有用的,但最好还是要附上一些解释来解释它是如何帮助解决问题的。如果未来出现了变化(可能与此无关),导致它停止工作,读者需要理解它以前是如何运行的,这时这些解释将特别有用。 - Kevin Brown-Silva

1
Jquery (>1.9.1):最大的scrollLeft值可以是:
$('#elemID').prop("scrollWidth") - $('#elemID').width();

0

你可以使用$(document).width()来获取文档的全宽度,使用$(window).width()来获取窗口/视口的宽度。

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


-1

我认为你可以使用类似这样的东西:

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

前一行代码将获取其中一个子元素的宽度并乘以子元素数量,最后需要减去元素宽度和偏移量


this 将是一个 DOM 对象,而不是 jQuery 对象。因此,this.children() 会抛出一个错误。 - War10ck
$(this) 将返回此元素的 jQuery 对象。 - Arjun

-2
var scrollContainer = $('.b-partners .b-partners__inner');
var maxScrollLeft = $(scrollContainer)[0].scrollWidth - $(scrollContainer).width();
console.log(maxScrollLeft);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接