How it's expected to work
I created a scollable div for a project. The position of the scrollbar is calculated width jQuery. In a desktop environment there is a visible slider. On mobile devices there is not but it's still possible to swipe left to get more content.
(It does not yet update on window resize. Reload is required.)
Expected: "overflow_diff" should be equal to "Scoll pos". "Percentage" should be 100 when scolled to the end.
What works
It works fine in Chrome and Firefox on desktop and on Chrome on Android.
What does not work - My question
Firefox on Android does the calculations all wrong. Strange is that it works on desktop. If it's a bug in Firefox, how do I get around it?
Full example
http://xn--trnell-wxa.se/scrolltest2/index.php
HTML header
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
CSS
* {
padding: 0;
margin: 0;
}
.wrap {
padding: 40px;
background: #eee;
width: 75%;
}
.cropped {
overflow-x: auto;
}
.overflow {
width: 300%;
background: #ddd;
height: 100px;
}
JS
jQuery(window).ready(function($) {
var cropped_width = $('.cropped').width();
var overflow_width = $('.overflow').width();
var overflow_diff = overflow_width - cropped_width;
$( '.log' ).append( 'Overflow: ' + overflow_width + '<br>' );
$( '.log' ).append( 'Cropped: ' + cropped_width + '<br>' );
$( '.log' ).append( 'Overflow diff: ' + overflow_diff + '<br>' );
$( '.log' ).append( '<div class="scrolled"></div>' );
$( '.log' ).append( '<div class="scrolled2"></div>' );
$( '.cropped' ).on('scroll touchmove', function() {
var scroll_pos = $( this ).scrollLeft();
var percentage = Math.round( scroll_pos / overflow_diff * 100 );
$( '.log .scrolled' ).html( 'Scroll pos: ' + scroll_pos + '<br>Percentage: ' + percentage + '<br>' );
});
});
HTML
<div class="wrap">
<div class="cropped">
<div class="overflow">Swipe to the end</div>
</div>
</div>
<div class="log"></div>
I think you should bind your event with .on() and use touchmove event too:
$( '.cropped' ).on('scroll touchmove', function() {
// the code here
});
From #Joeytje50 answer Android browsers not handling touchmove events correctly
Turns out the problem here was simply the fact the event handler
didn't have an event.preventDefault() in it, so the original action
still executed, which apparently interrupted the touch event. To fix
this, simply add e.preventDefault() in the current event handler
function to cancel the current event, and make it work as expected in
Chrome and Opera too.
Also, to check whether you use scroll or touchmove you can use the below condition,
// ..... your remaining code
$( '.log' ).append( '<div class="scrolled2"></div>' );
var eventName='scroll';
if ('ontouchstart' in document.documentElement) {
eventName = 'touchmove';
}
$( '.cropped' ).on(eventName , function(e) {
(eventName == 'touchmove') ? e.preventDefault() : '';
var scroll_pos = $( this ).scrollLeft();
// your remaining code
});
Related
I want to hide the top options bar in google drive. How can I achieve that? I am using cordova inAppBrowser to open this link.
https://drive.google.com/file/d/0B_nipvep1WpPd2JXeDdJcUlNYXM/view
I want to use embedded=true but I don't know how it would work. Please see the image below.
May be this will help you
You have to wait until your inAppBrowser page loading finishes.
//Set css in your inAppstyle.css
.drive-viewer-toolstrip{
display: none !important;
opacity: 0 !important;
}
You must add an event listener:
var inApp = window.open('https://drive.google.com/file/d/0B_nipvep1WpPd2JXeDdJcUlNYXM/view', '_blank', 'location=no');
inApp.addEventListener('loadstop', function(){
inApp.insertCSS({
file: 'inAppStyle.css'
},onSuccess);
});
Use this path for your android projects file:///android_asset/{your folder}
INFO: https://github.com/apache/cordova-plugin-file/blob/master/doc/index.md#android-file-system-layout
Your JS
text += '' + data.docs[i].doc_title + '';
Updated JS
text += '' + data.docs[i].doc_title + '';
//Create new function
function openthislink(ln)
{
var inApp = window.open(ln, '_blank', 'location=no');
inApp.addEventListener('loadstop', function(){
inApp.insertCSS({
file: 'inAppStyle.css'
},onSuccess);
});
}
I am new to use google maps on mobile phones, and I am using phonegap framework for that. below is the example code I am using to get the google maps on android phone. but it is of the version 3.8 and when I try to load the latest version 8.1.0 it shows a blank screen. So need help to go in right direction in using google maps.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, minimum-scale=1, maximum-scale=1">
<title>Map</title>
<link href="css/jquery/jquery.mobile-1.4.2.min.css" rel="stylesheet"
type="text/css" />
<script type="text/javascript" src="js/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="js/jquery.mobile-1.4.2.min.js"></script>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript" src="cordova-2.4.0.js"></script>
<script type="text/javascript">
var map;
var marker;
var infowindow;
var watchID;
$(document).ready(function(){
document.addEventListener("deviceready", onDeviceReady, false);
//for testing in Chrome browser uncomment
//onDeviceReady();
});
//PhoneGap is ready function
function onDeviceReady() {
$(window).unbind();
$(window).bind('pageshow resize orientationchange', function(e){
max_height();
});
max_height();
google.load("maps", "3.8", {"callback": map, other_params: "sensor=true&language=en"});
map();
}
function max_height(){
var h = $('div[data-role="header"]').outerHeight(true);
var f = $('div[data-role="footer"]').outerHeight(true);
var w = $(window).height();
var c = $('div[data-role="content"]');
var c_h = c.height();
var c_oh = c.outerHeight(true);
var c_new = w - h - f - c_oh + c_h;
var total = h + f + c_oh;
if(c_h<c.get(0).scrollHeight){
c.height(c.get(0).scrollHeight);
}else{
c.height(c_new);
}
}
function map(){
var latlng = new google.maps.LatLng(55.17, 23.76);
var myOptions = {
zoom: 6,
center: latlng,
streetViewControl: true,
mapTypeId: google.maps.MapTypeId.ROADMAP,
zoomControl: true
};
map = new google.maps.Map(document.getElementById("map"), myOptions);
google.maps.event.addListenerOnce(map, 'tilesloaded', function(){
//get geoposition once
//navigator.geolocation.getCurrentPosition(geo_success, geo_error, { maximumAge: 5000, timeout: 5000, enableHighAccuracy: true });
//watch for geoposition change
watchID = navigator.geolocation.watchPosition(geo_success, geo_error, { maximumAge: 5000, timeout: 5000, enableHighAccuracy: true });
});
}
function geo_error(error){
//comment
alert('code: ' + error.code + '\n' + 'message: ' + error.message + '\n');
}
function geo_success(position) {
map.setCenter(new google.maps.LatLng(position.coords.latitude, position.coords.longitude));
map.setZoom(15);
var info =
('Latitude: ' + position.coords.latitude + '<br>' +
'Longitude: ' + position.coords.longitude + '<br>' +
'Altitude: ' + position.coords.altitude + '<br>' +
'Accuracy: ' + position.coords.accuracy + '<br>' +
'Altitude Accuracy: ' + position.coords.altitudeAccuracy + '<br>' +
'Heading: ' + position.coords.heading + '<br>' +
'Speed: ' + position.coords.speed + '<br>' +
'Timestamp: ' + new Date(position.timestamp));
var point = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
if(!marker){
//create marker
marker = new google.maps.Marker({
position: point,
map: map
});
}else{
//move marker to new position
marker.setPosition(point);
}
if(!infowindow){
infowindow = new google.maps.InfoWindow({
content: info
});
}else{
infowindow.setContent(info);
}
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
}
</script>
</head>
<body>
<!-- Main Page-->
<div data-role="page" data-theme="b" id="main">
<div data-role="header">
<h1>RealTrac</h1>
</div>
<div data-role="content">
<h3>Select the application</h3>
<a data-role="button" href="#jnytimetracker">Journey-Time Tracker</a>
<a data-role="button" href="#qtimetracker">Queue-Time Tracker </a>
</div>
</div>
<!-- First Page End -->
<div data-role="page" id="jnytimetracker">
<div data-role="header" data-theme="b">
<h1>Map Header</h1>
</div>
<div data-role="content" style="padding: 0;">
<div id="map" style="width: 100%; height: 100%;"></div>
</div>
<div data-role="footer" data-theme="b">
<h4>Map Footer</h4>
</div>
</div>
</html>
THanks
I have worked on the google map on my mobile website . And its based on JQuery mobile . Here is what worked for me
This is the most common problem in JQM. I totally agree with #Omar about the solution .
Cause of the problem
The JQM uses script to layer divs over your normal div to make it more enrich and look better
So when you initialize the google map these hidden layer causes the problem to show it completely
Most of the time as I have researched in Google that the map is shown in the upper left corner of the window :).
Easy fix
This one goes only for JQM pages
$( document ).on( "pageshow", "#map", function() {
});
Just put your google map code inside the above code what it does is that the map will load only after all the divs have been loaded . Please see the event pageshow in JQM website.
My Script Look something like this
$( document ).on( "pageshow", "#map-page", function() {
<?php $coordenadas=explode(',',$fila['Googlemap']);?>
var defaultLatLng = new google.maps.LatLng('<?php echo $coordenadas[0];?>','<?php echo $coordenadas[1];?>');
$('#map-canvas').height( $(window).height() - $('#head1').height());
drawMap(defaultLatLng); // Default to Hollywood, CA when no geolocation support
//var latlng = marker.getPosition();
function drawMap(latlng) {
var myOptions = {
zoom: 18,
center: latlng,
streetViewControl:true,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map-canvas"), myOptions);
// Add an overlay to the map of current lat/lng
var marker = new google.maps.Marker({
position: latlng,
map: map,
title: "Greetings!"
});
// this is our gem
google.maps.event.addDomListener(window, "resize", function() {
var center = map.getCenter();
google.maps.event.trigger(map, "resize");
map.setCenter(center);
});
}
});
Just change the #map selector to the id of the page where the map has to be loaded .
Hope I have helped you or others who have been facing the same problem :)
Thanks & Regards
i got a problem with my app.i'm developing an app with cordova & jquery mobile.
Following the code on jquery mobile master i found that code
function openPopup(idPopup, onTimeout) {
var popupContent = '<div data-role="content" data-theme="a" style="border:0px;" class="ui-corner-bottom ui-content centerContent">' +
'<h3 class="ui-title" id="myTitle">Caricamento</h3>' +
'<img src="img/load_shop33sell.gif"/></div>';
var popup = '<div data-role="popup" id="popup-' + idPopup + '" data-overlay-theme="b" data-theme="a" class="ui-content">' + popupContent + '</div>';
$.mobile.activePage.append(popup).trigger("pagecreate");
$("#popup-" + idPopup).on({
popupbeforeposition: function () {
$('.ui-popup-screen').off();
}
});
var fallback = setTimeout(function () {
$("#popup-" + idPopup).popup("open");
}, 3000);
$("#popup-" + idPopup).popup("open");
clearTimeout(fallback);
callback = setTimeout(function () {
$("#popup-" + idPopup).popup('close');
if (onTimeout && typeof (onTimeout) === "function") {
onTimeout();
}
}, 20000);
}
With this code, i am able to open a popup without needing to include a
<div data-role="popup">..../<div>
in each page i create.I just modified a bit adding the popupbeforeposition event to make the popup undismissable by clicking on the background.
Well, it works fine but i got a problem. Randomly in my first page this happens
Seems like the popup opens before it get the right position. In addition i have a second page which is scrollable, and i always have this situation. If i try to scroll up to the top of the page, i have half of the screen black, as in first picture.
What could be the problem?
Thanks in advance, and sorry for my english :)
As you mentioned it is due to data-overlay-theme="a". But actually it should works in good way..thinking that this is due to $('.ui-popup-screen').off();
you can observe here
Prevent JQuery Mobile from closing a popup when user taps outside of it
if you need an alternative way for black background you can do this ..
Add div <div id="overlaypage"></div> like this inside <div data-role="page">
HTML:
<div data-role="page">
<div id="overlaypage"></div>
<div id="header"></div>
</div>
CSS:
.overlaycont {
background:#000;
bottom:0;
left:0;
position:fixed;
right:0;
top:0;
z-index:100;
opacity:.6
}
jQuery:
When you try to click to open a popup addclass
$("#overlaypage").addClass("overlaycont");
When you closing the popup remove class
$("#overlaypage").removeClass("overlaycont");
Working demo: http://jsfiddle.net/nPeaV/7421/
ok, i solved the problem combining the two answers, this is my function to open popup
function apriPopup(idPopup, onTimeout) {
$(".ui-navbar").css('display','none');
var popupContent = '<div data-role="content" data-theme="a" style="border:0px;" class="ui-corner-bottom ui-content centerContent">' +
'<h3 class="ui-title" id="myTitle">Caricamento</h3>' +
'<img src="img/load_shop33sell.gif"/></div>';
var popup = '<div data-role="popup" data-dismissible="false" id="popup-' + idPopup + '" data-theme="a" class="ui-content">' + popupContent + '</div>';
$.mobile.activePage.append(popup).trigger("create");
//$("#popup-" + idPopup).on({
// popupbeforeposition: function () {
// $('.ui-popup-screen').off();
// }
//});
var fallback = setTimeout(function () {
$("#overlaypage").addClass("overlaycont");
$("#popup-" + idPopup).popup("open");
}, 3000);
$("#overlaypage").addClass("overlaycont");
$("#popup-" + idPopup).popup("open");
clearTimeout(fallback);
callback = setTimeout(function () {
$(".ui-navbar").css('display','block');
$("#overlaypage").removeClass("overlaycont");
$("#popup-" + idPopup).popup('close');
if (onTimeout && typeof (onTimeout) === "function") {
onTimeout();
}
}, 20000);
}
as you can see i have commentend the $('.ui-popup-screen').off(); , added a data-dismissable="false"
and i have used the overlaycont css style suggested by dileep.
in my index, as child of body,i added a <div id="overlaypage"></div> and $("#overlaypage").addClass("overlaycont");,
in this way popup is undismissabile by cliking outside of it, and background is displayed correctly.
such a pain!
I'm having 2 strange problems with the code I'm using to pull in some data to use in a listview. Here is my javascript:
function getOrders(status, url) {
$(function () {
//check if url from pagination
if (!url) {
url = api_url + '/orders/?callback=?&status=' + status;
} else {
url = root_url + url + '&callback=?';
}
$.mobile.loading('show');
$.getJSON(url, null, function (d) {
//declare a variable with which to build our output (it's best to buffer output and only do one append at the end since DOM manipulation is CPU expensive)
var output = '';
//iterate through the data (we could also get rid of the jQuery here by using `for (key in data) {
$.each(d.objects, function (index, value) {
output += '<li><a id="' + value.reference + '" href="view_order.html" class="view_order"><h3>' + value.reference + ' - ' + value.client.company + '</h3><p>' + value.order_date + ' ' + value.user.username + '</p></a></li>';
});
$('#orders_list').html(output).listview('refresh');
//if paginated, update next button
if (d.meta.next) {
$("#id_ordersNext").attr('href', d.meta.next);
$("#id_ordersNext").show();
} else {
$("#id_ordersNext").hide();
}
if (d.meta.previous) {
$("#id_ordersPrevious").attr('href', d.meta.previous);
$("#id_ordersPrevious").show();
} else {
$("#id_ordersPrevious").hide();
}
$("#id_ordersTotal").html(d.meta.total_count);
$.mobile.loading('hide');
});
});
}
$(function () {
//bind the nav
$(".order_nav").die();
$(".order_nav").live('click', function () {
$(".order_nav").each(function () {
$(this).removeClass('ui-btn-active');
});
$(this).addClass('ui-btn-active');
getOrders($(this).attr('href'));
return false;
});
//bind the view order
$(".view_order").die();
$(".view_order").live('click', function () {
//save var
window.viewOrderReference = $(this).attr('id');
$.mobile.changePage("view_order.html");
});
$("#id_ordersNext,#id_ordersPrevious").die();
$("#id_ordersNext,#id_ordersPrevious").live('click', function () {
getOrders(null, $(this).attr('href'));
return false;
});
//default view
getOrders('Order Placed');
});
Here is the html I'm using for the page that's being loaded via JQMobile:
<div data-role="page" data-needs-auth='true'>
<script src="js/list_orders.js"></script>
<div class="headerDiv" data-role='header' data-theme='b'>Home
<h1>Jubilee Distributors</h1>
Login</div>
<div data-role='navbar'>
<ul>
<li>Placed</li>
<li>Picked</li>
<li>Delivered</li>
</ul>
</div>
<div data-role="content">
<ul data-role='listview' id="orders_list" data-filter="true"><li>No records found</li></ul>
<p>Previous <span id='id_ordersTotal' class='record-count'></span> records found Previous
</p>
</div>
<div id='footerDiv' data-role="footer"></div>
</div>
This all works fine in any browser on a desktop, but when I run it on an Android device 2 things happen, or rather don't.
The last line in the $(function() - getOrders('Order Placed'), doesn't seem to execute, or if it does, it's not updating the list with the returned result. If I click the first link with the "Orders Placed" it works no probs.
The addClass is not actually adding the class.
Like I said, this all works fine in any desktop browser, but not on the Android device.
Any ideas?
EDIT: Fixed the second problem, however the first problem still exists.. It works if I navigate to the page, then away from it, then back again tho.
Fixed this error by changing the dom ready function to pageinit.
Does somebody know how to hide URL on Android (like full screen) using HTML/javascript?
On iPad (Safari) this is simple and can be done using only a few meta tags.
I have tried something like that:
$(document).ready(function () {
scrollTo(0, 1);
});
But, on Motorola T1, the URL bar is still displayed :(
None of any solution above worked for me on Samsung S3 mini phone with Android 4.1.1
But I have followed the mentioned url and there was the absolutely right solution.
Thanks for it.
https://gist.github.com/1183357
See Fresheyeball's implementation. That works perfectly in portrait and landscape mode as well.
I just copy here my full example:
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<script type="text/javascript" src="jquery-1.8.3.min.js"></script>
<script type="text/javascript">
$(function() {
hideAddressBar();
});
function hideAddressBar() {
if (navigator.userAgent.match(/Android/i)) {
window.scrollTo(0, 0); // reset in case prev not scrolled
var nPageH = $(document).height();
var nViewH = window.outerHeight;
if (nViewH > nPageH) {
nViewH = nViewH / window.devicePixelRatio;
$('BODY').css('height', nViewH + 'px');
}
window.scrollTo(0, 1);
} else {
addEventListener("load", function() {
setTimeout(hideURLbar, 0);
setTimeout(hideURLbar, 500);
}, false);
}
function hideURLbar() {
if (!pageYOffset) {
window.scrollTo(0, 1);
}
}
return this;
}
</script>
</head>
<body>
<section>
<div>
<h1>First title</h1>
<p>Just some content</p>
</div>
</section>
<section>
<div>Any text</div>
</section>
</body>
</html>
Of course you need to put the jQuery main js file as well in order this example work properly. You can download from here http://jquery.com/download/
try this
$(document).ready(function() {
if (navigator.userAgent.match(/Android/i)) {
window.scrollTo(0,0); // reset in case prev not scrolled
var nPageH = $(document).height();
var nViewH = window.outerHeight;
if (nViewH > nPageH) {
nViewH -= 250;
$('BODY').css('height',nViewH + 'px');
}
window.scrollTo(0,1);
}
});
it works even if your page is not long enough
Try this one. I've used it and it seems to work perfectly on Android. It's from here:
https://gist.github.com/1183357
/*
* Normalized hide address bar for iOS & Android
* (c) Scott Jehl, scottjehl.com
* MIT License
*/
(function( win ){
var doc = win.document;
// If there's a hash, or addEventListener is undefined, stop here
if( !location.hash && win.addEventListener ){
//scroll to 1
window.scrollTo( 0, 1 );
var scrollTop = 1,
getScrollTop = function(){
return win.pageYOffset || doc.compatMode === "CSS1Compat" && doc.documentElement.scrollTop || doc.body.scrollTop || 0;
},
//reset to 0 on bodyready, if needed
bodycheck = setInterval(function(){
if( doc.body ){
clearInterval( bodycheck );
scrollTop = getScrollTop();
win.scrollTo( 0, scrollTop === 1 ? 0 : 1 );
}
}, 15 );
win.addEventListener( "load", function(){
setTimeout(function(){
//at load, if user hasn't scrolled more than 20 or so...
if( getScrollTop() < 20 ){
//reset to hide addr bar at onload
win.scrollTo( 0, scrollTop === 1 ? 0 : 1 );
}
}, 0);
} );
}
})( this );