Image in jquery mobile fixed header overlaps content until resize event - jquery-mobile

I have an image in my jquery mobile fixed header. When the page loads in Google Chrome or Apple Safari the header content overlaps the content div below the header until I resize the page. Firefox and IE work just fine.
Thanks!

I think the problem is that when jQuery Mobile initializes the page, the header image is not loaded and the header is much smaller so jQuery Mobile puts a padding on the .ui-page element that is too small once the image loads. A simple fix for this is to manually set the size of the header image so that it takes-up it's required space even before its source loads.
You could also do this, although it seems pretty hacky to me, force a redraw by triggering the resize event on document.ready or maybe window.load:
$(window).on('load', function () {
$(this).trigger('resize');
});
I pasted this code into the console while on your page and it re-positioned the title element as expected.

Does applying the following CSS help?
.ui-page {
padding-top: 91px !important;
}
Note that you will have to refine the selector as this will apply to overlay popups either.

I had lots of trouble with this. This worked until I wanted to add a link:
<div data-role="header">
<img border="0" src="logo.png" style="float:left;display:inline"/> <h1></h1>
</div>
Note the empty h1 tag.
I ended up not using a data-role="header" at all, I just couldn't get it to work with a link. I used a ui-bar class instead. Like this:
<div class="ui-bar ui-bar-a">
<a href="/" data-role="none">
<img border="0" src="images/logo.png" style="float: left; display:inline">
</a>
</div>

A solution based on #Jasper answer that worked for me was:
$(document).on('pageshow', "div[data-role='page']", function () {
$(window).trigger('resize');
});
It has an improvement that apply to all the jquery mobile pages

I played with the rather good solutions from Jasper and Carlos487 and found this to be the most up-to-date and reliable way to do it (jQM 1.4.x):
if it's due to an image without specified dimensions that will need some time to load and thus may cause the header to enlarge, then specifying the known dimensions (ideally via CSS) should do it. Otherwise there should be a way to determine if it has finished loading and thus applying the idea of solution 3 below.
if it's is due to some (maybe) unknown header resize event (e.g. through some image loaded later or some other content shrinking the header and thus making it vertically bigger), then this should work with a reasonable big enough timeout value:
$( ':mobile-pagecontainer' ).on( 'pagecontainershow', function(e) {
// maybe value > 100 needed for your scenario / page load speed
setTimeout( function() { $(window).trigger('resize'); }, 100 /*ms*/ );
}
if you know what is causing this (as in my case, where I am right shifting the page content on large screens via some (otherwise hidden/overlayed) left aligned navigation panel), then the following may be even better, beeing independent of the actual time the page needs to load on some device or scenario (which may be longer than your predefined timeout above):
// if its due to some animation like in my case
// otherwise try to find a similar way to determine when the resizing event has
// completed!
$('#someAnimated').animate( 'complete', function() { $(window).trigger('resize'); });
(I am not sure if Jaspers solution using $(window).on( 'load', ... will be correct in all jQM page load scenarios (with AJAX page navigation). That's why I would prefer Carlos487's approach in my example.)

None of the solutions above worked for me. But I found out my problem lies in the events after the page navigation. If the content div is hidden during this time, it doesn't get positioned under the header div, rather stays in its original place:
$(document).on("pageshow", "div[data-role='page']", function()
{
$("#pageContentDiv").hide();
setTimeout(function()
{
$("#pageContentDiv").show();
}, 0);
});
EDIT:
Found a better solution; set header div height and page div top padding to the same value:
<div data-role="page" style="padding-top: 60px">
<div data-role="header" data-position="fixed" style="height: 60px">
Hope this helps.

Related

Image in Jquery Mobile Header overlaps main content

I'm developing a Cordova project, building the user interface with jQuery Mobile (first project using any of them), and I'm having problems adding a logo image to the header.
Since it makes the header bigger than default, the header overlaps the content in the main div as in this capture:
If I navigate to other page and return to this one, then everything looks like it should:
I've read that when jQuery Mobile initializes the page, the header image is not loaded and the header is much smaller, so I've tried
this is my html for the image:
<div data-role="header" data-id="header" data-position="fixed">
<h1>
<img src="img/flycosette_logo-88cb7efa9f6acfcaf246f8523e87805d.png" alt="FlyCosette"/>
</h1>
</div><!-- /header -->
And this my css in a custom file called after jQM files:
.ui-header img {
width: 100%;
}
I've tried the approach in the quoted link:
$(window).on('load', function () {
$(this).trigger('resize');
});
but it doesn't work for me.
I've also tried placing the image inside a div, instead <h1>, and setting the code for it instead of the image, playing with several properties, but it doesn't solve the problem and the image size does not display as well as in the screencaptures...
So, any idea on how to fix it?
When you get back to the page, JQM internally triggers an event called upateLayout which probably also adapts the content positioning relative to the header. Try triggering this yourself by doing something like:
$([your_page]).trigger("updatLayout");
See if this works. Maybe you need to call it on the header or content instead of the page.
After refactoring my code, I've been trying all different solutions once again, and it turns out that the initial solution:
$(window).on('load', function () {
$(this).trigger('resize');
});
from the post: https://stackoverflow.com/a/11110607/3708095
is what finally solved my problem.
I'm calling the script with that code after the </body> tag, below all the html (not sure about how was it being called before), and now is working.
Sorry for the inconveniences.

external panel in jquery mobile 1.4 causes display bug

I thought my external panels (jQM 1.4) were working great, until I added more content to them, and now, I can see the external panel underneath my app's home page.
If they are short, it's fine, but once they reach a certain height, you can scroll down on the home (first) page and see the panel's contents.
The new docs aren't much help :/
I've tried a lot of variations... but here's a basic example that will trigger it:
<div data-role="panel" id="imExternal" data-theme="a">
<div style="height: 1200px; background: #000;">
<p>this is the panel, code is tight and outside of any containing page divs.</p>
</div>
</div>
*update: I'm specifically seeing it in my app with a popup open, and then clicking on an input field to show the Android keyboard. It seems to resize the page, which shows content from another page (external panel) underneath it.
You should enhance External widgets manually, as they don't get enhanced when page is created.
$(function () {
$("[data-role=panel]").panel();
});
Also, elements / widgets inside External panel should be enhanced as well.
$(function () {
$("[data-role=panel]").panel().enhanceWithin();
});
Actually... DON'T use popups in external panels. Ultimately, that was the root cause of this.
I solved this by setting the css height of the page in question to the window height, which prevented the underlying panel from showing below it.
$('#page').css('height', $(window).height());

How to obtain an always fixed header in jQuery Mobile?

I have implemented a fixed header in jQuery Mobile, and it's working great for the most part. When I scroll, the toolbar remains visible. When I tap the screen, the header does not disappear. Great. The only annoyance I see is that when you tap into an input field that's towards the bottom of the page, the header then reverts to position:static so it disappears. You can see that by scrolling back up to the top. Once you unfocus the input box (hit done on the keyboard), then it goes back to position:fixed. I would like it to always be visible no matter what.
<div data-role="header" data-position="fixed">
I'm using jQM 1.4.0 RC1 and in the change log it states:
- Fixed Toolbars are now an extension on the toolbar widget
Sounds relevant, but I'm not sure what exactly that means.
Thanks. :)
This actually a fix for many issues raised on fixedtoolbar widget.
Issue #4410
Issue #4724
jQM hides fixed toolbars once focus is triggered on select, textarea and select; to give more working place when screen width less than 1025.
I have tried the below solution but the results were ugly.
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script>
$(document).on("mobileinit", function() {
$.mobile.toolbar.prototype.options.hideDuringFocus = "";
});
</script>
<script src="http://code.jquery.com/mobile/1.4.0-rc.1/jquery.mobile-1.4.0-rc.1.min.js"></script>
For more details, check fixedToolbar.js widget on GitHub, go to line 243.
Demo (1)
(1) To be tested on Mobile browsers, not desktop.

Problems displaying PDF in iFrame on Mobile Safari

Within our web application we are displaying a PDF document in an iframe using the following line of code:
<iframe id="iframeContainer" src="https://example.com/pdfdoc.pdf"
style="width:100%; height:500px;"></iframe>
This works fine in all the major desktop browsers with the width of the PDF scaling to fit inside the confines of the iFrame and a vertical scroll bar to view all the pages within the document.
At the moment however I can't get the PDF to display correctly in Mobile Safari. In this instance only the top left portion of the PDF is visible without any horizontal or vertical scrollbars to see the rest of the document.
Does anybody know of I workaround for this problem in Mobile Safari?
UPDATE - MARCH 2013
After hours of searching and experimentation I can conclude that this problem is a real mess!! There are a bunch of solutions but each far from perfect. Anybody else struggling with this one I advise to refer to 'Strategies for the iFrame on the iPad Problem'. For me I need to write this one off and look for another solution for our iPad users.
UPDATE - MAY 2015
Just a quick update on this question. Recently I have started using the Google Drive viewer, which has mostly solved the original problem. Just provide a full path to the PDF document and Google will return a HTML formatted interpretation of your PDF (don't forget to set embedded=true). e.g.
https://drive.google.com/viewerng/viewer?embedded=true&url=www.analysis.im%2Fuploads%2Fseminar%2Fpdf-sample.pdf
I'm using this as a fallback for smaller viewports and simply embedding the above link into my <iframe>.
I found a new solution. As of iOS 8, mobile Safari renders the PDF as an image within an HTML document inside the frame. You can then adjust the width after the PDF loads:
<iframe id="theFrame" src="some.pdf" style="height:1000px; width:100%;"></iframe>
<script>
document.getElementById("theFrame").contentWindow.onload = function() {
this.document.getElementsByTagName("img")[0].style.width="100%";
};
</script>
<iframe
id="ifamePdf"
type="application/pdf"
scrolling="auto"
src={"https://docs.google.com/viewerng/viewer?url="+"https://example.com/pdfdoc.pdf"+"&embedded=true"}
height="600"
></iframe>
My solution for this is to use google drive on mobile and a standard pdf embed in an iframe on larger screens.
.desktop-pdf {
display: none;
}
.mobile-pdf {
display: block;
}
#media only screen and (min-width : 1025px) {
.mobile-pdf {
display: none;
}
.desktop-pdf {
display: block;
}
}
<div class="outer-pdf" style="-webkit-overflow-scrolling: touch; overflow: auto;">
<div class="pdf">
<iframe class="desktop-pdf" scrolling="auto" src="URL HERE" width="100%" height="90%" type='application/pdf' title="Title">
<p style="font-size: 110%;"><em>There is content being displayed here that your browser doesn't support.</em> Please click here to attempt to view the information in a separate browser window. Thanks for your patience!</p>
</iframe>
<iframe class="mobile-pdf" scrolling="auto" src="https://drive.google.com/viewerng/viewer?embedded=true&url=URL HERE" width="100%" height="90%" type='application/pdf' title="Title">
<p style="font-size: 110%;"><em>There is content being displayed here that your browser doesn't support.</em> Please click here to attempt to view the information in a separate browser window. Thanks for your patience!</p>
</iframe>
</div>
</div>
For using the google preview in 2021, I had to do the following. Some small adjustments to how it was posted above.
"https://drive.google.com/viewerng/viewer?embedded=true&url=" + encodeURIComponent(pdfUrl)
try pdf.js should also work inside mobile safari: https://github.com/mozilla/pdf.js/
I got the same issue. I found that by setting the focus on an input (doesn't work with div tags) the pdf is displayed.
I fix it by adding an hidden input and set the focus on it. this work around doesn't slowdown the application.
<html><head>
<script>
$(document).ready(function () {
$("#myiframe").load(function () { setTimeout(function () { $(".inputforfocus").focus(); }, 100); });
});
</script></head>
<body>
<div class="main">
<div class="level1">Learning</div>
<input type="hidden" class="inputforfocus">
<div>
<iframe src="PDF/mypdf.pdf" frameborder="0" id="myiframe" allow="fullscreen"></iframe>
</div>
</div>
</body>
</html>

Maximise div[data-role=content] in Jquery Mobile

Has anyone actually succeeded in doing this it seems like there are so many attempts on line but no one has a definite solution. I've tried plugins that a lot of people suggested but nothing is working.
I just want to have a Google Map go full dimensions (apart from header and footer) and then on another page I want a div to do the same
JQuery-Mobile content area 100% height between head and foot
In the meantime I would recommend to use iScroll [with CSS position:fixed; for header&footer in iOS5 only]
In iScroll you just wrap the content into a wrapper & scroller class, the rest is done by the script. Here's the homepage http://cubiq.org/iscroll-4 and here's some code:
<div id="content" data-role="content">
<div id="wrapper">
<div id="scroller">
your content here.
</div>
</div>
</div>
For iScroll initialization use the documentation provided on cubiq's site.
zY

Resources