由于虚拟键盘导致的window.resize导致jquery mobile出现问题

时间:2012-10-14 06:30:24

标签: jquery cordova jquery-mobile event-handling

我遇到了一个不寻常的问题,我正在寻找建议。基本上,我正在使用:

  • JQuery Mobile 1.1
  • JQuery 8.2
  • PhoneGap(Cordova)2.1

在iPhone上我的应用程序的许多页面上,如果我将光标放入输入框,则会打开虚拟键盘。这很好,也很期待。

问题出在这里:在某些情况下(但不是全部),将光标放入输入框会触发window.resize事件。我已通过以下代码验证了这一点:

    $(window).resize(function(e) {
        alert('The window resize occurred!  Width: ' + $(window).width() + " Height: " + $(window).height());
        debugger;
        return false;
    });

在解析window.resize事件后,JQueryMobile立即决定将页面调整为不正确的高度。我可以告诉它是页面,因为我为每个元素添加了不同的颜色边框以查看它是什么。在许多情况下,这个调整大小的动作导致我的一半GUI在div的底部溢出,有时甚至使我的光标隐藏在div下面。

了解它的最佳方式是使用屏幕截图:

window.resize() triggering page resize

现在,我真的不希望任何人对此有一个确切的答案。我只是在寻找调试技巧。我在window.resize()事件中添加了一个“调试器”语句,并尝试逐步执行代码。我希望能够引导一些旨在调整页面大小的其他调整大小的侦听器。如果我能找到它,那么当有人选择表单元素时,我可以暂时削弱它,然后重新启用模糊或方向更改的大小调整。问题是,我逐步完成了每行代码,调试过程在调整大小之前就停止了。

这让我想知道除了window.resize之外是否还有其他事件被触发。所以我在下面添加了两行:

    document.addEventListener("throttledresize", function() { alert("throttledresize fired.") }, false);
    document.addEventListener("orientationchange", function() { alert("orientationchange fired.") }, false);
但是,他们都没有被解雇。所以我有点卡住了。我很清楚我知道问题是什么,但我无法追溯到源头。关于在哪里可以找到这个神秘的代码,在window.resize()上调整页面大小的任何建议?

5 个答案:

答案 0 :(得分:10)

我很高兴看到我不疯了!我很高兴地报告我已经实施了一个非常好的解决方案。以下是步骤,如果您想要这样做:

1)进入jquery.mobile-1.x.x.js

2)找到$ .mobile = $ .extend()并添加以下属性:

last_width: null,
last_height: null,

3)修改getScreenHeight,使其工作如下:

getScreenHeight: function() {
    // Native innerHeight returns more accurate value for this across platforms,
    // jQuery version is here as a normalized fallback for platforms like Symbian

    if (this.last_width == null || this.last_height == null || this.last_width != $( window ).width())
    {
        this.last_height = window.innerHeight || $( window ).height();
        this.last_width = $(window).width();
    }
    return this.last_height;
}

基本上这会阻止jQuery重新计算页面高度,除非宽度也发生变化。 (即方向更改)由于软键盘仅影响高度,因此此方法将返回缓存的值而不是修改的高度。

我将创建一个单独的帖子,询问如何正确覆盖$ .mobile.getScreenHeight方法。我尝试将下面的代码添加到一个单独的JS文件中,但它不起作用:

delete $.mobile.getScreenHeight;
$.mobile.last_width = null;
$.mobile.last_height = null;
$.mobile.getScreenHeight = function() 
{
   ... the code listed above
}
它大部分时间都解雇了,但也解雇了原来的功能。有点奇怪。我已经发布了一个单独的主题,关于如何在此处正确扩展$ .mobile:Proper way to overide a JQuery Mobile method in $.mobile

答案 1 :(得分:3)

我有一个类似的问题试试这个:

  $('#main-browse').bind("orientationchange", function(event) {
    //Put the page dimensions for example with minimum height property

  }

答案 2 :(得分:2)

我在使用JQuery Mobile 1.4的Cordova(3.x)中遇到了同样的问题 - 所以这不是图书馆作者可能解决的问题。我尝试了许多不同的解决方案 - 但没有一个真正解决它最接近的候选者涉及绑定简单处理程序,分别绑定到窗口和文档对象上的“throttleresize”和“pageshow”事件。

然而,我仍然失去了用户界面的“锁定”感觉,用户可以在键盘退出后拖动整个用户界面。当然页眉和页脚没有移动,但我的背景和主要内容区域现在可以拖动,并且滚动条出现了。如果您正在尝试使用原生应用程序感觉完全不可接受......

所以我决定查看Chrome / Safari firebug并找出将额外像素添加到盒子模型的位置。奇怪的是,我注意到高度根本没有改变,在我的情况下,它是活动页面上的填充。所以我改编了另一个Stack发布的解决方案:

function resetActivePageHeight() {
var aPage = $( "." + $.mobile.activePageClass ),
  aPagePadT = parseFloat( aPage.css( "padding-top" ) ),
  aPagePadB = parseFloat( aPage.css( "padding-bottom" ) ),
  aPageBorderT = parseFloat( aPage.css( "border-top-width" ) ),
  aPageBorderB = parseFloat( aPage.css( "border-bottom-width" ) );
aPage.css( "min-height", deviceInfo.height - aPagePadT - aPagePadB - aPageBorderT - aPageBorderB )
.css("top","0px").css("padding","0px");}

然后我将它们绑定到设备上的文档和窗口事件。

  $( document ).bind( "pageshow", resetActivePageHeight );
  $( window ).bind( "throttledresize", resetActivePageHeight );

同样,虽然我想赞扬,但我认为我只是为别人的好主意找到了另一个角度。

答案 3 :(得分:1)

转到androidmanifest文件并在活动中,更改或更新此值 机器人:windowSoftInputMode = “adjustResize”

我知道adjustPan会破坏页面,因此隐藏了控件。默认(未指定)可能没问题,此处还有其他选项。 我认为如果不调整大小,它不会与jqm通信显示kb

所以请保留jqm,不做任何更改,它将完成其工作 顺便说一句,我使用的是cordova 2.2,jqm 1.2和jquery 1.8.2

答案 4 :(得分:0)

我遇到一个问题,虚拟键盘会扩展视口,显示下面的内容(外部面板)。

我通过根据窗口高度设置css高度来解决:

$('#page').css('height', $(window).height());