通过JavaScript在移动版Safari中检测应用顶部的双击

时间:2014-03-05 16:25:55

标签: javascript html ios safari

iOS有一个惯例,即双击顶部栏(即显示当前时间的位置)将应用程序滚动到顶部状态。例如,双击Safari中的顶栏会将您带到当前网页的顶部,并且在Facebook / Twitter中双击顶部会将您带到Feed的顶部。这是一个非常有用的导航快捷方式。

为了解决这个问题,我们称之为TopTap。

我想知道如何在移动版Safari中的JavaScript应用中检测TopTaps - 也就是说,不是在iOS应用中,而是在移动版Safari中看到的网页中。

在我的特定情况下,我不能依赖内置的移动Safari TopTap行为,因为我的文档由一个<canvas>元素组成,它实现了自己的可滚动界面。我希望能够检测到TopTap,以便将<canvas>滚动到顶部状态。

我已尝试添加onscroll事件处理程序,但在该事件中没有区别信息可以让我隔离TopTaps。此外,我无法使用触摸事件(touchstart等),因为TopTap发生在浏览器/ OS chrome中,超出了网页的范围。

有什么想法吗?

4 个答案:

答案 0 :(得分:5)

事实证明,双击本机​​状态栏会触发{em} 实际上可以监听的document.body上的滚动事件。如你所说,诀窍是如何判断它是否来自双击?

为了检测它,身体必须向下滚动才能开始。设置滚动位置会导致滚动事件。

虽然这是一堆黑客,但我已经能够实现这个目标:

代码:https://github.com/HenrikJoreteg/holy-grail-ios-layout

演示:http://ios-layout.surge.sh

基本上,您并没有真正使用<body>作为容器。您将其设置为position: absolute和全高/宽。然后,您将某些容器元素设置为position: fixed,并将其用作内容的实际容器。

执行此操作可让您以编程方式滚动正文,而不会影响页面上的任何视觉效果。

现在,您已设置为侦听正文上的滚动事件,理想情况下,用户无法通过双击状态栏实际导致之外的滚动。

不幸的是,你必须做各种愚蠢的事情来使这项工作。

  1. 在身体上放置高于100%的东西,这样身体实际上可以滚动。
  2. 以编程方式将滚动位置设置为1以开始,并在每个状态栏双击后。
  3. 在主体上设置一个去抖动的滚动处理程序,只有在知道事件不是由将位置设置为1时才会触发。
  4. 事实证明,当您旋转手机等时,iOS也喜欢打破它。
  5. 使用以下CSS使您的实际内容容器的内容可以使用动量和橡皮筋滚动:
  6. overflow-y: scroll; /* has to be scroll, not auto */ -webkit-overflow-scrolling: touch;

    无论如何,这是:)

    github repo中的更多信息,但无论如何,对于iOS 8来说这确实看起来效果很好(还没有测试过其他版本的iOS)。

答案 1 :(得分:2)

如果您的目标是最近的iOS,则可以将canvas上的position: fixed元素放在视口顶部,并使用它来检测双击。

编辑:我正在考虑类似下面的内容,但正如Adrian所指出的那样,当本地浏览器Chrome也被双击时,他需要这样做。

<!doctype html>
<html>
    <head>
        <style type="text/css">
        canvas {
            height: 1000px;
            width: 320px;
        }
        #top-tap {
            height: 16px;
            left: 0;
            position: fixed;
            right: 0;
            top: 0;
        }
        </style>
    </head>
    <body>
        <canvas></canvas>
        <a id="top-tap"></a>
        <script type="text/javascript">
        function secondTap() {
            window.scrollTo(0,0)
        }
        document.querySelector('#top-tap').addEventListener('touchend', function (e) {
            var self = this
            this.addEventListener('touchend', secondTap)
            setTimeout(function () {
                self.removeEventListner('touchend', secondTap)
            }, 100)
        })
        </script>
    </body>
</html>

答案 2 :(得分:1)

是否可以创建隐藏的本机html元素,其高度与画布中的内容相同。然后将本机元素上的滚动位置映射到画布中的相同位置。也可以隐藏画布滚动小部件。

就用户而言,他们只看到原生滚动条...但所有滚动事件都映射到画布 - 包括状态栏点击。

如果页面上有其他HTML内容,则可能无效,但可能只有画布可见。

编辑:这是一个非常粗略的原型http://jsbin.com/cisizopi/3

我正在使用divs

模拟画布和内容

答案 3 :(得分:0)

经过一番研究后,我发现了这篇文章:http://prud.github.io/ios-overflow-scroll-to-top/。我不确定这是否能满足您的需求。另外,我很确定你不能在IOS的浏览器中拦截状态栏触摸JS。