您可以在此处的第一页轻松查看问题:http://m.vancouverislandlife.com/
向下滚动(向上滑动)并允许内容离开页面,它不会反弹并永久丢失。但是,在内容 溢出页面并因此应该可滚动的页面上,滚动工作正常(请参阅住宿> 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;
答案 0 :(得分:4)
我认为安德鲁在设置#wrapper
div的高度方面走在了正确的轨道上。正如他指出的那样,
that.maxScrollY = that.wrapperH - that.scrollerH;
通常,这会奏效。但是现在您已将#content
更改为position: fixed
,包装元素不再“包装”您的内容,因此that.wrapperH
的值为0,事情就会中断。
免责声明:我没有浏览整个脚本,所以我可能在这里错了
当手动将高度设置为#wrapper
时,请说500px
,它变为,
that.maxScrollY = 500 - that.scrollerH;
愚蠢的是,当内容很多且窗口很小时,that.scrollerH
的值相对接近500,比如700px
。两者的差异是200px
,因此您只能滚动200像素,从而给出它被冻结的外观。这归结为您如何设置maxScrollY
值。
解决方案(至少适用于Chrome浏览器):
由于#wrapper
实际上不包含任何内容,因此我们无法在计算中使用它。现在,我们唯一能够可靠地从#content
获得这些维度的东西。在这种特殊情况下,似乎使用内容元素scrollHeight
会产生我们想要的东西。这很可能是具有预期行为的那个,
that.maxScrollY = that.scrollerH - that.scroller.scrollHeight;
scrollerH
是offsetHeight
,大致是您在窗口中看到的高度。 scroller.scrollHeight
是被认为可滚动的高度。当内容不超过页面的长度时,它们大致相当于彼此。这意味着没有滚动。当有很多内容时,这两个值的差异就是你需要的滚动量。
还有一个小错误,看起来它已经存在了。当您有大量内容时,滚动到底部时,栏中会覆盖最后几个元素。要解决此问题,您可以设置偏移量,例如
that.maxScrollY = that.scrollerH - that.scroller.scrollHeight - 75;
数字75任意。它可能是最好的,如果它是条的高度本身有2或3像素的一点填充。祝你好运!
编辑:
昨晚我忘了提及,但这里是我尝试调试此问题时使用的两个示例页面。
答案 1 :(得分:1)
你的包装div似乎高度为0.所以所有的计算都是负数,将它的高度设置为窗口高度将纠正滚动问题。当我通过firebug和chromes调试条手动设置包装器高度时,滚动按原样运行。
你#content div似乎在调整大小时会改变它的大小,可能更好的想法让#wrapper div改变它的大小,然后让#content继承大小。
<强> [编辑] 强> 你不相信我这么编码,来自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为负数,则向上滚动永远不会反弹。
答案 2 :(得分:1)
这可能是一个CSS问题。在样式表(mobile.css第22行)中,尝试从position:fixed
删除#content
。
这应该允许文档正常滚动(计算机上的垂直滚动条,移动浏览器上的“可滑动”)。
带有position:fixed
的元素退出文档的正常流程,它们的位置相对于浏览器窗口。这可能是您遇到滚动问题的原因。固定定位通常用于应始终保持在同一位置的元素,即使页面滚动(即页面顶部的“固定”通知栏)。
答案 3 :(得分:1)
没有明确的解决方案,但更多的方向我会去: #wrapper和#content的溢出:隐藏配对#content的位置:固定并且似乎是问题的原因。
如果从#content中移除了position:fixed,则可以滚动,但“blank”divs错误地分层(在Firefox 5中测试)。
答案 4 :(得分:0)
我最终只是制作了自己的小脚本来处理滚动:
// 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天内接受答案并奖励赏金。
答案 5 :(得分:0)
更改的问题需要一个新的答案。我看了一下代码,看到你计算了“移动”功能每一步的动量。这没有意义,因为在移动结束后使用动量。这意味着在开始时捕获鼠标位置,然后在结束时计算差异。所以我添加了两个新变量
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上看到的跳跃行为。我也看到了其他不受欢迎的行为(整个窗口“滚动”),但我猜你一直在努力摆脱那些,所以我没有尝试。
祝你好运。这是我为我的测试重复的coded up page。我还冒昧地重构了本节的代码,以删除一些重复的代码。如果你想查看它,它在mobile3.js下。