In my (android) phonegap app, I've added the code below to show a loading-spinner while logging in on facebook.
At first start-up, it works beautifuly. However, when I press the back-button and launch the app again, the spinner is out of control: it spins way too fast and with short pauzes. Also, the spinner appears not in the center of the screen, but slightly higher (it looks like it's centered with my text that follows afterwards).
Anyone familiar with this issue and knows how to fix it?
function DeviceReadyListener() {
$.mobile.loading( 'show' );
console.log("Device ready");
try {
FB.init({ appId:"xxx", nativeInterface:CDV.FB, useCachedDialogs:false });
navigator.splashscreen.hide();
getLoginStatus();
document.addEventListener("offline", onOffline, false);
} catch (e) {
alert(e);
}
}
Related
I am having some trouble with a mobile menu. At first i had my code written like this which worked fine on desktop
$('#nav-icon3').click(function(){
$(this).toggleClass('open');
});
$('.menu-item').click(function(){
$('#nav-icon3').toggleClass('open');
});
after uploading and checking on my mobile device via android chrome the click function was not working, so i tried using the touchstart.
$('#nav-icon3').on('touchstart', function(){
$(this).toggleClass('open');
});
$('.menu-item').on('click touchstart', function(){
$('#nav-icon3').toggleClass('open');
});
when touching the menu-item element, the toggle fires twice. Anyway I can prevent this from happening and let it only fire once?
I think what is going on based on your question is that your event is propagating. What you can do is the stop the event from propagating by doing something like this.
$('.menu-item').on('click touchstart', function(e) {
e.stopPropagation();
$('#nav-icon3').toggleClass('open');
});
More reference here:
https://api.jquery.com/event.stoppropagation/
Using e.preventDefault(); worked for me when I had the same issue as you.
$('#nav-icon3').on('touchstart', function(e){
e.preventDefault();
$(this).toggleClass('open');
});
I have the following logic for my mobile app using cordova and angular.js
Process my logic in mobile.js included in index.html like saving the files on sdcard then redirect the user to the second html page using
window.location.href="main.html";
which will use the files put in sdcard by mobile.js
The issue I'm facing is that when I am on the homepage on main.html and the user presses the back button it comes back to the index.html file and then, after processing goes back to main.html instead of App closing.
I tried using the history.length object with the "backbutton" eventListener
document.addEventListener('deviceready',function(){
document.addEventListener('backbutton',function(e){
console.log("history is "+history.length);
if(history.length==1){
e.preventDefault();
navigator.app.exitApp();
}
else{
navigator.app.backHistory();
}
},false);
},false);
but it doesn't decrease the length when going back, only increases it, so the app goes back to index.html.(history.length is always greater than 1)
I have looked the solution available, like
document.addEventListener("backbutton", function(e){
if($.mobile.activePage.is('#homepage')){
/*
Event preventDefault/stopPropagation not required as adding backbutton
listener itself override the default behaviour. Refer below PhoneGap link.
*/
//e.preventDefault();
navigator.app.exitApp();
}
else {
navigator.app.backHistory()
}
}, false);
but the issue in using it is, if the user goes to
second-page->homepage->third-page->homepage
the app will exit, but instead should go to the third-page.
You could use the jQuery mobile pageload event to keep your own history list, whose length does decrease when you go back. Something like this (untested off the top of my head, so might not be exactly correct):
var pageHistory = [];
$(document).on("deviceready", onDeviceReady);
function onDeviceReady(){
$(document).on("pagecontainerload", onPageLoad);
$(document).on("backbutton", onBackButton);
}
function onBackButton(e){
e.preventDefault();
pageHistory.pop();
if(pageHistory.length==0){
navigator.app.exitApp();
}
else{
navigator.app.backHistory();
}
}
function onPageLoad(e, ui){
var pageId = ui.toPage.attr('id');
if(pageId !== pageHistory[pageHistory.length]){
pageHistory.push(pageId);
}
}
In my app i am using phonegap 2.6.For back button, I am using the following function
document.addEventListener("backbutton", onBackKeyDown, false);
function onBackKeyDown() {
alert("hello");
navigator.app.backHistory();
}
document.addEventListener('deviceready', onDeviceReady, true);
The above function works fine when I click on the device's hardware back button. But when I click on the back button it is not working.
I have designed my back button as below:
<a class="ui-link" href="#" rel="external" onclick="onBackKeyDown()">
<img src="images/icon-back.png" alt="Phone" border="0">
</a>
But this button is working fine for this navigator.app.exitApp(); (application exit).
//Working Fine
function onBackKeyDown() {
navigator.app.exitApp();
}
//Not Working
function onBackKeyDown() {
navigator.app.backHistory();
}
but not working for navigator.app.backHistory();.
I have tried 3 separate things when I faced the same situation:
window.history.back()
navigator.app.backHistory();
History.go(-1);
Individually, none of these solve the problem. I put all 3 things together and much to my surprise it worked. I really don't know what is behind it.
Then I decreased to two functions and removed:
window.history.back()
Now I am using this function and it is working fine.
//Works Fine
function onBackKeyDown() {
history.go(-1);
navigator.app.backHistory();
}
If you use the attribute data-rel="back" on an anchor, any clicks on that anchor will mimic the back button, going back one history entry and ignoring the anchor's default href.
it depends where you are:
on my windowsphone 8.1 lumia 925, it works history.go(-1);,
while navigator.app.backHistory(); causes an exception before crashing.
On my Android (I believe the majority), navigator.app.backHistory(); works properly.
This might help some people, as it helped me fix the history.go(-1) not working in google chrome browser.
// Doesn't work in Chrome browser
function onBackKeyDown() {
history.go(-1);
navigator.app.backHistory();
}
// Does work in Chrome browser
function onBackKeyDown() {
history.go(-1);
return false; //needed in chrome to prevent about:blank page.
navigator.app.backHistory();
return false; //needed in chrome to prevent about:blank page.
}
Im no expert at all in jQuery, but thought it might help someone, as I was looking for this answer but couldn't find it at first.
Solved! Stop getting "TypeError: navigator.app is undefined"
A function I created that will first check what device you're on and then apply the relevant script:
function onBackKeyDown() {
var userAgent = navigator.userAgent || navigator.vendor || window.opera;
if (userAgent.match(/iPad/i) || userAgent.match(/iPhone/i) || userAgent.match(/iPod/i)) {
// IOS DEVICE
history.go(-1);
} else if (userAgent.match(/Android/i)) {
// ANDROID DEVICE
navigator.app.backHistory();
} else {
// EVERY OTHER DEVICE
history.go(-1);
}
}
Call function by adding this to your back link/button:
onclick="onBackKeyDown()"
I am having the most annoying situation. Ok, here goes. I am using a javascript based sliding menu for a mobile app. The "slider" works just like Facebook mobile, where you can click the button to show the menu on the left and click it again to close the menu. As an alternative, if you touch the still visible part of the page when the menu is showing it will also close. And that's it.
Problem: Note that I'm using Phonegap for this app. When I run the iOS simulator in Xcode all works fine EXCEPT if you swipeleft, for example, the page will move. I want to disable the swipe event all together. I have tried preventDefault, return false etc. Nothing seems to work. Again, my only goal is to disable touch events because for this app, I simply don't need them. Please see the javascript code for the menu show/hide below.
Thanks is advance. All is appreciated.
$(function(){
var menuStatus;
// Show menu
$("a.showMenu").click(function(){
$('#menu').show();
if(menuStatus != true){
$(".ui-page-active").animate({
marginLeft: "170px",
}, 300, function(){menuStatus = true});
return false;
} else {
$(".ui-page-active").animate({
marginLeft: "0px",
}, 300, function(){menuStatus = false});
return false;
}
});
// Menu behaviour
$("#menu li a").click(function(){
var p = $(this).parent();
if($(p).hasClass('active')){
$("#menu li").removeClass('active');
} else {
$("#menu li").removeClass('active');
$(p).addClass('active');
}
});
});
You could over-ride the $.event.special.swipe.horizontalDistanceThreshold to a larger value and prevent swipes on your page from triggering the swipe event.
Refer to Touch Events -> Swipe
Is there a way to prevent scrolling of a rendered HTML page in the Android browser? The following does not appear to have any impact on page scrolling in the Android browser:
var preventDefault = function(e) {
e.preventDefault();
return false;
};
document.addEventListener('touchmove',preventDefault,false);
document.body.addEventListener('touchmove',preventDefault,true);
window.addEventListener('touchmove',preventDefault,true);
(I've tried with bubbling on and off.)
It looks to me like Android Webkit makes the "window" the same length as the document, so scrolling is being done on the browser itself, not on the document body or DOM window object. What's weird is that that's exactly what webkit on iOS does, but the code above still works.
Answering my own question.
The problem ended up being that you need to capture and suppress ontouchstart as well as ontouchmove on document to stop the browser from scrolling. This is definitely different in iOS, but it still works identically on both platforms.
The actual code I ended up using looks sort of like this:
var preventDefault = function(e){
e.preventDefault();
};
var touchstart = function(e) {
document.addEventListener('touchstart', preventDefault,false);
document.addEventListener('touchmove', preventDefault,false);
/*do other stuff*/
};
var touchend = function(e) {
document.removeEventListener('touchstart', preventDefault,false);
document.removeEventListener('touchmove', preventDefault,false);
};
element.addEventListener('touchstart', touchstart, false);
element.addEventListener('touchend', touchend, false);
Not works on Chrome on Android though
But preventing event on window and stopping immediate propagation helps!
Handler should be not passive to do that.
MAY BE adding an event handler on capturing phase would help too
But this snippet below is tested by me
window.addEventListener("touchmove", function(event) {
event.preventDefault();
event.stopImmediatePropagation();
}, { passive: false });
DEMO https://codepen.io/ColCh/full/qvLqoe