问题
I'm hitting an unusual problem and I'm looking for suggestions. Basically, I'm using:
- JQuery Mobile 1.1
- JQuery 8.2
- PhoneGap (Cordova) 2.1
On many pages in my app on iPhone, if I put my cursor into an input box, this opens the virtual keyboard. That's fine and expected.
Here's the problem: In some cases (but not all), placing my cursor into an input box fires the window.resize event. I've verified this via the code below:
$(window).resize(function(e) {
alert('The window resize occurred! Width: ' + $(window).width() + " Height: " + $(window).height());
debugger;
return false;
});
Immediately after it resolves the window.resize event, JQueryMobile decides to resize the page to an incorrect height. I can tell it is the page because I added a different color border to each element to see what was what. And in many cases, this resize action is causing half of my GUI to overflow underneath the bottom of the div, sometimes even making my cursor appear hidden under the div.
The best way to understand it is with a screenshot:

Now, I don't really expect anyone to have an exact answer for this. I'm just looking for debugging tips. I added a "debugger" statement into my window.resize() event and tried to step through the code. I was hoping to be lead to some other resize listener that is designed to resize the page . If I can find that, then I can temporarily cripple it when someone selects a form element, then re-enable resizing on blur or orientation change. The problem is, I stepped through every line of code and the debug process stops right before the resize occurs.
This makes me wonder if there is some other event being fired aside from window.resize. So I added the two lines below:
document.addEventListener("throttledresize", function() { alert("throttledresize fired.") }, false);
document.addEventListener("orientationchange", function() { alert("orientationchange fired.") }, false);
Neither fired, however. So I'm somewhat stuck. I have a good feeling I know what the problem is, but I can't trace it to the source. Any suggestions on where I can find this mysterious code that resizes the page on window.resize()?
回答1:
I'm glad to see I'm not crazy! I'm happy to report I've implemented a pretty good solution. Here are the steps, in case you'd like to do the same:
1) Go into jquery.mobile-1.x.x.js
2) Find $.mobile = $.extend() and add the following attributes:
last_width: null,
last_height: null,
3) Modify getScreenHeight to work as follows:
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;
}
Basically this will prevent jQuery from recalculating the page height unless the width also changes. (i.e. an orientation change) Since the soft keyboard only affects the height, this method will returned the cached value instead of a modified height.
I'm going to create a separate post to ask how to properly override the $.mobile.getScreenHeight method. I tried adding the code below into a separate JS file, but it didn't work:
delete $.mobile.getScreenHeight;
$.mobile.last_width = null;
$.mobile.last_height = null;
$.mobile.getScreenHeight = function()
{
... the code listed above
}
It fired most of the time, but also fired the original function. Kinda weird. I've posted a separate topic in regard to how to properly extend $.mobile here: Proper way to overide a JQuery Mobile method in $.mobile
回答2:
I had a similar issue try this:
$('#main-browse').bind("orientationchange", function(event) {
//Put the page dimensions for example with minimum height property
}
回答3:
I was having the same issue in Cordova (3.x) using JQuery Mobile 1.4--so this isn't something likely to be addressed by the authors of the library. I tried many different solutions--but none really fixed it. The closest candidate involved binding simple handlers bound to the "throttleresize" and "pageshow" events on the window and document objects, respectively.
Yet, I still lost the "locked down" feel of the UI and the user could drag my entire UI up after the keyboard exited. Sure the header and footer did not move, but my background and the main content area were now draggable, and scroll bars appeared. Totally unacceptable if you are trying for that native app feel...
So I decided to look in Chrome/Safari firebug and find out where the extra pixels are being added to the box model. Oddly, I noticed it isn't the height being changed at all, in my case it was the padding on the active page. so I adapted a solution from another Stack posting:
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");}
Then I bound them to the document and window events on device ready.
$( document ).bind( "pageshow", resetActivePageHeight );
$( window ).bind( "throttledresize", resetActivePageHeight );
Again, although i would like to take credit, I think I just found an additional angle to someone else's good idea.
回答4:
go to your androidmanifest file and in the activity, change or update to this value android:windowSoftInputMode="adjustResize"
i know for a fact that adjustPan breaks the page so the controls are hidden. the default (unspecified) may be ok and there are other options here. i think if it is not to resize, it does not communicate to jqm that kb is shown
so leave jqm as is, without your changes and it will do its job btw, i am using cordova 2.2, jqm 1.2 and jquery 1.8.2
回答5:
I had a problem where the virtual keyboard would extend the viewport, showing the contents underneath(an external panel).
I solved by setting the css height based on the window height:
$('#page').css('height', $(window).height());
来源:https://stackoverflow.com/questions/12879857/window-resize-due-to-virtual-keyboard-causes-issues-with-jquery-mobile