虚拟键盘导致窗口大小改变引起jquery mobile问题

24

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

  • 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()事件中添加了一个“debugger”语句,并尝试逐行执行代码。我希望能够找到其他的调整页面大小的监听器。如果我能找到它,那么我就可以在某个人选择表单元素时临时禁用它,然后在模糊或方向更改时重新启用调整大小。问题是,我逐行执行了所有代码,而调试过程停在调整大小发生之前。

这让我想知道是否有其他事件除了window.resize被触发。因此,我添加了下面两行:

    document.addEventListener("throttledresize", function() { alert("throttledresize fired.") }, false);
    document.addEventListener("orientationchange", function() { alert("orientationchange fired.") }, false);

不过它们都没起作用。所以我有点卡住了。我很有感觉知道问题出在哪里,但是我无法追溯到源头。你有什么建议可以指导我在哪里找到这个神秘的代码,在窗口尺寸改变时调整页面大小吗?


2
我真的很希望我能给你一个答案,朋友。 - Ohgodwhy
你确定是JQM而不是Cordova吗?我确信最近读到过一些关于Cordova的内容(现在找不到了),涉及由于软键盘出现而调整窗口大小,并确保它不是方向改变的问题。 - Dave R
我遇到了同样的问题。很高兴在SO上找到了你的问题,否则我就不知道出了什么问题。正是因为这种情况,我正在尝试放弃使用jQuery Mobile。我现在只有一个小部件在我的应用程序中使用,一旦它消失了,我就会摆脱jqm。 - groodt
我花了几天时间进行破解,但问题已经解决了。实际上,我发现我在JQM 0.x时代放置的许多CSS hack正在干扰JQM 1.3.1。因此,我基本上只是禁用了所有内容,以查看应用程序的行为,然后逐步重新启用了所有自定义CSS。我认为在某个时候我搞乱了ui-page或ui-content的定位,导致了副作用。 - Anthony
以下解决方案对我来说很容易。只需设置视口高度即可。 https://dev59.com/DGIk5IYBdhLWcg3wi-xM - Raydemo
显示剩余3条评论
5个回答

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


很好。我发现使用data-position="Fixed"的页眉/页脚是问题的根源。将它们更改为非固定的后,当键盘出现时,我的文本框位置正确。 - Dave R
你,先生,是一个救星。这个应该被移入jQuery mobile本身。 - groodt
嗯,这很“hacktastic”。:) 我也不再使用它了。请参阅我之前关于CSS hack是根本问题的评论。也许尝试做一个“Hello World”应用程序,看看是否仍然有这个问题。如果是这样,你可能在某个地方有CSS冲突。 - Anthony

3

我遇到了类似的问题,尝试这个:

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

  }

2

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

然而,我仍然失去了UI的“锁定”感,用户可以在键盘退出后拖动整个UI。当然,标题和页脚没有移动,但我的背景和主要内容区域现在是可拖动的,并出现了滚动条。如果您想要本地应用程序的感觉,这是完全不可接受的...

因此,我决定在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 );

再次强调,虽然我很想自己拍胸脯表示这是我的好主意,但事实上我只是在别人的好主意上找到了额外的角度。


1

前往您的androidmanifest文件,在活动中更改或更新此值 android:windowSoftInputMode="adjustResize"

我知道调整面板会破坏页面,因此控件被隐藏。默认值(未指定)可能还可以,这里还有其他选项。 我认为如果不调整大小,它不会向jqm传达kb已显示

因此,请保持jqm不变,不要进行更改,它将完成其工作 顺便说一下,我正在使用cordova 2.2,jqm 1.2和jquery 1.8.2


0

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

我通过根据窗口高度设置CSS高度来解决这个问题:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接