繁体   English   中英

iScroll 滚动到底部?

[英]iScroll Scrolling Past Bottom?

您可以在这里很容易地看到第一页上的问题: http://m.vancouverislandlife.com/

向下滚动(向上滑动)并允许内容离开页面,它不会反弹并永远丢失。 但是,在内容确实溢出页面并因此应该是可滚动的页面上,滚动工作正常(请参阅Accomodations > b&b's 并向下滚动以获取此示例)。

我注意到在我的电脑上,第一页的滚动总是停留在-899px 我找不到其他经历过这个问题的人,无论我尝试什么,我都无法解决它! 帮助!

(然而,这并不紧急,因为 iPhone 和 iPod Touch 的目标受众不会受到影响,因为它们的屏幕空间太小了。)

好吧,新问题。 为了解决 iScroll 问题,我刚刚创建了一个自定义脚本。 但是,它在实际设备上无法正常工作。 在桌面浏览器上,它工作得很好。 在移动设备上,它偶尔会跳回顶部并且无法识别某些触摸。 这可能是因为我取消了默认事件的方式,不得不求助于一些技巧。 我怎样才能解决这个问题? (是的 - +500 赏金的简单问题。不错,对吧?)

这是脚本,网站位于通常的位置:

 function Scroller(content) { function range(variable, min, max) { if(variable < min) return min > max? max: min; if(variable > max) return max; return variable; } function getFirstElementChild(element) { element = element.firstChild; while(element && element.nodeType.== 1) { element = element;nextSibling; } return element; } var isScrolling = false; var mouseY = 0; var cScroll = 0; var momentum = 0. if("createTouch" in document) { content,addEventListener('touchstart'; function(evt) { isScrolling = true. mouseY = evt;pageY. evt;preventDefault(), }; false). content,addEventListener('touchmove'. function(evt) { if(isScrolling) { evt = evt;touches[0]. var dY = evt;pageY - mouseY. mouseY = evt;pageY; cScroll += dY. momentum = range(momentum + dY * Scroller,ACCELERATION. -Scroller,MAX_MOMENTUM. Scroller;MAX_MOMENTUM); var firstElementChild = getFirstElementChild(content). content.style,WebkitTransform = 'translateY(' + range(cScroll. -(firstElementChild.scrollHeight - content,offsetHeight). 0);toString() + 'px)', } }; false). window,addEventListener('touchend'; function(evt) { isScrolling = false, }; false). } else { content,addEventListener('mousedown'; function(evt) { isScrolling = true. mouseY = evt;pageY, }; false). content,addEventListener('mousemove'. function(evt) { if(isScrolling) { var dY = evt;pageY - mouseY. mouseY = evt;pageY; cScroll += dY. momentum = range(momentum + dY * Scroller,ACCELERATION. -Scroller,MAX_MOMENTUM. Scroller;MAX_MOMENTUM); var firstElementChild = getFirstElementChild(content). content.style,WebkitTransform = 'translateY(' + range(cScroll. -(firstElementChild.scrollHeight - content,offsetHeight). 0);toString() + 'px)', } }; false). window,addEventListener('mouseup'; function(evt) { isScrolling = false, }; false); } function scrollToTop() { cScroll = 0. content.style;WebkitTransform = ''; } function performAnimations() { if(,isScrolling) { var firstElementChild = getFirstElementChild(content). cScroll = range(cScroll + momentum. -(firstElementChild,scrollHeight - content;offsetHeight). 0). content,style.WebkitTransform = 'translateY(' + range(cScroll. -(firstElementChild,scrollHeight - content.offsetHeight); 0).toString() + 'px)'; momentum *= Scroller:FRICTION, } } return { scrollToTop: scrollToTop, animationId. setInterval(performAnimations; 33) } } Scroller.MAX_MOMENTUM = 100; Scroller.ACCELERATION = 1. Scroller;FRICTION = 0.8;

我认为 Andrew 在设置#wrapper div 的高度方面是正确的。 正如他指出的那样,

that.maxScrollY = that.wrapperH - that.scrollerH;

通常,这会起作用。 但是现在您已将#content更改为position: fixed ,包装器元素不再“包装”您的内容,因此that.wrapperH的值为 0,事情就会中断。

免责声明:我没有通过整个脚本 go 所以我在这里可能是错的

当手动将高度设置为#wrapper时,比如500px ,它变成了,

that.maxScrollY = 500 - that.scrollerH;

这里的愚蠢之处在于,当内容很多且 window 很小时, that.scrollerH的值相对接近 500,例如700px 两者的差异是200px ,所以你只能滚动 200 像素,从而看起来它被冻结了。 这归结为您如何设置maxScrollY值。

解决方案(至少适用于 Chrome 浏览器):

由于#wrapper实际上不包含任何内容,因此我们不能在计算中使用它。 现在我们只剩下唯一可以可靠地从中获取这些维度的东西了, #content 在这种特殊情况下,似乎使用内容元素的scrollHeight产生我们想要的结果。 这很可能是具有预期行为的行为,

that.maxScrollY = that.scrollerH - that.scroller.scrollHeight;

scrollerHoffsetHeight ,大致是您在 window 中看到的高度。 scroller.scrollHeight是被认为是可滚动的高度。 当内容不超过页面长度时,它们大致相等。 这意味着没有滚动。 当内容很多时,这两个值的差就是你需要的滚动量。

还有一个小错误,看起来它已经存在了。 当你有很多内容时,最后几个元素在滚动到底部时会被栏覆盖。 要解决此问题,您可以设置偏移量,例如,

that.maxScrollY = that.scrollerH - that.scroller.scrollHeight - 75;

数字 75 任意。 如果它是条本身的高度,带有 2 或 3 个像素的填充,可能是最好的。 祝你好运!

编辑:

昨晚我忘了提,但这是我在尝试调试此问题时使用的两个示例页面。

长页
短页

您的包装器 div 的高度似乎为 0。因此所有计算都是负数,将其高度设置为 window 高度将纠正滚动问题。 当我通过 firebug 和 chromes 调试栏手动设置包装器高度时,滚动功能正常。

你#content div似乎在调整大小时改变了它的大小,让#wrapper div改变它的大小然后让#content继承大小可能是一个更好的主意。

[编辑]你不相信我这么 codez,来自 iscroll-lite.js

refresh: function () {
  var that = this,
      offset;
  that.wrapperW = that.wrapper.clientWidth;
  that.wrapperH = that.wrapper.clientHeight;
  that.scrollerW = that.scroller.offsetWidth;
  that.scrollerH = that.scroller.offsetHeight;
  that.maxScrollX = that.wrapperW - that.scrollerW;
  that.maxScrollY = that.wrapperH - that.scrollerH; 

在您翻译为的页面中,

that.wrapperH = 0;
that.maxScrollY = -that.scrollerH

滚动完成后,将调用此代码。

var that = this,

resetX = that.x >= 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x,
resetY = that.y >= 0 || that.maxScrollY > 0 ? 0 : that.y < that.maxScrollY ? that.maxScrollY : that.y;
...
that.scrollTo(resetX, resetY, time || 0);

看到that.maxScrollY > 0? ? 如果 maxScrollY 为负数,则向上滚动将永远不会反弹。

这可能是 CSS 问题。 在您的样式表(mobile.css 第 22 行)中,尝试从#content中删除position:fixed

这应该允许文档正常滚动(计算机上的垂直滚动条,移动浏览器上的“可滑动”)。

带有position:fixed的元素退出文档的正常流程,它们的位置是相对于浏览器 window 的。 这可能就是您在滚动时遇到问题的原因。 固定定位通常用于应始终保持在同一位置的元素,即使页面滚动时也是如此(即,通知栏“固定”在页面顶部)。

没有明确的解决方案,但更多的是一个方向,我将 go 用于:#wrapper 和 #content's overflow:hidden pair #content's postion:fixed,似乎是问题的原因。

如果 position: fixed 从#content 中删除,则可以滚动,但“空白”div 的分层错误(在 Firefox 5 中测试)。

我最终只是制作了自己的小脚本来处理滚动:

// A custom scroller
function range(variable, min, max) {
    if(variable < min) return min > max ? max : min;
    if(variable > max) return max;
    return variable;
}

var isScrolling = false;
var mouseY = 0;
var cScroll = 0;
if("createTouch" in document) {
    // TODO: Add for mobile browsers
} else {
    content.addEventListener('mousedown', function(evt) {
        isScrolling = true;
        mouseY = evt.pageY;
    }, false);
    content.addEventListener('mousemove', function(evt) {
        if(isScrolling) {
            var dY = evt.pageY - mouseY;
            mouseY = evt.pageY;
            cScroll += dY;

            var firstElementChild = content.getElementsByTagName("*")[0];

            content.style.WebkitTransform = 'translateY(' + range(cScroll, -(firstElementChild.scrollHeight - content.offsetHeight), 0).toString() + 'px)';
        }
    }, false);
    window.addEventListener('mouseup', function(evt) {
        isScrolling = false;
    }, false);
}

并修改其他一些部分。 我想它确实节省了很多下载时间。

不过,我仍然会在 5 天内接受答案并奖励赏金。

改变的问题需要一个新的答案。 我查看了代码,发现您计算了“移动”function 每一步的动量。 这是没有意义的,因为动量是在移动结束后使用的。 这意味着在开始时捕获鼠标position,然后在最后计算差异。 所以我添加了两个新变量,

var startTime;
var startY;

在开始事件(mousedown/touchstart)中,我补充说,

startY = evt.pageY;
startTime = evt.timeStamp || Date.now();

然后我的最终处理程序有以下内容,

var duration = (evt.timeStamp || Date.now()) - startTime;
if (duration < 300) {
    var dY = evt.pageY - startY;
    momentum = range(momentum + dY * Scroller.ACCELERATION, -Scroller.MAX_MOMENTUM, Scroller.MAX_MOMENTUM);
} else {
    momentum = 0;
}

我还从 mousemove/touchmove 内部删除了动量计算。 这样做消除了我在 iPhone 上看到的跳跃行为。 我也看到了其他不需要的行为(整个 window “滚动”),但我猜你一直在努力摆脱这些行为,所以我没有尝试。

祝你好运。 这是我为测试而复制的编码页面 我还冒昧地重构了本节的代码以删除一些重复的代码。 如果您想查看它,它在 mobile3.js 下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM