[英]Can't scroll to the bottom of an iScroll div
所以我想在这里使用iScroll演示 - Zhuinden的帖子。
所以我在我的应用程序中有这个代码(这将是一个PhoneGap移动应用程序) - 滚动在我的笔记本电脑/台式机上工作正常,但由于某种原因我不能滚动到移动设备的底部(在一个移动应用)。
这是代码:
<script>
function pullDownAction(theScroller) {
var el, li, i;
//TODO: do your things
theScroller.refresh(); //just in case
}
function pullUpAction(theScroller) {
var el, li, i;
//TODO: doYourThings();
theScroller.refresh(); //just in case
}
var IScrollPullUpDown = function(wrapperName, iScrollConfig, pullDownActionHandler, pullUpActionHandler) {
var iScrollConfig, pullDownActionHandler, pullUpActionHandler, pullDownEl, pullDownOffset, pullUpEl, scrollStartPos;
var pullThreshold = 5;
var me = this;
function showPullDownElNow(className) {
// Shows pullDownEl with a given className
pullDownEl.style.transitionDuration = '';
pullDownEl.style.marginTop = '';
pullDownEl.className = 'pullDown ' + className;
}
var hidePullDownEl = function(time, refresh) {
// Hides pullDownEl
pullDownEl.style.transitionDuration = (time > 0 ? time + 'ms' : '');
pullDownEl.style.marginTop = '';
pullDownEl.className = 'pullDown scrolledUp';
// If refresh==true, refresh again after time+10 ms to update iScroll's "scroller.offsetHeight" after the pull-down-bar is really hidden...
// Don't refresh when the user is still dragging, as this will cause the content to jump (i.e. don't refresh while dragging)
if(refresh) setTimeout(function() {
me.myScroll.refresh();
}, time + 10);
}
function init() {
var wrapperObj = document.querySelector('#' + wrapperName);
var scrollerObj = wrapperObj.children[0];
if(pullDownActionHandler) {
// If a pullDownActionHandler-function is supplied, add a pull-down bar at the top and enable pull-down-to-refresh.
// (if pullDownActionHandler==null this iScroll will have no pull-down-functionality)
pullDownEl = document.createElement('div');
pullDownEl.className = 'pullDown scrolledUp';
pullDownEl.innerHTML = '<span class="pullDownIcon"></span><span class="pullDownLabel">Pull down to refresh...</span>';
scrollerObj.insertBefore(pullDownEl, scrollerObj.firstChild);
pullDownOffset = pullDownEl.offsetHeight;
}
if(pullUpActionHandler) {
// If a pullUpActionHandler-function is supplied, add a pull-up bar in the bottom and enable pull-up-to-load.
// (if pullUpActionHandler==null this iScroll will have no pull-up-functionality)
pullUpEl = document.createElement('div');
pullUpEl.className = 'pullUp';
pullUpEl.innerHTML = '<span class="pullUpIcon"></span><span class="pullUpLabel">Pull up to load more...</span>';
//scrollerObj.appendChild(pullUpEl);
}
me.myScroll = new IScroll(wrapperObj, iScrollConfig);
me.myScroll.on('refresh', function() {
if((pullDownEl) && (pullDownEl.className.match('loading'))) {
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
if(this.y >= 0) {
// The pull-down-bar is fully visible:
// Hide it with a simple 250ms animation
hidePullDownEl(250, true);
} else if(this.y > -pullDownOffset) {
// The pull-down-bar is PARTLY visible:
pullDownEl.style.marginTop = this.y + 'px';
// CSS-trick to force webkit to render/update any CSS-changes immediately: Access the offsetHeight property...
pullDownEl.offsetHeight;
var animTime = (250 * (pullDownOffset + this.y) / pullDownOffset);
this.scrollTo(0, 0, 0);
setTimeout(function() {
hidePullDownEl(animTime, true);
}, 0);
} else {
hidePullDownEl(0, true);
this.scrollBy(0, pullDownOffset, 0);
}
}
if((pullUpEl) && (pullUpEl.className.match('loading'))) {
pullUpEl.className = 'pullUp';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Pull up to load more...';
}
});
me.myScroll.on('scrollStart', function() {
scrollStartPos = this.y; // Store the scroll starting point to be able to track movement in 'scroll' below
});
me.myScroll.on('scroll', function() {
if(pullDownEl || pullUpEl) {
if((scrollStartPos == 0) && (this.y == 0)) {
this.hasVerticalScroll = true;
// Set scrollStartPos to -1000 to be able to detect this state later...
scrollStartPos = -1000;
} else if((scrollStartPos == -1000) &&
(((!pullUpEl) && (!pullDownEl.className.match('flip')) && (this.y < 0)) ||
((!pullDownEl) && (!pullUpEl.className.match('flip')) && (this.y > 0)))) {
this.hasVerticalScroll = false;
scrollStartPos = 0;
this.scrollBy(0, -this.y, 0); // Adjust scrolling position to undo this "invalid" movement
}
}
if(pullDownEl) {
if(this.y > pullDownOffset + pullThreshold && !pullDownEl.className.match('flip')) {
showPullDownElNow('flip');
this.scrollBy(0, -pullDownOffset, 0); // Adjust scrolling position to match the change in pullDownEl's margin-top
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Release to refresh...';
} else if(this.y < 0 && pullDownEl.className.match('flip')) { // User changes his mind...
hidePullDownEl(0, false);
this.scrollBy(0, pullDownOffset, 0); // Adjust scrolling position to match the change in pullDownEl's margin-top
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
}
}
if(pullUpEl) {
if(this.y < (this.maxScrollY - pullThreshold) && !pullUpEl.className.match('flip')) {
pullUpEl.className = 'pullUp flip';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Release to load more...';
} else if(this.y > (this.maxScrollY + pullThreshold) && pullUpEl.className.match('flip')) {
pullUpEl.className = 'pullUp';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Pull up to load more...';
}
}
});
me.myScroll.on('scrollEnd', function() {
if((pullDownEl) && (pullDownEl.className.match('flip'))) {
showPullDownElNow('loading');
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Loading...';
pullDownActionHandler(this); // Execute custom function (ajax call?)
}
if((pullUpEl) && (pullUpEl.className.match('flip'))) {
pullUpEl.className = 'pullUp loading';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Loading...';
pullUpActionHandler(this); // Execute custom function (ajax call?)
}
if(scrollStartPos == -1000) {
this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0;
}
});
me.myScroll.refresh();
}
window.addEventListener('load', function() {
init();
}, false);
};
var scroller1 = new IScrollPullUpDown('messages-wrapper', {
probeType: 2,
bounceTime: 250,
bounceEasing: 'quadratic',
mouseWheel: false,
scrollbars: true,
fadeScrollbars: true,
interactiveScrollbars: false,
click: true,
tap: true
}, pullDownAction, pullUpAction);
function blockTouchMove(e) {
e.preventDefault();
}
document.addEventListener('touchmove', blockTouchMove, false);
</script>
<div id="messages-wrapper"><div id="messages"></div></div>
我没看到它可能是什么。 我试过改变滚动距离,我尝试选择禁用部分代码。 我只是不确定究竟是什么限制了我一直向下滚动,并且看起来没有其他人有这个特殊问题。
可能是因为我通过AJAX更新我的div的大小(我正在添加消息)? 如何使用iScroll复制iOS下拉以获取新的消息功能?
编辑:这是一个不起作用的JSFiddle。 我可能会根据某些事情对其进行更改:
和JSFiddle更接近生产(并且它绝对不能在iOS 11中滚动):
首先,整个代码需要重构和组织。 没有进攻,但这是一个大混乱。
第二:jQuery并没有在iScroll脚本中加入小提琴。 在修复它们之后,iScroll在笔记本电脑和移动设备上都能很好地工作。
function pullDownAction(theScroller) {
var el, li, i;
//TODO: do your things
theScroller.refresh(); //just in case
}
function pullUpAction(theScroller) {
var el, li, i;
//TODO: doYourThings();
theScroller.refresh(); //just in case
}
var IScrollPullUpDown = function(wrapperName, iScrollConfig, pullDownActionHandler, pullUpActionHandler) {
var iScrollConfig, pullDownActionHandler, pullUpActionHandler, pullDownEl, pullDownOffset, pullUpEl, scrollStartPos;
var pullThreshold = 5;
var me = this;
init();
function showPullDownElNow(className) {
// Shows pullDownEl with a given className
pullDownEl.style.transitionDuration = '';
pullDownEl.style.marginTop = '';
pullDownEl.className = 'pullDown ' + className;
}
var hidePullDownEl = function(time, refresh) {
// Hides pullDownEl
pullDownEl.style.transitionDuration = (time > 0 ? time + 'ms' : '');
pullDownEl.style.marginTop = '';
pullDownEl.className = 'pullDown scrolledUp';
// If refresh==true, refresh again after time+10 ms to update iScroll's "scroller.offsetHeight" after the pull-down-bar is really hidden...
// Don't refresh when the user is still dragging, as this will cause the content to jump (i.e. don't refresh while dragging)
if(refresh) setTimeout(function() {
me.myScroll.refresh();
}, time + 10);
}
function init() {
var wrapperObj = document.querySelector('#' + wrapperName);
var scrollerObj = wrapperObj.children[0];
console.log(wrapperObj)
if(pullDownActionHandler) {
// If a pullDownActionHandler-function is supplied, add a pull-down bar at the top and enable pull-down-to-refresh.
// (if pullDownActionHandler==null this iScroll will have no pull-down-functionality)
pullDownEl = document.createElement('div');
pullDownEl.className = 'pullDown scrolledUp';
pullDownEl.innerHTML = '<span class="pullDownIcon"></span><span class="pullDownLabel">Pull down to refresh...</span>';
scrollerObj.insertBefore(pullDownEl, scrollerObj.firstChild);
pullDownOffset = pullDownEl.offsetHeight;
}
if(pullUpActionHandler) {
// If a pullUpActionHandler-function is supplied, add a pull-up bar in the bottom and enable pull-up-to-load.
// (if pullUpActionHandler==null this iScroll will have no pull-up-functionality)
pullUpEl = document.createElement('div');
pullUpEl.className = 'pullUp';
pullUpEl.innerHTML = '<span class="pullUpIcon"></span><span class="pullUpLabel">Pull up to load more...</span>';
//scrollerObj.appendChild(pullUpEl);
}
me.myScroll = new IScroll(wrapperObj, iScrollConfig);
me.myScroll.on('refresh', function() {
if((pullDownEl) && (pullDownEl.className.match('loading'))) {
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
if(this.y >= 0) {
// The pull-down-bar is fully visible:
// Hide it with a simple 250ms animation
hidePullDownEl(250, true);
} else if(this.y > -pullDownOffset) {
// The pull-down-bar is PARTLY visible:
pullDownEl.style.marginTop = this.y + 'px';
// CSS-trick to force webkit to render/update any CSS-changes immediately: Access the offsetHeight property...
pullDownEl.offsetHeight;
var animTime = (250 * (pullDownOffset + this.y) / pullDownOffset);
this.scrollTo(0, 0, 0);
setTimeout(function() {
hidePullDownEl(animTime, true);
}, 0);
} else {
hidePullDownEl(0, true);
this.scrollBy(0, pullDownOffset, 0);
}
}
if((pullUpEl) && (pullUpEl.className.match('loading'))) {
pullUpEl.className = 'pullUp';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Pull up to load more...';
}
});
me.myScroll.on('scrollStart', function() {
scrollStartPos = this.y; // Store the scroll starting point to be able to track movement in 'scroll' below
});
me.myScroll.on('scroll', function() {
if(pullDownEl || pullUpEl) {
if((scrollStartPos == 0) && (this.y == 0)) {
this.hasVerticalScroll = true;
// Set scrollStartPos to -1000 to be able to detect this state later...
scrollStartPos = -1000;
} else if((scrollStartPos == -1000) &&
(((!pullUpEl) && (!pullDownEl.className.match('flip')) && (this.y < 0)) ||
((!pullDownEl) && (!pullUpEl.className.match('flip')) && (this.y > 0)))) {
this.hasVerticalScroll = false;
scrollStartPos = 0;
this.scrollBy(0, -this.y, 0); // Adjust scrolling position to undo this "invalid" movement
}
}
if(pullDownEl) {
if(this.y > pullDownOffset + pullThreshold && !pullDownEl.className.match('flip')) {
showPullDownElNow('flip');
this.scrollBy(0, -pullDownOffset, 0); // Adjust scrolling position to match the change in pullDownEl's margin-top
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Release to refresh...';
} else if(this.y < 0 && pullDownEl.className.match('flip')) { // User changes his mind...
hidePullDownEl(0, false);
this.scrollBy(0, pullDownOffset, 0); // Adjust scrolling position to match the change in pullDownEl's margin-top
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Pull down to refresh...';
}
}
if(pullUpEl) {
if(this.y < (this.maxScrollY - pullThreshold) && !pullUpEl.className.match('flip')) {
pullUpEl.className = 'pullUp flip';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Release to load more...';
} else if(this.y > (this.maxScrollY + pullThreshold) && pullUpEl.className.match('flip')) {
pullUpEl.className = 'pullUp';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Pull up to load more...';
}
}
});
me.myScroll.on('scrollEnd', function() {
if((pullDownEl) && (pullDownEl.className.match('flip'))) {
showPullDownElNow('loading');
pullDownEl.querySelector('.pullDownLabel').innerHTML = 'Loading...';
pullDownActionHandler(this); // Execute custom function (ajax call?)
}
if((pullUpEl) && (pullUpEl.className.match('flip'))) {
pullUpEl.className = 'pullUp loading';
pullUpEl.querySelector('.pullUpLabel').innerHTML = 'Loading...';
pullUpActionHandler(this); // Execute custom function (ajax call?)
}
if(scrollStartPos == -1000) {
this.hasVerticalScroll = this.options.scrollY && this.maxScrollY < 0;
}
});
me.myScroll.refresh();
}
window.addEventListener('load', function() {
init();
}, false);
};
var scroller1 = new IScrollPullUpDown('wrapper', {
probeType: 2,
bounceTime: 250,
bounceEasing: 'quadratic',
mouseWheel: false,
scrollbars: true,
fadeScrollbars: true,
interactiveScrollbars: false,
click: true,
tap: true
}, pullDownAction, pullUpAction);
function blockTouchMove(e) {
e.preventDefault();
}
document.addEventListener('touchmove', blockTouchMove, false);
从这一点来看,我们找到了真正的问题。
PS:拉动刷新的事件正常。
如果您在Android设备上遇到问题,请禁用事件侦听器的被动模式:
document.addEventListener('touchmove', blockTouchMove, { passive: false });
来自MDN - 提高滚动性能 :
从Chrome 56(桌面,Chrome for Android和Android webview)开始,touchstart和touchmove的默认值为true,不允许调用preventDefault()。 要覆盖此行为,请将passive选项设置为false。
这很可能是由你的大小调整引起的,一点css会为你解决:
#messages-wrapper {
padding-bottom:10vh;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.