I'm developing a PhoneGap + JSmobile + html5 app for iOS and Android. I'd like to force the landscape orientation for same pages. I'm trying to find a solution but I can't do it.
Is it possible at all?
I found a post where someone says to use a trick in CSS to rotate the #div:
#ID {
-webkit-transform:rotate(90deg); /* Safari and Chrome */
}
this trick rotates the page but it is rendered with with a border on the left and right side.
i found a solution:
$(document).on('pagebeforeshow', '#ID',function() {
setTimeout(function() {
$('head').append( '<meta name="viewport" content="width=device-height, height=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;">' );
}, 200);
});
the timeout is to prevent strange change in the prev page ;)
Related
I'm getting puzzled by this..
I have this piece of code:
<a href=" #/products/{{product.id}}" ng-click="customFunction()">
Where product is an object with an 'id' element.
Where customFunction adds the product in a shopping cart
Both are combined because the route in the href element permits to access a new page where the added product is customizable.
The code and the routing is working fine cross browser except on mobile phone (android at least, both chrome and native browser). On android phone only the ng-click reacts on click. But i am still able to open the web page routed by href by pressing the link and opening in a new tab :oO
my routing looks like that (app.js):
when('/products/:productId', {
templateUrl: 'partials/store_composition.html',
controller: 'mainCtrl'
})
and in the main Ctrl is called the getProduct function:
if ($routeParams.productId != null) {
$scope.product = $scope.store.getProduct($routeParams.productId);
}
which access the store.js file here :
store.prototype.getProduct = function (id) {
for (var i = 0; i < this.products.length; i++) {
if (this.products[i].id== id)
return this.products[i];
}
return null;
}
And it works fine... Except on android!! but again the link exists if long pressed for new tab :s :s
Any idea?
Update:
I am noticing that the URL in the navbar of android/chrome never changes. Contrarly of whats happening in regular browsers (an URL such as app/index.html#/products/batavia400 is updated on top)
But except for the route i have linked in my post every other routing in my app are working (with no url update just the same... :/)
SOLVED:
I actually solved the problem by adding the
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
and its the user-scalable=nothat made the trick.
The screen was slightly, really slightly zoomed by default by android, and this was creating the conflict on user's touch on the div's link.
I guess if my web designing skills were better I wouldn't have had the problem ;)
I actually solved the problem by adding the
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
and its the user-scalable=nothat made the trick.
The screen was slightly, really slightly zoomed by default by android, and this was creating the conflict on user's touching the div's link.
I can't get all of these to work together. I have phonegap/JQM running with fastclick.js perfectly on iOS. It's a dream. But for some reason I still get a 300ms delay on android. I put some alerts in and the code is being called. It's baffling really. I am testing on a motorola droid razor maxx.
In my index.html file:
<!DOCTYPE html>
<html>
<head>
...
<script type='application/javascript' src='js/fastclick.js'></script>
</head>
<script>
$(document).on("pagebeforechange", function (e, data) {
FastClick.attach(document.body);
alert('fastclick attached');
var to_page = data.toPage[0].id;
// skip showing #myPage if condition is true
if (to_page == "index") {
$.mobile.pageContainer.pagecontainer('change', 'event-list.html');
e.preventDefault();
}
});
</script>
<body>
<div id="index" data-role="page">
This is the index page.
</div>
</body>
</html>
But it doesn't seem to work. I've also tried attaching it like:
window.addEventListener('load', function() {
new FastClick(document.body);
}, false);
Which both work on iOS but don't seem to have any effect on android. Any suggestions?
edit: It seems if I remove the JQuery libraries it works fine. There has got to be a conflict somewhere. Any idea what it may be? I am using JQM 1.4.
edit: I have also tried using vclick to no avail
$("#test-element").bind('vclick',function() {
$.mobile.pageContainer.pagecontainer('change', 'description.html?lunch_pk=2133',{
transition: "slide",
});
});
...
<h1 id='test-element'> CLICK HERE FOR TEST </h1>
I am also using gestures to change pages which are also being delayed by 300ms, so I don't think that even if vclick was working that it would be a complete solution.
edit: ok, so after some further testing, I am pretty sure the delay is coming from inside JQM pagechange functions. I did a console.log inside the vclick and I the log is pretty responsive when hitting the button. I am trying to dig through JQM but not being very successful, I mean why would it be seemless on iOS and not work on android? And maybe I just need to find a better mobile library.
Answer
I was never able to solve this problem. My solution was to switch libraries. I went to Intel's mobile app framework which was able to do everything I was doing with JQM only more successfully.
You can try vclick without trying onclicks. These built-in jQuery Mobile vclick omits the 300ms delay. I do this by doing this.
$("#element").bind('vclick',function(event) {
yourFunction(this.id);
event.preventDefault();// this prevents the default click event
});
Have you tried opening jQueryMobile library file? There are some functions like:
setTimeout(function() {
$link.removeClass( $.mobile.activeBtnClass );
}, 300 );
I am sure, that searching this file for "delay" or "timeout" and changing it would give a good result. Line above is from
.mobile.popup.handleLink = function( $link ) {
...
}
Try registering FastClick inside the deviceready event handler:
document.addEventListener('deviceready', function() {
FastClick.attach(document.body);
}, false);
Have you tryed to juse the tap event?
$("#test-element").off('tap').on('tap', function(event) {...do your stuff});
Note that .bind is deprecated - better use on / off
Note that depending upon, where you're attaching your eventhandler the eventhandler might get bound multiple times on pagechange and revisit.
You best bind your tap-event-handler in ther pageinit event in order to make sure, that you attaching to the event only once and not every time, you revisit a certain page.
In case you're attaching on pageshow use the "off" first (see above)
I had the same problem with some menu buttons. My solution works for all platforms without a helper library, however, I wish there was a better way like setting a JQM variable:
$('#button').unbind('touchstart click').bind('touchstart click', function(event) {
$('#button').addClass('ui-btn-active');
//doSomethingHere();
setTimeout(function() {
$('#button').removeClass('ui-btn-active');
}, 300); //this 300ms is just the delay for styling the button
event.preventDefault(); //if touchstart is supported, do not let the event propagate to the click handler. Having this here avoids a double trigger.
});
The key is binding to touchstart which triggers immediately.
NOTE- I have this code within a pageshow handler which is why I unbind and then bind it. Otherwise, you'd end up with the same event bound multiple times as the user navigates to and from this page.
There are durations associated with the page transition animations in JQM. Here is some of the CSS for the default 'fade' transition (from jquery.mobile.structure.css v1.4.2):
.fade.out {
opacity: 0;
-webkit-animation-duration: 125ms;
-webkit-animation-name: fadeout;
-moz-animation-duration: 125ms;
-moz-animation-name: fadeout;
animation-duration: 125ms;
animation-name: fadeout;
}
.fade.in {
opacity: 1;
-webkit-animation-duration: 225ms;
-webkit-animation-name: fadein;
-moz-animation-duration: 225ms;
-moz-animation-name: fadein;
animation-duration: 225ms;
animation-name: fadein;
}
JQM changes classes on the to and from pages when transitions start and complete, so in the case of the 'fade' transition, the page being changed to will become the active page 225ms after the from page has completed fading out (125ms) i.e. after 350ms.
You could try disabling the transition by specifying {transition: 'none'} in your call to $.mobile.pageContainer.pagecontainer('change' or by setting $.mobile.defaultPageTransition = "none"; in your mobileinit event handler to rule it as the cause of the delay.
I've always disabled page transitions in my Phonegap JQM apps because of the poor performance and flickering (Android), but I still have responsiveness issues, especially on Android. I think it is down to how the webview prioritises rendering the DOM. I've found that a strategically positioned setTimeout can make page changes seem more responsive by allowing the webview to postpone my application logic until after it has rendered the DOM.
I know there are questions on this issue, but I tried everything and do not fix my mistake! X__X
I have a mobile application (astronomical) for Android and when I use to load another html, in the transition makes a white flash that I can't remove (I tried removing the transitions "slide" to use and nothing, background: # 000000! important, etc. ..). I use jQuery mobile 1.3.1 and Phonegap 2.9.0.
I'll share a video where you can see better the problem: http://www.youtube.com/watch?v=ykjCN03nOCM
Any help??
Regards,
Daniela.
CSS :
.ui-page {
-webkit-backface-visibility: hidden;
}
Code :
The CSS solution from this thread didn't work for me (Android 2.x).
I disabled the transistion with data-transition="none" in all links and everything was ok. It should also work when set on page-level, but it didn't work for me (jQuery Mobile 1.0). This is the code:
// turn off animated transitions for Android
if (navigator.userAgent.indexOf("Android") != -1)
{
$("a").attr("data-transition", "none");
}
Another (the better) way would be to set the default transitions for jQuery Mobile:
$(document).bind("mobileinit", function()
{
if (navigator.userAgent.indexOf("Android") != -1)
{
$.mobile.defaultPageTransition = 'none';
$.mobile.defaultDialogTransition = 'none';
}
});
iPhone performs the transitions hardware-accelerated, while the other platforms perform it per software. This explains why only iPhone performs smooth transitions.
Try this one here: here
Maybe your transitions will be more smoothly then.
I have recently come across something quite wierd, I'm not sure if it's maybe me just missing something but I can't understand why this is happening.
I have a site that has the following jQuery snippet running on it:
$(window).resize(function(){
alert("Resize fired!");
});
When I go to the site on an Android phone browser, and simply scroll up and down the site, I can see the alert.
The Android browsers scroll bars (which fade in and out) are overlayed ontop of the entire site and don't seem to cause any resizing of the window, so I'm guessing this event isn't being fired by them.
Does anyone know why the Android browser is firing this event on scrolling?
Any information will be greatly appreciated.
EDIT:
I have tried setting CSS for body, setting overflow-y to scroll to see if that was a viable solution but the event is still being fired on scrolling on Android.
EDIT #2:
I am using the following metatag in my HTML:
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
I was having the same problem, my solution was to check if the window size actually changed, for doing it I needed to store the past window width somewhere in my app. The code could be something like this:
$(window).resize(function() {
clearTimeout(app.resize.timer)
app.resize.timer = setTimeout(function(){
var window_changed = $(window).width() != app.size.window_width
if(window_changed) console.log('Window size changed! resize site')
}, 500)
})
I did not count on the window height because my Android browser hides and shows the address textbox when I scroll down the site making the window height change on vertical scroll
#john-mccollum is correct in the comments. It appears to be the disappearing browser interface causing a change in height that triggers the resize event. So check for change in width specifically in your function if you are doing responsive design stuff where you want to check if the width has been resized.
$(window).resize(function(){
var w = $(window).width();
if (typeof checkw == 'undefined') checkw = w;
if (w!=checkw) {
console.log("The width changed from "+checkw+" to "+w);
// do your responsive magic!
checkw = w;
}
});
Not required to make this work, but this pairs well with the Paul Irish / John Hann "smartresize" method.
i'm having the same problem too!
the problem is true because the height of the browser in Android will change when the url bar hide and show. So, we have to make the browser reload only happens when the width size changes.
i saw this question in Stackoverflow show me how to do this. And this is the jsfiddle.
var doit;
function resizedw(appwidth){
var window_changed = $(window).width() != appwidth;
if ($(window).width() != appwidth){
("body").append("did it"+appwidth+" ");
}
past_width = $(window).width();
}
var past_width = $(window).width();
window.onresize = function() {
clearTimeout(doit);
doit = setTimeout(function() {
resizedw(past_width);
}, 100);
};
I'm creating an App using PhoneGap for Android. One of the pages in the App contains an iFrame (with local content) that is larger than the rest of the pages (this is a single-page App).
The problem I've run into is that once the iFrame page is viewed, the window.innerHeight and window.innerWidth JavaScript objects change their values to match the iFrame's width/height which is causing the rest of the 'pages' to display incorrectly as they are not the same size.
This persists even after I remove the iFrame from the DOM.
Has anyone run into this or has an idea of a workaround?
I just was in the same situation and also I removed the iframe, the solution (that worked for me) is to put the next in your html head:
<meta name="viewport" content="width=device-width, initial-scale=1">
I always though that this part was unnecessary because the innerWidth and innerHeight don't complicate on the desktop, but it cost me 6 hours.
I would like to know if it worked for you, bye.
First, for sure there is a bug here !
I just had the same issue and resolved, here is how.
I changed all the iframes & images width to 100% or less for those wider than window.innerWidth.
Here is the corresponding HaxeJS code:
resizeNodeChildrenTag(_contentContainer,"iframe");
resizeNodeChildrenTag(_contentContainer,"img");
private function resizeNodeChildrenTag(node:HtmlDom, tagName:String):Void
{
var tagNodes:HtmlCollection<HtmlDom> = node.getElementsByTagName(tagName);
// for all nodes with the given tag name
for (i in 0...tagNodes.length)
{
if(tagNodes[i].clientWidth > Lib.window.innerWidth)
tagNodes[i].setAttribute("width", "96%");
tagNodes[i].setAttribute("height", "");
}
}
}