无法滚动到iScroll div

时间:2017-09-21 17:48:18

标签: javascript jquery html cordova

所以我试图使用iScroll demo here - Zhuinden帖子。

所以我在我的应用程序中获得了这个代码(这将是一个PhoneGap移动应用程序) - 滚动在我的笔记本电脑/台式机上工作正常,但出于某种原因,我无法滚动到底部手机上的div(在移动应用中)。

以下是代码:

<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

和更接近生产的JSFiddle (这绝对不适合在iOS 11中滚动):

JSFiddle 2

3 个答案:

答案 0 :(得分:0)

首先,整个代码需要重构和组织。没有进攻,但这是一个很大的混乱。

第二: 在iScroll脚本中,jQuery并没有完全加载到小提琴中。在修复它们之后,iScroll在笔记本电脑和移动设备上都运行良好。

测试 here

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

从这一点开始,让我们找到真正的问题。

P.S:拉动刷新的事件工作正常。

答案 1 :(得分:0)

如果您在Android设备上遇到问题,请禁用事件监听器的被动模式:

Binary file "FILE"

来自MDN - Improve scrolling performance

  

从Chrome 56开始(桌面,Chrome for Android和Android   webview)touchstart和touchmove的默认值为true   不允许调用preventDefault()。要覆盖它   行为,您将被动选项设置为false。

答案 2 :(得分:0)

这很可能是由你的大小调整引起的,一点css会为你解决:

#messages-wrapper {
   padding-bottom:10vh;
}