Why do the pages blink/flicker after transitions in my jQuery Mobile PhoneGap app on iOS? - iphone

I have a jQuery Mobile app that I've converted to an iOS app using PhoneGap. I'm using version 1.1.0 of jQM.
I'm using "fade" transitions between pages (as I read they were less demanding).
When initially running the PhoneGap version of the app in the iPhone Simulator I was getting a flicker/flash after every page transition - as if the page was being displayed, cleared and then redisplay - all with a fraction of a second. Some thing happened when I ran it on the device.
I applied the advice in Sarah-Jane's answer to a similar question.
This fixed the problem in the simulator, but not on the actual device.
Has anyone experienced this problem, and found a solution?

This guy solved the problem - it worked for me:
http://outof.me/fixing-flickers-jumps-of-jquery-mobile-transitions-in-phonegap-apps/
CSS:
body {
/* Setting body margins to 0 to have proper positioning of #container div */
margin: 0;
}
/* #container div with absolute position and 100% width and height so it takes up whole window */
#container {
position: absolute;
width: 100%;
height: 100%;
}
JS:
$(document).one("mobileinit", function () {
// Setting #container div as a jqm pageContainer
$.mobile.pageContainer = $('#container');
// Setting default page transition to slide
$.mobile.defaultPageTransition = 'slide';
});
And wrap all your jQM pages in a single <div id="container">

Fade transition blinks mostly you should change it to slide or some other transition mode.

That might help
<meta name="viewport" content="width=device-width, user-scalable=no" />

use following code
$(document).ready(function()
{
$.mobile.defaultPageTransition = "none"
$.mobile.defaultDialogTransition = 'none';
$.mobile.useFastClick = true;
$.mobile.touchOverflowEnabled = true;
});

Related

How to get work Infinite scroll depending on div container's scroll position?

I'm looking for a infinite scroll script, but can't find one which really fits my needs. I have found one which would be great, but the problem is that the script works after the User scrolls down using the browser SCROLLBAR. Instead it should load and display more data depending on the div "scroll" position.
How can i do that? It doesn't have to be this script but it should include a mysql query function so I can implement mine easily, because I'm really a newbie in Javascript, jQuery etc. A tutorial would do it also...but can't really find one. All of them are depending on the browser's scroll position.
That's the script I'm using:
github.com/moemoe89/infinite-scroll/blob/master/index.php
I made only one modification:
news_area{ width:400px; height:95px; overflow:auto;}
Thanks in advance!
Instead of $(window).scrollTop() use any container that you would want to get it's scrolling position from, like $('.scrollable').scrollTop().
$('.scrollable').on('scroll', function(){
var $el = $(this);
$('.scrolled').text($(this).scrollTop());
if( $el.innerHeight()+$el.scrollTop() >= this.scrollHeight-5 ){
var d = new Date();
$el.append('more text added on '+d.getHours()+':'+d.getMinutes()+':'+d.getSeconds()+'<br>');
}
});
div {
height: 50px;
border: 1px solid gray;
overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Scrolled from top: <span class="scrolled">0</span></p>
<div class="scrollable">
text<br>
text<br>
text<br>
text<br>
text<br>
text<br>
</div>

Hide iPhone HTML5 video play button

I want to hide the big play button that appears by default on the <video> element
Is it possible?
I don't have any iOS device handy to test, but perhaps try this:
video::-webkit-media-controls {
display:none !important;
}
It seems Apple has changed the shadow-dom again.
In order to hide the play button control you must use the following CSS:
/* This used to work for the parent element of button divs */
/* But it does not work with newer browsers, the below doesn't hide the play button parent div */
*::-webkit-media-controls-panel {
display: none!important;
-webkit-appearance: none;
}
/* Old shadow dom for play button */
*::-webkit-media-controls-play-button {
display: none!important;
-webkit-appearance: none;
}
/* New shadow dom for play button */
/* This one works! */
*::-webkit-media-controls-start-playback-button {
display: none!important;
-webkit-appearance: none;
}
A look at the shadow DOM in Safari iOS tells me that what you want (hidding only the big central play button) is:
video::-webkit-media-controls-start-playback-button {
display: none !important;
}
The answer from Ian hides everything including text tracks (closed captions ...)
Newer iOS versions display such play button when the device is in "Low power mode".
In the video source file you can simply change
controls= "false"
For the Safari CSS, which the native browser on ios, you can also try this hacky trick
.custom-video-controls {
z-index: 2147483647;
}
Here's a link to a details discussion on managing/hiding controls on HTML 5 video
http://css-tricks.com/custom-controls-in-html5-video-full-screen/
UPDATE OCTOBER 2021
All answers are outdated for iOS 13, 14, and 15. It appears because iOS low power mode prevents autoplay on all videos in the browser by default (to save power).
The best way to remove the annoying play button is to remove the autoplay tag on any video element and start playing the video when there is any user interaction.
React example below:
<video ref={playerRef} playsInline >
let playVideo = (event) => {
if (playerRef.current) {
playerRef.current.play()
}
}
Sidenote: the play button is hidden in a shadow dom that I am unable to figure out how to hide with external CSS modifications or even JS. If anyone has any ideas on how to hide a shadow dom element then that would be a better solution.
Based on Ian's answer
video::-webkit-media-controls {
opacity: 0;
}
This will hide all controls. Good for background videos that won't autoplay.
Today #2017 in iOS 10 this works:
.video-background::-webkit-media-controls-panel,
.video-background::-webkit-media-controls-start-playback-button {
display: none !important;
}
For webapps.
Works iOS 10.3 iPhone7 & Safari 10.1 on Mac as well. Thx to previous contributors.
I had also the issue that the element does not contain any "control" attribute at all.
'<style type="text/css">'+
'*::-webkit-media-controls-panel {'+
' display: none!important;'+
' -webkit-appearance: none;'+
' }'+
/* Old shadow dom for play button */
'*::--webkit-media-controls-play-button {'+
'display: none!important;'+
'-webkit-appearance: none;'+
'}'+
/* New shadow dom for play button */
/* This one works */
'*::-webkit-media-controls-start-playback-button {'+
'display: none!important;'+
' -webkit-appearance: none;'+
'}'+
+'</style>'
Try this:
video {
&::-webkit-media-controls {
display:none !important;
}
&::-webkit-media-controls-start-playback-button {
display: none!important;
-webkit-appearance: none;
}
}
Update:
IOS 13.*
video::slotted::-webkit-media-controls-container{
display:none !important;
visibility: hidden!important;
opacity: 0 !important;
-webkit-appearance: none !important;
}
IOS 14
changed selector to
:host::shadow::-webkit-media-controls-container{/* hide the element */}
helpful resource:
html5rocks shadow dom 201
As of 20 Oct 2022,
My solution was to remove autoplay from the video element and use HTMLMediaElement.play() on page load. The promise returned from play() will catch any issues with playing the video, else the video will play as usual. My implementation in React looks like this:
useEffect(() => {
ref &&
ref.current
.play()
.then(() => {})
.catch((err) => {
// Video couldn't play, low power play button showing.
});
}, []);
This should be a relief from having to deal with the inconsistent Shadow DOM properties.
Resources:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play
You can't remove the play button. This video placeholder always appears as the doc says :
iPhone Video PlaceHolder. But maybe you can detect you're on an iphone and display an image with a link to your video instead of the video tag.
<img src="yourposter.png"/>
The video will be launched in a player just as a video tag.
According to this answer, in Google Chrome we can hide the big play button like this:
video::-webkit-media-controls-overlay-play-button {
display: none;
}
That might be useful if you want to hide it on Android as well as on iOS.
video::-webkit-media-controls { display:none !important; }
Didn't work for me on iOS, but
*::-webkit-media-controls-panel {
display: none!important;
-webkit-appearance: none;
}
/* Old shadow dom for play button */
*::--webkit-media-controls-play-button {
display: none!important;
-webkit-appearance: none;
}
/* New shadow dom for play button */
/* This one works */
*::-webkit-media-controls-start-playback-button {
display: none!important;
-webkit-appearance: none;
}
Worked perfect!
Yes you can do this! The trick is to "hide" the video controls, by not adding the "controls" attribute to your video tag. Then you let it be dynamically added a few seconds after the video starts to play, by appending the "controls" property to the tag using Javascript. Simply set the value to "controls" and it will dynamically appear in the DOM... as if you had added the controls to your video tag's HTML. Adjust the timer as needed.
<video id="some-video-id" src="some-video-url" poster="some-thumbnail-url" />
Start the Video
<script type="text/javascript">
var oVideoTag = document.getElementById('some-video-id');
var oLink = document.getElementById('startVideoLink');
if (oLink && oVideoTag) {
oLink.addEventListener('click',function(e) {
oVideoTag.play();
setTimeout(function() {
oVideoTag.controls = 'controls';
},2500);
},false);
}
</script>

IOS can't click links in fixed footer until after scroll? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Mobile Webkit reflow issue
I have been trying to figure this out. I have a fixed footer on ios with 4 links in it. Their are also 6 links under it that should not be clickable since they are below. However on ios when unless you scroll the page first the links on the fixed footer do not work and it instead clicks the link below it. After you scroll the slightest bit it works fine. I hope i explained this clearly enough.
You can see an example of it here:
amstar.m77950.com
(view on iphone)
I tried applying z-index to basically every element on the page to see if there was a fix. I also used jquery to make sure that the z-index was being applied onLoad (although it should have been anyway).
Yet i still cannot get the links in the footer to work until after you scroll the page.
Any help on this is much apprceiated. Thanks.
Here is the css i am applying to the element:
.alertsBarClass {
background: url("dynamicimage.aspx?id=21844") no-repeat scroll 0 0 #EA7E25;
border-bottom: medium none;
bottom: 0;
display: block;
position: fixed;
width: 100%;
z-index: 1000;
}
There are known issues with Position:Fixed in iOS 5.1 and anchors/links and scrolling. See the following bug #10301184, #10810232.
One thing that can help...sometimes... is to put cursor:pointer in the divs surrounding your links.
Had the same issue. Fixed it by scrolling up and down on orientation change using javascript.
I added the following script to each page, its ugly but it works:
<script type=\"application/x-javascript\">
addEventListener('load', function() { setTimeout(orientationChange, 0);}, false);
var currentWidth = 0;
function orientationChange()
{
if (window.innerWidth != currentWidth)
{
currentWidth = window.innerWidth;
var orient = (currentWidth == 320) ? \"profile\" : \"landscape\";
window.scrollTo(0, 0);
setTimeout(function() {window.scrollTo(0, 1); }, 250);
document.body.setAttribute('orient', orient);
}
}
setInterval(orientationChange, 400);
</script>

position: fixed doesn't work on iPad and iPhone

I have been struggling with fixed positioning in iPad for a while. I know iScroll and it does not always seem to work (even in their demo). I also know that Sencha has a fix for that, but I couldn't Ctrl + F the source code for that fix.
I am hoping that someone may have the solution. The problem is that fixed positioned elements do not get updated when the user pans down/up on an iOS powered mobile Safari.
A lot of mobile browsers deliberately do not support position:fixed; on the grounds that fixed elements could get in the way on a small screen.
The Quirksmode.org site has a very good blog post that explains the problem: http://www.quirksmode.org/blog/archives/2010/12/the_fifth_posit.html
Also see this page for a compatibility chart showing which mobile browsers support position:fixed;: http://www.quirksmode.org/m/css.html
(but note that the mobile browser world is moving very quickly, so tables like this may not stay up-to-date for long!)
Update:
iOS 5 and Android 4 are both reported to have position:fixed support now.
I tested iOS 5 myself in an Apple store today and can confirm that it does work with position fixed. There are issues with zooming in and panning around a fixed element though.
I found this compatibility table far more up to date and useful than the quirksmode one:
http://caniuse.com/#search=fixed
It has up to date info on Android, Opera (mini and mobile) & iOS.
Fixed positioning doesn't work on iOS like it does on computers.
Imagine you have a sheet of paper (the webpage) under a magnifying glass(the viewport), if you move the magnifying glass and your eye, you see a different part of the page. This is how iOS works.
Now there is a sheet of clear plastic with a word on it, this sheet of plastic stays stationary no matter what (the position:fixed elements). So when you move the magnifying glass the fixed element appears to move.
Alternatively, instead of moving the magnifying glass, you move the paper (the webpage), keeping the sheet of plastic and magnifying glass still. In this case the word on the sheet of plastic will appear to stay fixed, and the rest of the content will appear to move (because it actually is) This is a traditional desktop browser.
So in iOS the viewport moves, in a traditional browser the webpage moves. In both cases the fixed elements stay still in reality; although on iOS the fixed elements appear to move.
The way to get around this, is to follow the last few paragraphs in this article
(basically disable scrolling altogether, have the content in a separate scrollable div (see the blue box at the top of the linked article), and the fixed element positioned absolutely)
"position:fixed" now works as you'd expect in iOS5.
position: fixed does work on android/iphone for vertical scrolling. But you need to make sure your meta tags are fully set. e.g
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
Also if you're planning on having the same page work on android pre 4.0, you need to set the top position also, or a small margin will be added for some reason.
I had this problem on Safari (iOS 10.3.3) - the browser was not redrawing until the touchend event fired. Fixed elements did not appear or were cut off.
The trick for me was adding transform: translate3d(0,0,0); to my fixed position element.
.fixed-position-on-mobile {
position: fixed;
transform: translate3d(0,0,0);
}
EDIT - I now know why the transform fixes the issue: hardware-acceleration. Adding the 3D transformation triggers the GPU acceleration making for a smooth transition. For more on hardware-acceleration checkout this article: http://blog.teamtreehouse.com/increase-your-sites-performance-with-hardware-accelerated-css.
now apple support that
overflow:hidden;
-webkit-overflow-scrolling:touch;
Fixed Footer (here with jQuery):
if (navigator.platform == 'iPad' || navigator.platform == 'iPhone' || navigator.platform == 'iPod' || navigator.platform == 'Linux armv6l') {
window.ontouchstart = function() {
$("#fixedDiv").css("display", "none");
}
window.onscroll = function() {
// 45 is the height of the Footer
var iPadPosition = window.innerHeight + window.pageYOffset-45;
$("#fixedDiv").css("position", "absolute");
$("#fixedDiv").css("top", iPadPosition);
$("#fixedDiv").css("display", "block");
}
}
In the CSS file should stand:
#fixedDiv {
position: fixed;
bottom: 0;
height: 45px;
...
}
Avoid on the same box using transform:--- and position:fixed. Element will stay in position:static if there is any transform.
I ended up using the new jQuery Mobile v1.1: http://jquerymobile.com/blog/2012/04/13/announcing-jquery-mobile-1-1-0/
We now have a solid re-write that provides true fixed toolbars on the
a lot of popular platforms and safely falls back to static toolbar
positioning in other browsers.
The coolest part about this approach is that, unlike JS-based
solutions that impose the unnatural scrolling physics across all
platforms, our scrolling feels 100% native because it is. This means
that scrolling feels right everywhere and works with touch, mousewheel
and keyboard user input. As a bonus, our CSS-based solution is super
lightweight and doesn’t impact compatibility or accessibility.
using jquery i am able to come up with this. it doesnt scroll smooth, but it does the trick. you can scroll down, and the fixed div pops up on top.
THE CSS
<style type="text/css">
.btn_cardDetailsPg {height:5px !important;margin-top:-20px;}
html, body {overflow-x:hidden;overflow-y:auto;}
#lockDiv {
background-color: #fff;
color: #000;
float:left;
-moz-box-shadow: 0px 4px 2px 2px #ccc;-webkit-box-shadow: 0px 4px 2px 2px #ccc;box-shadow:0px 4px 2px 2px #ccc;
}
#lockDiv.stick {
position: fixed;
top: 0;
z-index: 10000;
margin-left:0px;
}
</style>
THE HTML
<div id="lockSticky"></div>
<div id="lockDiv">fooo</div>
THE jQUERY
<script type="text/javascript">
function sticky_relocate() {
var window_top = $(window).scrollTop();
var div_top = $('#lockSticky').offset().top;
if (window_top > div_top)
$('#lockDiv').addClass('stick')
else
$('#lockDiv').removeClass('stick');
}
$(function() {
$(window).scroll(sticky_relocate);
sticky_relocate();
});
</script>
Finally we want to determine if the ipod touch in landscape or portrait mode to display accordingly
<script type="text/javascript">
if (navigator.userAgent.match(/like Mac OS X/i)) {
window.onscroll = function() {
if (window.innerWidth > window.innerHeight) {
//alert("landscape [ ]");
document.getElementById('lockDiv').style.top =
(window.pageYOffset + window.innerHeight - 268) + 'px';
}
if (window.innerHeight > window.innerWidth) {
//alert("portrait ||");
document.getElementById('lockDiv').style.top =
(window.pageYOffset + window.innerHeight - 418) + 'px';
}
};
}
</script>
The simple way to fix this problem just types transform property for your element. and it will be fixed.
.classname{
position: fixed;
transform: translate3d(0,0,0);
}
Also you can try his way as well this is also work fine.
.classname {
position: -webkit-sticky;
}
Even though the CSS attribute {position:fixed;} seems (mostly) working on newer iOS devices, it is possible to have the device quirk and fallback to {position:relative;} on occasion and without cause or reason. Usually clearing the cache will help, until something happens and the quirk happens again.
Specifically, from Apple itself Preparing Your Web Content for iPad:
Safari on iPad and Safari on iPhone do not have resizable windows. In
Safari on iPhone and iPad, the window size is set to the size of the
screen (minus Safari user interface controls), and cannot be changed
by the user. To move around a webpage, the user changes the zoom level
and position of the viewport as they double tap or pinch to zoom in or
out, or by touching and dragging to pan the page. As a user changes
the zoom level and position of the viewport they are doing so within a
viewable content area of fixed size (that is, the window). This means
that webpage elements that have their position "fixed" to the viewport
can end up outside the viewable content area, offscreen.
What is ironic, Android devices do not seem to have this issue. Also it is entirely possible to use {position:absolute;} when in reference to the body tag and not have any issues.
I found the root cause of this quirk; that it is the scroll event not playing nice when used in conjunction with the HTML or BODY tag. Sometimes it does not like to fire the event, or you will have to wait until the scroll swing event is finished to receive the event. Specifically, the viewport is re-drawn at the end of this event and fixed elements can be re-positioned somewhere else in the viewport.
So this is what I do: (avoid using the viewport, and stick with the DOM!)
<html>
<style>
.fixed{
position:fixed;
/*you can set your other static attributes here too*/
/*like height and width, margin, etc.*/
}
.scrollableDiv{
position:relative;
overflow-y:scroll;
/*all children will scroll within this like the body normally would.*/
}
.viewportSizedBody{
position:relative;
overflow:hidden;
/*this will prevent the body page itself from scrolling.*/
}
</style>
<body class="viewportSizedBody">
<div id="myFixedContainer" class="fixed">
This part is fixed.
</div>
<div id="myScrollableBody" class="scrollableDiv">
This part is scrollable.
</div>
</body>
<script type="text/javascript" src="{your path to jquery}/jquery-1.7.2.min.js"></script>
<script>
var theViewportHeight=$(window).height();
$('.viewportSizedBody').css('height',theViewportHeight);
$('#myScrollableBody').css('height',theViewportHeight);
</script>
</html>
In essence this will cause the BODY to be the size of the viewport and non-scrollable. The scrollable DIV nested inside will scroll as the BODY normally would (minus the swing effect, so the scrolling does stop on touchend.) The fixed DIV stays fixed without interference.
As a side note, a high z-index value on the fixed DIV is important to keep the scrollable DIV appear to be behind it. I normally add in window resize and scroll events also for cross-browser and alternate screen resolution compatibility.
If all else fails, the above code will also work with both the fixed and scrollable DIVs set to {position:absolute;}.
In my case, it was because the fixed element was being shown by using an animation. As stated in this link:
in Safari 9.1, having a position:fixed-element inside an animated element, may cause the position:fixed-element to not appear.
Had the same issue on Iphone X. To fixed it I just add height to the container
top: 0;
height: 200px;
position: fixed;
I just added top:0 because i need my div to stay at top
This might not be applicable to all scenarios, but I found that the position: sticky (same thing with position: fixed) only works on old iPhones when the scrolling container is not the body, but inside something else.
Example pseudo html:
body <- scrollbar
relative div
sticky div
The sticky div will be sticky on desktop browsers, but with certain devices, tested with: Chromium: dev tools: device emultation: iPhone 6/7/8, and with Android 4 Firefox, it will not.
What will work, however, is
body
div overflow=auto <- scrollbar
relative div
sticky div
This seems to work for Ionic5 on iPhone 6 Plus on iOS 12.4.2
.large_player {
float: left;
bottom: 0;
width: 100%;
position: fixed;
background-color: white;
border-top: black 1px solid;
height: 14rem;
z-index: 100;
transform: translate3d(0,0,0);
}
The transform tag makes it work, but it also seems a little clunky in how the scroll works, it is seems to redraw the 'on top' element after it's all moved and sort of resets and makes it jump a little.
Or, you could also use this tag option as well, position: -webkit-sticky;, but then you won't get, or may run in to trouble with WPA/browser or Android builds while having to do version checking and have multiple CSS tags.
.large_player {
float: left;
bottom: 0;
width: 100%;
position: -webkit-sticky;
background-color: white;
border-top: black 1px solid;
height: 14rem;
z-index: 100;
}
I don't know at what point it was fixed, but later iOS phones work without the transform tag. I don't know if it's the iOS version, or the phone.
As most iOS devices are usually on the most recent iOS version, it's pretty safe with go with a weird work around - such as using the transform tag, rather than building in a quirky detection routine for the sake of less than 1% of users.
Update:
After thinking about this answer further, this is just another way of doing this by platform for ionic5+:
.TS
import {Platform } from '#ionic/angular';
constructor(public platform: Platform) {
// This next bit is so that the CSS is shown correctly for each platform
platform.ready().then(() => {
if (this.platform.is('android')) {
console.log("running on Android device!");
this.css_iOS = false;
}
if (this.platform.is('ios')) {
console.log("running on iOS device!");
this.css_iOS = true;
}
if (this.platform.is('ipad')) {
console.log("running on iOS device!");
this.css_iOS = true;
}
});
}
css_iOS: boolean = false;
.HTML
<style *ngIf="css_iOS">
.small_player {
position: -webkit-sticky !important;
}
.large_player {
position: -webkit-sticky !important;
}
</style>
<style>
.small_player {
float: left;
bottom: 0;
width: 100%;
position: fixed;
background-color: white;
border-top: black 1px solid;
height: 4rem;
z-index: 100;
/*transform: translate3d(0,0,0);*/
}
.large_player {
float: left;
bottom: 0;
width: 100%;
position: fixed;
background-color: white;
border-top: black 1px solid;
height: 14rem;
z-index: 100;
/*transform: translate3d(0,0,0);*/
}
</style>

JQTouch link with no animation

Im building a web app using JQTouch and have been very impressed with it so far! I'm currently having a little problem in that I now need to link between certain parts of my site with NO ANIMATION. Reason for this is that I'm adding a 'tabbar' at the bottom of my page and in keeping with the whole iPhone feel would like to link to other sections with no animation. From what I've seen so far, the dissolve effect seems the closest I guess.
So just to clear up I dont want to disable all animations, only the four in my tabbar.
Thanks!
You can probably add a custom animation which does nothing. See this page.
So, if you want no animation you may want something like this (i.e. leaving out #webkit-keyframes):
<script>
$(function(){
jQT.addAnimation({
name: 'noanimate',
selector: '.noanimate'
});
});
</script>
<style>
.noanimate.in {
-webkit-animation-name: dontmove;
z-index: 0;
}
.noanimate.out {
-webkit-animation-name: noanimateout;
z-index: 10;
}
.noanimate.out.reverse {
z-index: 0;
-webkit-animation-name: dontmove;
}
.noanimate.in.reverse {
z-index: 10;
-webkit-animation-name: noanimatein;
}
</style>