如何自动检测是否需要iScroll?

How to automatically detect the need for iScroll?

iScroll project provides the “overflow:scroll for mobile WebKit”,并开始

[…] because webkit for iPhone does not provide a native way to scroll content inside a fixed size (width/height) div. So basically it was impossible to have a fixed header/footer and a scrolling central area.

我们开发了一个移动友好的 Web 应用程序,使用响应式设计(等),使用有时在移动设备上显示固定页眉和页脚的布局,基于 core-layout library, which in turn uses angular-iscroll

您可以尝试打开和关闭 core-layout demo on desktop and mobile, and try to turn the use of iScroll。在桌面滚动时,不同的区域应该可以在有和没有 iScroll 的情况下工作(假定 window 不是太高,因此不需要滚动);然而,在移动设备上,滚动是否可以在没有 iScroll 的情况下工作取决于浏览器的种类和版本。

最新版本的移动 Safari 浏览器和 Android 浏览器已开始支持 overflow:scroll 上述固定大小的 div 元素。因此,一些浏览器仍然需要使用 iScroll 才能工作,而另一些浏览器则不需要。因为使用 iScroll 本身会引入一些问题,比如正确的点击和触摸事件处理,我想在所有不需要它的浏览器中关闭 iScroll。

我想在angular-iscroll or core-layout for automatically detecting if there is any need to use iScroll or not for each browser opening the page. I know about feature detection libraries like modernizr中添加支持,但似乎很难根据特征检测来确定是否需要iScroll。

有谁知道如何实现这种自动检测?

另一种可能性是使用 white/black-list 并检查浏览器版本,但在那种情况下,我想知道是否有人有可靠的规则集来根据用户代理字符串正确确定是否需要使用 iScroll ?

披露:我是这两本书的作者 angular-iscroll and core-layout

2016-01-10 更新:

由于还没有人提出任何答案,我想我可以分享一些我对如何解决这个问题的想法:

如果有人可以根据其中一个想法(或它们的组合)提出可靠的解决方案,那么我很乐意提供帮助。

另外,我想知道为什么没有人试图想出一个答案;甚至没有评论说这太过分了 difficult/trivial/irrelevant/strange/outdated?

如果只需要实现一个置顶header。你确实需要找出系统。其实最新的Ios系统(8以上)browser support,可以用"position:sticky"实现粘头。非常方便,而且没有副作用。

其他平台(android 和旧的 IOS),你确实需要像 'Iscroll' 这样的东西,你可以像你提到的那样使用 platform.js 或者你可以简单地检查 'useragent'。它包含您需要的一切。

由于还没有其他人提出解决方案,我想我可以分享我的,希望这个答案可以被编辑和改进,以更准确地决定哪些设备必须使用 iScroll。

我写了下面的 Modernizr extension that makes use of platform.js 来决定是否支持原生 overflow: scroll div 滚动:

'use strict';

var platform = require('platform'),
    Modernizr = require('modernizr');

function _isChromeMobile(platform) {
    return platform.name === 'Chrome Mobile';
}

function _isAndroidBrowserWithRecentOS(platform) {
    return platform.name === 'Android Browser' &&
        versionCompare(platform.os.version, '4.0.4') >= 0;
}

module.exports = function _useNativeScroll(platform) {
    if (platform.name === 'Opera Mini') {
        return false;
    }

    if (platform.name === 'IE Mobile') {
        return versionCompare(platform.version, '11.0') >= 0
    }

    switch (platform.os.family) {
        case 'Android':
            // In Chrome we trust.
            return _isChromeMobile(platform) ||
                _isAndroidBrowserWithRecentOS(platform);
        case 'iOS':
            // Buggy handling in older iOS versions.
            return versionCompare(platform.version, '5.1') >= 0;
        default:
            // Assuming desktop or other browser.
            return true;
    }
};

Modernizr.addTest('usenativescroll',
                  require('modernizr-usenativescroll'));

其中 Jon Papaioannou 的 compareVersion()How to compare software version number using js? (only number) or this gist with documentation 中定义。

现在,不幸的是,这种方法不使用特征检测,但如果有人提出更多关于有问题的设备或浏览器版本的事实,希望可以进一步改进。

更新2016-01-27

感谢 BrowserStack, I've been able to test core-layout, and thereby angular-iscroll 慷慨的“开源免费”赞助,以及大量的设备和浏览器。基于这些测试,我改进了 angular-iscroll 的 auto-detect 规则和上面的代码。

更新2016-01-25

从 3.1.0 版开始 angular-iscroll 内置了此功能。自动检测的结果通过布尔标志 iScrollService.state.autoDetectedUseNativeScrolliScrollServiceProvider.useNativeScroll 公开;后者在应用程序初始化的 config 阶段可用。