I am trying to use JQM in a Phonegap project to create a fixed header and footer in an iOS app. I have a page that uses collapsable DIVs and it has a text input inside the DIV. Everything is fine with the header and footer until I expand the DIV and input something into the text field. Once I dismiss the iOS keyboard the header has moved up and is overlaid by the iPhones "information" bar, and the footer has also slid up on the page and is no longer fixed to the bottom. If I expand another collapsible DIV after this the footer moves back into the correct location, but the header stays overlaid off the top of the screen. Any ideas what is going on?
JQM Page Code:
<div data-role="page" id="wizard_3">
<div data-role="header" class="header" data-id="cls_header">
<h1>
<label>Testing®</label>
testProgram®</h1>
</div>
<div data-role="content">
<div data-role="collapsible-set" id="ability_set">
<div data-role="collapsible" data-collapsed="true" id="abilQuestion1" class="collapsedAbilityQuestion">
<h3 id="abilQuestion1Header">XXXXXXX </h3>
<p id="abilQuestion1Text">XXXXXXX</p>
<div data-role="fieldcontain" data-inline="true" class="ratingControls">
<fieldset data-role="controlgroup">
<input type="button" data-icon="arrow-l" data-iconpos="notext" data-inline="true"/>
<input type="text" id="ability1" class="assessNum" value="0"/>
<input type="button" data-icon="arrow-r" data-iconpos="notext" data-inline="true"/>
</fieldset>
</div>
</div>
<div data-role="collapsible" data-collapsed="true" id="abilQuestion2" class="collapsedAbilityQuestion">
<h3 id="abilQuestion2Header">XXXXXXX</h3>
<p id="abilQuestion2Text">XXXXXXX</p>
<div data-role="fieldcontain" data-inline="true" class="ratingControls">
<fieldset data-role="controlgroup">
<input type="button" data-icon="arrow-l" data-iconpos="notext" data-inline="true"/>
<input type="text" id="ability2" class="assessNum" value="0"/>
<input type="button" data-icon="arrow-r" data-iconpos="notext" data-inline="true"/>
</fieldset>
</div>
</div>
<div data-role="collapsible" data-collapsed="true" id="abilQuestion3" class="collapsedAbilityQuestion">
<h3 id="abilQuestion3Header">XXXXXXX</h3>
<p id="abilQuestion3Text">XXXXXXX</p>
<div data-role="fieldcontain" data-inline="true" class="ratingControls">
<fieldset data-role="controlgroup">
<input type="button" data-icon="arrow-l" data-iconpos="notext" data-inline="true"/>
<input type="text" id="ability3" class="assessNum" value="0"/>
<input type="button" data-icon="arrow-r" data-iconpos="notext" data-inline="true"/>
</fieldset>
</div>
</div>
<div data-role="collapsible" data-collapsed="true" id="abilQuestion4" class="collapsedAbilityQuestion">
<h3 id="abilQuestion4Header">XXXXXXX</h3>
<p id="abilQuestion4Textr">XXXXXXX</p>
<div data-role="fieldcontain" data-inline="true" class="ratingControls">
<fieldset data-role="controlgroup">
<input type="button" data-icon="arrow-l" data-iconpos="notext" data-inline="true"/>
<input type="text" id="ability4" class="assessNum" value="0"/>
<input type="button" data-icon="arrow-r" data-iconpos="notext" data-inline="true"/>
</fieldset>
</div>
</div>
<div data-role="collapsible" data-collapsed="true" id="abilQuestion5" class="collapsedAbilityQuestion">
<h3 id="abilQuestion5Header">XXXXXXX</h3>
<p id="abilQuestion5Text">XXXXXXX</p>
<div data-role="fieldcontain" data-inline="true" class="ratingControls">
<fieldset data-role="controlgroup">
<input type="button" data-icon="arrow-l" data-iconpos="notext" data-inline="true"/>
<input type="text" id="ability5" class="assessNum" value="0"/>
<input type="button" data-icon="arrow-r" data-iconpos="notext" data-inline="true"/>
</fieldset>
</div>
</div>
<div data-role="collapsible" data-collapsed="true" id="abilQuestionn6" class="collapsedAbilityQuestion">
<h3 id="abilQuestion6Header">XXXXXXXX</h3>
<p id="abilQuestion6Text">XXXXXXXX</p>
<div data-role="fieldcontain" data-inline="true" class="ratingControls">
<fieldset data-role="controlgroup">
<input type="button" data-icon="arrow-l" data-iconpos="notext" data-inline="true"/>
<input type="text" id="ability6" class="assessNum" value="0"/>
<input type="button" data-icon="arrow-r" data-iconpos="notext" data-inline="true"/>
</fieldset>
</div>
</div>
</div>
</div>
<div id="footer" data-role="footer" data-position="fixed" class="ui-bar footer" data-theme="b"> <span class="leftButton">
<input type="button" class="leftButton" data-theme="b" data-icon="arrow-l" value="Back" onClick="goBack(2)"/>
</span> <span class="rightButton">
<input type="button" class="rightButton" id="wizardNextButton_3" data-theme="b" data-icon="arrow-r" value="Coninue to Step 3" onClick="javascript:wizardDecision(3, true); return false"/>
</span> </div>
</div>
I had a similar problem I fixed with this:
/* iOS keyboard popup somehow leaves page scrolled, unscroll it */
$.mobile.silentScroll(0);
I've found the solution in http://forum.jquery.com/topic/phonegap-jqm-fixed-position-header-footer-moves-after-dismissing-ios-keyboard
Take a look at this solution.
This was reported as a jQM bug but it still in jQM 1.3.2.
Try this solution which works for me, taken from the thread noted below.
// Workaround for buggy header/footer fixed position when virtual keyboard is on/off
$('input, textarea')
.on('focus', function (e) {
$('header, footer').css('position', 'absolute');
})
.on('blur', function (e) {
$('header, footer').css('position', 'fixed');
//force page redraw to fix incorrectly positioned fixed elements
setTimeout( function() {
window.scrollTo( $.mobile.window.scrollLeft(), $.mobile.window.scrollTop() );
}, 20 );
});
Other solutions are posted here. It is a worth looking thread: https://github.com/jquery/jquery-mobile/issues/5532
This is a difficult problem to get 'right'. You can try and hide the footer on input element focus, and show on blur, but that isn't always reliable on iOS. Every so often (one time in ten, say, on my iPhone 4S) the focus event seems to fail to fire (or maybe there is a race condition), and the footer does not get hidden.
After much trial and error, I came up with this interesting solution:
<head>
...various JS and CSS imports...
<script type="text/javascript">
document.write( '<style>#footer{visibility:hidden}@media(min-height:' + ($( window ).height() - 10) + 'px){#footer{visibility:visible}}</style>' );
</script>
</head>
Essentially: use JavaScript to determine the window height of the device, then dynamically create a CSS media query to hide the footer when the height of the window shrinks by 10 pixels. Because opening the keyboard resizes the browser display, this never fails on iOS. Because it's using the CSS engine rather than JavaScript, it's much faster and smoother too!
Note: I found using 'visibility:hidden' less glitchy than 'display:none' or 'position:static', but your mileage may vary.
The best solution i found for this problem is use this plugin: ( input blur not working so well )
bindViewEvents: function () {
var context = this;
window.addEventListener('native.showkeyboard', context.keyboardShowHandler);
window.addEventListener('native.hidekeyboard', context.keyboardHideHandler);
},
keyboardHideHandler: function (e) {
var context = this;
$(".ui-footer[data-role='footer']").show();
},
keyboardShowHandler: function (e) {
var context = this;
$(".ui-footer[data-role='footer']").hide();
}
I just test it, it works.
$(document).on('focus','input', function() {
setTimeout(function() {
$('#footer1').css('position', 'absolute');
$('#header1').css('position', 'absolute');
}, 0);
});
$(document).on('blur','input', function() {
setTimeout(function() {
$('#footer1').css('position', 'fixed');
$('#header1').css('position', 'fixed');
}, 800);
});
来源:https://stackoverflow.com/questions/8992502/phonegap-jqm-fixed-position-header-footer-moves-after-dismissing-ios-keyboard