【问题标题】:window.resize due to virtual keyboard causes issues with jquery mobilewindow.resize 由于虚拟键盘导致 jquery mobile 出现问题
【发布时间】:2012-10-04 11:54:39
【问题描述】:

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

  • 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() 事件中添加了一个“调试器”语句,并尝试单步执行代码。我希望被引导到其他一些旨在调整页面大小的调整大小侦听器。如果我能找到它,那么当有人选择表单元素时,我可以暂时削弱它,然后重新启用调整模糊或方向变化的大小。问题是,我单步执行了每一行代码,调试过程在调整大小发生之前就停止了。

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

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

然而,两人都没有开火。所以我有点卡住了。我有一种很好的感觉,我知道问题出在哪里,但我无法追查到根源。关于在哪里可以找到这个在 window.resize() 上调整页面大小的神秘代码有什么建议吗?

【问题讨论】:

  • 我真希望我能给你一个答案 mang
  • 您确定是 JQM 而不是 Cordova?我确定我记得我最近读过一些关于 Cordova 的文章(如果我现在能找到的话,那该死的),由于出现软键盘而调整窗口大小并确保它不是方向改变.....
  • 我很确定它是 JQM,因为它只影响页面
    Cordova 没有任何特定于 UI 的智能。我认为它在 JQM 中绊倒了一些东西,这让 JQM 认为“嘿,现在页面变小了,我最好调整画布的大小”,即使它不应该这样做。此外,如果我将其纯粹作为禁用 Cordova 的 iPhone Web 应用程序运行,也会发生这种情况。
  • 顺便说一句,您可能指的是stackoverflow.com/questions/6731517/…。如果是这样,不幸的是这不是这里的问题。
  • 有趣的是,我刚刚创建了一个存在这个问题的页面 - 当键盘出现时,输入框会滚出屏幕,因此您看不到正在输入的内容。看看我能找到什么。

标签: jquery cordova jquery-mobile event-handling


【解决方案1】:

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

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" 的页眉/页脚是我问题的根源。通过将它们更改为不固定,我的文本框在键盘出现时被正确定位。
  • 您先生,是救生员。这应该被移动到 jQuery mobile 本身。
  • 嗯,这很 hacktastic。 :) 我也不再使用它了。请参阅我之前关于 CSS hack 的 cmets 是根本问题。也许尝试做一个“Hello World”应用程序,看看你是否还有问题。如果是这样,您可能在某个地方遇到了 CSS 冲突。
【解决方案2】:

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

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

  }

【讨论】:

    【解决方案3】:

    我在使用 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 );
    

    再一次,虽然我想表扬,但我想我只是找到了另一个角度来理解别人的好主意。

    【讨论】:

      【解决方案4】:

      转到您的 androidmanifest 文件并在活动中更改或更新此值 android:windowSoftInputMode="adjustResize"

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

      所以让 jqm 保持原样,无需您的更改,它会完成它的工作 顺便说一句,我使用的是科尔多瓦 2.2、jqm 1.2 和 jquery 1.8.2

      【讨论】:

        【解决方案5】:

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

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

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

        【讨论】:

          猜你喜欢
          相关资源
          最近更新 更多
          热门标签