White screen appears before showing a form page in Phonegap application - jquery-mobile

In my phonegap application I have a page that contains form elements. The problem is that when I navigate from home page to this page (form page) a white screen appears and then the form page appears. This screen occurs only once, when I open the form page after launching the app. This problem happens only for the form page, since the other pages in the application are showed directly.
I have set all transitions to none in my app, and tried to use fastclick, but nothing worked for me! How can I solve this problem?
Any help would be greatly appreciated.
Home page .js
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady ()
{
setTimeout(function(){ navigator.splashscreen.hide();} ,3000);
$('#GoToForm_BTN').on('click', function(){
$(this).attr('href','formPage.html');
} );
I have used this code in my css file but the problem remains
.ui-page {
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
overflow: hidden;
}
a, input, button {
-ms-touch-action: none !important;
}
*{
-webkit-transform: translateZ(0);
-webkit-transform:translate3d(0,0,0);
}

Without seeing any code it is difficult to locate the exact problem, if indeed there is a one. I believe that the problem can be located at the loading time of your application. If it is a multipage application (one html file), and depending on the size of the DOM tree created, it is natural that you are seeing this white screen. The DOM hasn't been fully loaded so you see a blank screen. The best thing you can do is to show a loading image when your application launches, and remove it when the page is ready.

Related

Anchor links in HTML file don't work in iframe after iOS fix

Ok, so I am working on a javascript application. One feature is a help page for the application. The way I am trying to do it is to have a button that opens the help page - .html - in an iframe contained within a container div.
This works just fine, but I run into the well-known issue of iframes not scrolling in iOS(i.e. on iPads and iPhones).
There is a common fix for this, which involves setting overflow rules in the css for the container div.
So the initial CSS is something like:
#iframeContainer {
position:absolute;
left:0px;
top:0px;
width: 750px;
}
#iframeContainer iframe {
{
width:100%;
height: 600px;
}
and the css with the iOS fix is something like:
#iframeContainer {
position:absolute;
left:0px;
top:0px;
width: 750px;
height: 600px;
-webkit-overflow-scrolling: touch;
overflow: scroll;
}
#iframeContainer iframe {
{
width:100%;
height: 12000px;
}
The overflow rules are added to the css for the container, but in order to work, you have to set a height on the container. You also have to adjust the height of the iframe itself. If I leave it at its initial 600px, it never overflows the container div and there is no scrolling. If I don't set any height at all on the iframe, it hardly shows anything at all. So I have to set the iframe's height to contain all of the contents of the HTML file, which comes to 12000px.
All of this works, and the scrolling issue on iOS is fixed. But here's where I run into the issue in question.
The HTML page being loaded into the iframe has within it a bunch of anchor links that link to other places on the same page. After applying the iOS fix, those anchor links no longer work at all. Nothing happens when they're clicked.
I am reasonably sure that the reason is because when I set the iframe's height to 12000px, the HTML page behaves as though it is all displayed on one page, in which event, nothing happening is the appropriate behavior for anchor links.
So I think understand what is going on, and I'm just wondering if anyone has any ideas on how to make the anchor links work while keeping the iOS fix in tact. If I decrease the iframe's height to make the anchor links work, then less and less of the HTML page will show up within the iframe. If I remove the iOS fix all together, the anchor links will work but the scrolling won't work on iOS.
Open to anything. For the time being, I've abandoned the idea and the 'Help' button just opens the HTML page in a new tab/window.

Overflow-y not working on iPad

I have a panel with a scrollable content. It works fine in every browser & device except for iPad (no matter what browser I use on the iPad).
I have a panel-container and a panel-slide
.panel-container {
position: relative;
width:100%;
height:100%;
z-index:1;
}
.panel-slide {
width:90%;
height: 90%;
display:block;
position: absolute;
z-index: 2;
background-color: white;
overflow-y: scroll;
overflow-x: hidden;
}
The panel-slide contains a lot of content, so I get the scroll bar. However I can't scroll on iPad.
I have googled the problem and have tried the -webkit-overflow-scrolling: touch, but I can't seem to get to the bottom of it.
What is there to do?
I don't know if this will be helpful, but I had a similar issue, and this is how I resolved it.
My issue:
My page has a popup element that gets populated by AJAX with a list of clickable links. When this element is pre-populated with the rest of the page (some pages required the list to be visible from initial page load), it worked fine. But, when I opened the element and populated the list, as mentioned above, using AJAX, the list would not scroll on iOS.
The problem, as far as I could tell:
In the interim between clicking the button to open the list and when the server responded with the populated list, I had the element show some simple text saying "Loading...". I found that when this was removed, and the element was already populated from the page load, it would work fine. It seemed that as long as there were already contents in the list with a height greater than the containing element, it would be scroll-able when the list populated.
My resolution:
What I did was to take the simple text in the interim from "Loading..." and to wrap it in a div that would prompt scrolling, like such: "<div style='height:1000px;'>Loading...</div>", and that seemed to work for me.
Again, I hope that this can help someone, or if not then perhaps someone with a little more skill than myself may be able to tell us why this might have worked.
There are no scrollbars in any of the iPhone OS. Use 2 fingers to scroll. They use gestures and not mouse scrolls so you are unable to achieve this without hacks.
It maybe worth looking at http://iscrolljs.com/

Turbolinks/Fastclick - Touch event 'passes through' to the next page when using the transition cache

I'm using Turbolinks 3.0 on iOS with Fastclick to remove the 300ms iOS delay, with the transition cache enabled. This provides a really great/instant experience with Rails on mobile devices.
I have a link on both pages in the same place, and when I press the link on one page, fastclick+turbolinks loads the next page instantly - but the event passes through to the next page and the link on that page gets clicked too, triggering both links and navigating pages twice.
The event will actually pass through to anything thats in the same place (if I click a link and a form input is on the same place on the next page loaded, it will focus on the input).
I can actually do a 'faster tap' with my finger to prevent it from happening. Its only when the tap is more sluggish (it lasts longer) that it happens.
Any help or insight would be greatly appreciated!
After tons of depressing debugging and thinking over the past few days, this solution seems to work (but is very hack-ish):
JS:
$(document).on("page:restore", function() {
$("body").prepend("<div id='ghost-blocker' onclick='return false;'></div>");
setTimeout(function() {
$("#ghost-blocker").remove();
}, 300);
});
CSS:
#ghost-blocker {
position: absolute;
left: 0;
right: 0;
height: 100%;
width: 100%;
z-index: 999;
}
I basically debugged all the callbacks with alerts and saw that the last thing that happened after loading the page from the cache but before the ghost click fired was the page:restore function. I made a blocker div that covers the whole screen and cancels out any click event, then removed it 300ms later. This does the job, albeit sloppily. The page:restore callback is also a great time to reset the page in any other way that you need, such as resetting loader images that were left over (I'm using ladda).
I'm now going to try to dive deeper and attempt to catch the ghost click event and prevent it from happening instead of manipulating the DOM with a whole div. If anyone has any insight on how to do this, I'd love to hear.

How might one force-show the mobile Safari bottom nav bar to show programmatically?

I have a fixed button for a CTA (call to action) at the bottom of my web page. Scrolling down the page on newer version of iOS, mobile Safari hides the bottom navigation bar (with back, forward, share, bookmark, and new tab buttons). If you click on the CTA button, instead of executing that action, mobile Safari shows the bottom nav bar.
As a solution, I was looking to alway force-show the bottom nav bar. Is there a way of doing this? Both Jack Threads when viewed on mobile, and Thread Flip's mobile site are able to pull this off when viewing an individual item.
I'm unable to reverse engineer this so far. Does anyone know how the force-show is accomplished?
Related to:
Buttons aligned to bottom of page conflict with mobile Safari's menu bar and
Prevent Mobile Safari from presenting toolbar when bottom of viewport is tapped
I think I may have found an answer. Setting your content to have the following styles:
height: 100% (allows content to fill the viewport and go beyond the
bottom)
overflow-y: scroll (allows you to scroll below the viewport;
the default value is visible)
-webkit-overflow-scrolling: touch (to smooth any scroll behavior)
appears to force the iOS menu in Safari to always appear. That way, button clicks will actually work instead of opening up the Safari menu.
Unfortunately, you have to pair this CSS with JavaScript browser detection because it messes up the scrolling on iOS Chrome (also webkit). There's no way to target all versions of iOS Safari only using only CSS.
My answer is, don't try.
Whilst Jon Catmull's answer technically does force the browser to retain the bottom toolbar. In trials I've experienced a massive performance drop following that setup.
An example of this is with https://www.contiki.com/uk/en, the toolbar appears permanently but the performance loss is noticeable between Chrome and Safari.
After investigating other websites it seems that the world has just accepted that this double-click is a necessary evil.
https://www.bbc.co.uk/news, breaking news appears at the bottom of the browser, if the ui is minimised, the first click returns the bottom toolbar, the second click goes through to the article.
amazon, ebay etc the toolbar is minimised as per the browser defaults. Any clicks to links in the bottom ~30 pixels enable the toolbar.
Whilst there are technical solutions in other answers here, I don't think the double click compares to the performance loss
I'm pasting in a solution mentioned at https://benfrain.com/the-ios-safari-menu-bar-is-hostile-to-web-apps-discuss/#comment-119538 in relation to how this is done for https://app.ft.com:
The trick was adding height: 100% to html, and body, and anywhere in
the css where it was using 100vh. No js browser detection needed as it
causes no quirks in iOS Chrome, Safari fullscreen, or on Android
browsers.
I'm having this same issue. We're working to implement a bottom navigation on our site and safari is giving us problems because tapping the bottom of the screen opens Safari's bottom nav, forcing users to click twice. The best solution we've come up with has been to add a 44px space below the navigation which looks really bad. It would be nice if I could force safari's navigation to stay open so it could fill that space instead of an essentially useless empty block.
I believe the height: 100% is the way to go. It seems this seems to make Safari think that it might as well show the bar as no content is trying to go behind it, and then you add scroll within you 100% height element.
My issue was different as my button was in a fixed position modal, I didn't want the Safari bottom nav to show all the time but when my mobile filter nav opened it needed to be shown.
Essentially applying the code below (e.g. on menu-open class). and then positioning menu as position: fixed and height: 100%
html.menu-open {
height: 100%;
body {
position: fixed;
width: 100%;
top: 0px;
overflow: hidden;
}
}
.menu {
position: fixed;
height: 100%;
width: 100%;
overflow: auto;
}
working example here:
https://www.electronicsadvisor.com/products/51/washing-machines-tumble-dryers
Open link
scroll down to hide safari bottom nav
click the filters button near the top of screen
The Filter menu will open and force the safari nav open.
Screenshots from example:
Before the filter button clicked:
Then when opening nav with js I apply styles above and the nav is forced open
Theres a better solution to this problem(i think). I check the windows's innerHeight on pageload. On scroll, if the height increases at least 50px, i can raise the button 25px. 25px appears to be the sweet-spot for this, you need to touch the very bottom of the button to show the toolbar. Here is a live demo and the code: https://visztpeter.me/demos/ios.html
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Fix tap for button at the bottom in iOS Safari when the toolbar is gone</title>
<style type="text/css">
div {
margin:20px;
height:2000px;
background:gray
}
button {
position:fixed;
bottom:0;
left:0;
right:0;
height:48px;
background:blue;
border:none;
transition: all ease 0.2s;
}
.ios-toolbar-gone button {
transform: translateY(-25px);
}
</style>
</head>
<body>
<div></div>
<button></button>
<script>
var baseWindowHeight = Math.max(window.innerHeight);
var classAdded = false;
var documentBody = document.body;
document.addEventListener('scroll', function(e){
var newWindowHeight = Math.max(window.innerHeight);
if(newWindowHeight-50 > baseWindowHeight) {
if (! documentBody.classList.contains("ios-toolbar-gone")) {
documentBody.classList.add("ios-toolbar-gone");
}
} else {
if (documentBody.classList.contains("ios-toolbar-gone")) {
documentBody.classList.remove("ios-toolbar-gone");
}
}
});
</script>
</body>
</html>

jQuery Mobile blinking at page transitions on iPad

I have a web app built with jQuery Mobile that works fine when using it in Safari on an iPad. However, when you add it to the home screen to use it as a standalone app (with the browser navigation removed by , then the page transitions "blink" quickly after each page transition.
I have Googled on this and found that blinking was considered a bug a long time ago, and by now should be fixed. And it seems to be in Safari, but not as standalone from home screen. Does anyone know what is causing this and how to fix it?
Does it have anything to do with the fact that the navigation bar is not there? It works fine as standalone on iPhone though, it's only on the iPad that it occurs...
I would accept as an answer even if someone can show me that this is a known bug (not one of the old bugs that have already been fixed, where it flickered even in Safari mode) or if someone has inside knowledge about that (no one is answering my question at the jQuery forum either...). But of course I would love it if someone actually had a workaround for the problem!
i had exactly the same problem
http://mailinglist-archive.com/rhomobile/2011-08/00656-Re+rhomobile+page+views+and+transitions mentions something that worked for me.
<style>
/*** patch for jquerymobile page flicker that was happending ***/
.ui-page {
-webkit-backface-visibility: hidden;
}
</style>
I still get the flicker in the toolbar, so I converted my tool bar to :
<ul data-theme="b" data-role="listview" style="margin-top: 0;">
<li data-role="list-divider">Your text goes here</li>...
I was nervous about commenting out focus, but a google search found the following CSS that seems to work:
.ui-page * {
-webkit-transform: rotateY(0deg);
-moz-transform: rotateY(0deg);
transform: rotateY(0deg);
}
Original link: https://github.com/jquery/jquery-mobile/issues/2856
I was only having a problem with the slide transition (even reverse slide worked fine.
JQ 1.7.1
JQM 1.0.1
PhoneGap 1.5.0
Revision: It should be noted that the discussion below was mitigated with the release of iOS 5.0. It can be a partial influencing factor for anyone who hasn't upgraded but if you're running 5.0, Nitro is ever present. http://arstechnica.com/apple/news/2011/06/ios-5-brings-nitro-speed-to-home-screen-web-apps.ars
--original answer--
Apple introduced the Nitro javascript engine into the Safari browser. However, they only installed it on the browser, not in the UIWebView (which is what you get when you run form the home screen or embedded in an application like PhoneGap.
There has been some speculation if this performance boost was omitted on purpose. http://www.mobilexweb.com/blog/apple-phonegap-html5-nitro.
So, if it seems like it's actually performing slowly... that's cause it really is. It's not using the Nitro engine.
Adding this line
<style>
/*** patch for jquerymobile page flicker that was happending ***/
.ui-page {
-webkit-backface-visibility: hidden;
}
</style>
helped me.
I fixed it with:
<meta id="viewPortId" name="viewport" content="width=device-width; user-scalable=no" />
This only partially works for me:
<style>
body .ui-page
{
height: 100% !important;
-webkit-backface-visibility: hidden;
}
input { outline: none; }
</style>
$(document).bind("mobileinit", function () {
$.mobile.defaultPageTransition = "none";
});
Which prevent's flickering and whitespace at the bottom of the page but notice that transitions are turned off.
Also, id's are not being used more than once which I can verify with:
// an id used more than once??
var ids = new Array();
$.each($("[id]"), function () {ids.push($(this).attr("id"));});
var matches, val1;
for (var i = 0; i < ids.length; i++) {
matches = 0;
val1 = new RegExp(ids[i], "i");
for (var i2 = 0; i2 < ids.length; i2++) {
if (ids[i].length == ids[i2].length && val1.test(ids[i2]) == true)
matches++;
}
if (matches > 1)
alert("This id was used more than once: " + ids[i]);
}
Have also tried:
$.extend($.mobile, {
metaViewportContent: "width=device-width, height=device-height, minimum-scale=1, maximum-scale=1"
});
And loading the page into the DOM and only once that is complete doing the transition as so:
var promise = $.mobile.loadPage(url, {
pageContainer : $("body")
});
promise.done(function () {
var newPage = $("body [data-role='page']:last").attr("id");
$.mobile.changePage($("#" + newPage));
});
I'm still getting the flickering on page transitions.
the answer.... jquery mobile page flicker
Unfortunately, none of the suggestions actually solved the problem, at least not for me. However, finally it has been fixed in the latest stable version of jQuery mobile (1.1.0), so the problem is finally gone! I just had to go in and change the global transition back to slide, because they set it to fade:
$(document).bind("mobileinit", function () {
$.extend($.mobile, {
defaultPageTransition: 'slide'
});
});
Hope this helps someone else who perhaps hadn't noticed the update.
It seems that the following META tag solves the issue:
<meta id="viewPortId" name="viewport" content="width=320; user-scalable=no" />
It is a known bug. See the article in the seaside mailing list.
Rolf van der Vleuten noticed:
flickering can occur when using the same #id more than once in a page,
which is not unlikely when you are using the one page template method. so
be sure to not use #id's more than once.
I don't know why this happens, but I found out that when my first page had
an element that is outlined by default, flickering would occur, this was
fixed by adding:
input {
outline: none;
}
From the currently open issue, "Slide page transition causes screen repaint on iOS 5 chromeless", the recommendation is to comment out pageTitle.focus() from the reFocus function.
This however did not solve my problem. I found it necessary to remove both pageTitle.focus() and page.focus(), basically the entire function.
This issue (and specifically the change to the reFocus function) is also mentioned in issue 2474. It is a fix for iOS4 that did not solve my iOS5 iPad problem.
This seems to be a very very strange bug.I tried to fixed it.But failed.Finally I try to add some code to my project to avoid this issue.
If you deep into jquery mobile's page transition you would know his principle.
It loads another page's (the page you want to go) body into an element such as : .
I just add an wrapper outside of this element and make a setTimeout to delay showing this page.
I made a phonegap app in iPhone 4(ios5) and can't fix this issue.Just pray that jquery mobile team would fix this bug quickly.After spending a few days on this problem I just wanna fuxk jqm...
This only worked partially for me
<style>
body .ui-page
{
height: 100% !important;
-webkit-backface-visibility: hidden;
}
input { outline: none; }
</style>
for data transition "flip" it worked but not for "slide"

Resources