【问题标题】:Occasionally unresponsive back button on jQueryMobile PhoneGap appjQueryMobile PhoneGap 应用程序上的后退按钮偶尔无响应
【发布时间】:2014-06-05 22:08:17
【问题描述】:

我已经使用 jQuery Mobile (1.3.1) 和 PhoneGap (3.4) 创建了一个应用程序,并将它的外观设计为具有相当“扁平”的界面:

我遇到了一些麻烦,只有在 iOS 上,而且只是偶尔,只有一个特定屏幕上的“返回”按钮变得无响应。其他屏幕上的后退按钮的相同 HTML 和 CSS 似乎很好,只是这一屏幕。这是 chrome,在 devtools 中选择了按钮以突出显示其命中区域:

为了更好的衡量,这里也是标题:

该屏幕标题的代码对于应用程序中的几乎每个屏幕都是相同的:

<div data-role="header" data-theme="e" data-position="fixed" data-tap-toggle="false">
    <h1>Event Detail</h1>
    <a data-rel="back">Back</a>
</div>

我们发现,如果用户卡在此屏幕上并强制关闭应用程序,该按钮在后续使用中似乎会按预期工作。

所以我目前的理论是标题以某种方式妨碍了后退按钮(有时)。然而,并非每次都这样的事实让我并不完全相信这个理论。

按钮的 z-index 设置为 10,并且标题的 z-index 保留为默认值(即 1,对吗?)。因此,即使是标题妨碍了我,我的理解是 z-index 为 10 应该将按钮放在“顶部”并使其第一次有机会接收点击/点击事件。

该应用程序使用 jQueryMobile 1.3.1,因为它创建的时间和方式,目前升级不是一个合理的选择。 (在 1.4.x 中有大量重大变化)

我已经在 iOS 和 Android 上调试了该应用程序,并且没有抛出任何 JavaScript 错误。我完全不知道该怎么做。这个应用程序正在向成千上万的用户推出,很有可能很多人,可能是大多数人,都会遇到这个错误。我宁愿不必解释(用我的尾巴夹在两腿之间)强制关闭是解决这个问题的唯一方法......但这就是我迄今为止一直在做的事情。

有人对如何解决这个问题有任何建议或想法吗?


更新 1:

我注意到,在通过 USB 远程调试 Safari 中的应用程序时,我可以看到后退按钮上的类在点击时从 ui-btn-up-e 变为 ui-btn-hover-e 短暂变为 ui-btn-down-e 并返回到 @987654328 @ -- 但该应用程序不会返回! :(

根据要求,这里是应用于标题、H1 和后退按钮的 CSS:(只是“计算”的最终值,不是所有中间覆盖的值)

标题 div:

-webkit-background-clip: border-box;
-webkit-background-origin: padding-box;
-webkit-background-size: auto;
background-attachment: scroll;
background-clip: border-box;
background-color: rgb(179, 27, 27);
background-image: none;
background-origin: padding-box;
background-size: auto;
border-bottom-color: rgb(179, 27, 27);
border-bottom-style: solid;
border-bottom-width: 1px;
border-image-outset: 0px;
border-image-repeat: stretch;
border-image-slice: 100%;
border-image-source: none;
border-image-width: 1;
border-left-color: rgb(179, 27, 27);
border-left-style: solid;
border-left-width: 0px;
border-right-color: rgb(179, 27, 27);
border-right-style: solid;
border-right-width: 0px;
border-top-color: rgb(179, 27, 27);
border-top-style: solid;
border-top-width: 1px;
color: rgb(255, 255, 255);
display: block;
font-family: MyriadPro, Helvetica, sans-serif;
font-weight: bold;
height: 45px;
left: 0px;
padding-top: 1px;
position: fixed;
right: 0px;
text-shadow: rgb(85, 85, 85) 0px 1px 0px;
top: -1px;
width: 320px;
z-index: 1000;
zoom: 1;

上半年:

color: rgb(255, 255, 255);
display: block;
font-family: MyriadPro, Helvetica, sans-serif;
font-size: 18px;
font-weight: bold;
height: 23px;
margin-bottom: 10px;
margin-left: 48px;
margin-right: 48px;
margin-top: 12px;
min-height: 19.799999237060547px;
outline-color: rgb(255, 255, 255);
outline-style: none;
outline-width: 0px;
overflow-x: hidden;
overflow-y: hidden;
padding-bottom: 0px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
text-align: center;
text-overflow: ellipsis;
text-shadow: rgb(85, 85, 85) 0px 1px 0px;
white-space: nowrap;
width: 224px;
zoom: 1;

后退按钮:

-webkit-background-clip: border-box;
-webkit-background-origin: padding-box;
-webkit-background-size: auto;
-webkit-box-shadow: none;
background-attachment: scroll;
background-clip: border-box;
background-color: rgb(179, 27, 27);
background-image: none;
background-origin: padding-box;
background-size: auto;
border-bottom-color: rgb(179, 27, 27);
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
border-bottom-style: solid;
border-bottom-width: 0px;
border-image-outset: 0px;
border-image-repeat: stretch;
border-image-slice: 100%;
border-image-source: none;
border-image-width: 1;
border-left-color: rgb(179, 27, 27);
border-left-style: solid;
border-left-width: 0px;
border-right-color: rgb(179, 27, 27);
border-right-style: solid;
border-right-width: 0px;
border-top-color: rgb(179, 27, 27);
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-top-style: solid;
border-top-width: 0px;
box-shadow: none;
color: rgb(255, 255, 255);
cursor: pointer;
display: block;
font-family: MyriadPro, Helvetica, sans-serif;
font-weight: bold;
height: 31px;
left: 5px;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
margin-top: 0px;
padding-bottom: 0px;
padding-left: 0px;
padding-right: 0px;
padding-top: 0px;
position: absolute;
text-align: center;
text-decoration: none solid rgb(255, 255, 255);
text-shadow: rgb(0, 0, 0) 0px 1px 0px;
top: 15px;
vertical-align: middle;
width: 60px;
z-index: 10;
zoom: 1;

【问题讨论】:

  • 你能告诉我们应用于标题和 h1 的 CSS 吗?
  • 另外请注意,我可以看到 CSS 响应点击,但导航没有发生。我也在 update1 中描述了这一点。
  • 如果你删除它会怎样:data-tap-toggle="false"。同样的行为?
  • 是的,这并不能解决问题,并添加了额外的使标题消失的不良行为(如果您点击屏幕内容)。
  • 告诉我一件事,您(我的意思是您的应用程序)是否在任何时候以编程方式从您的应用程序中删除内容,例如页面。如果上一页以某种方式从 DOM 中删除并且导航历史未相应更改,则会发生此错误。在这种情况下,如果您尝试返回(并且您正在使用 data-rel="back" 执行此操作)应用程序将被卡住。

标签: javascript css jquery-mobile cordova touch


【解决方案1】:

首先让我告诉您,您的问题可能与按钮/标题 CSS 无关。如果此错误仅在返回功能期间偶尔显示,则您的问题可能是由于 data-rel="back" 功能而发生的。

与经典的 href 页面移动不同,data-rel="back" 使用 javascript 导航历史记录,这取决于您的应用内容可能会或可能不会起作用。因为 jQuery Mobile 使用 AJAX 进行页面处理(从你的按钮我可以看到你正在使用这种方法)它也有自己的处理导航历史的方式。

现在,假设您的应用程序大量使用动态内容生成(包括内容删除),例如从 DOM 中删除前一页,在这种情况下 data-rel="back" 不会工作。如果上一页不存在,您将无法返回。还有几个其他因素也会影响此功能。

你可以做些什么来解决这个问题:

  1. 给这个按钮一个类名甚至一个id。之后将点击事件绑定到它(vclick 更好,因为它与点击一样快,没有 300 毫秒延迟,并且可以在桌面和移动浏览器上运行)并在每次单击此按钮时添加控制台输出。所以你会这样做:

    $(document).on('vclick', '#button-ID-goes-here', function(){ 
        console.log('Problematic button');
    });
    

    这样你就可以测试按钮是否被点击了。

  2. 接下来的事情有点复杂。您从未发布过您的页面 HTML,但查看您的页面图像我认为您使用的是正确的 jQuery Mobile 范例,基本上您使用 data-role="page" div 容器作为页面容器。如果他们想要一个合适的 jQuery Mobile 应用程序,那么有多少 jQuery Mobile 开发人员不知道/不了解他们需要/必须拥有它,您会感到惊讶。

    查看在其标题中包含此按钮的页面。将 pagebeforeshow 事件绑定到该页面并监控它是否会触发,如果触发,您可以使用它来显示上一页和下一页。

    工作示例:http://jsfiddle.net/Gajotres/vds2U/72/

    $(document).on('pagebeforeshow', '.ui-page',function (e, data) {
        alert("Previous page : " + data.prevPage.attr('id') + " - Next page: " + $.mobile.activePage.attr('id'));
    }); 
    

    使用此解决方案检查下一页是否正确以及是否存在。如果单击返回按钮时未触发此页面事件,则说明发生了一些不好的事情。

  3. 使用下面的代码作为解决方法。基本上使用页面事件并记住您的上一页。因为您当前正在使用后退按钮,所以这个解决方案在这里是可行的。我们将使用 pagebeforeshow 事件找出我们之前的页面,我们会将其存储到某个 JavaScript 对象中(它将在页面转换之间持续存在)。

    工作示例:http://jsfiddle.net/Gajotres/vds2U/73/

    $(document).on('pagebeforeshow', '#second',function (e, data) {
        pageHandler.prevPage = data.prevPage.attr('id');
    
        $(document).on('click', '#custom-back-button',function () {
            $.mobile.changePage( "#"+pageHandler.prevPage);
        });    
    }); 
    
    var pageHandler = {
        prevPage : null
    }
    

    这是 data-rel="back" 页面处理的完整自定义解决方案。

【讨论】:

  • 感谢您的建议。我肯定在使用&lt;div data-role="page"&gt;。我会尝试其他的事情并回复你...
  • 初步测试看起来不错。它似乎在我的个人设备上运行。在我接受之前需要进行一些更广泛的测试,但它看起来不错。考虑到当时的情况,我不敢相信这是可行的,但我会很高兴它确实有效。 (我会尽快更新问题的更多细节......)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-30
  • 2015-02-08
  • 2014-11-29
相关资源
最近更新 更多