I am using Phonegap and jQuery Mobile. This is my code:
function onDeviceReady() {
// Register the event listener
document.addEventListener("backbutton", onBackKeyDown, false);
setPage();
}
function setPage(){
//All pages at least 100% of viewport height
var viewPortHeight = $(window).height();
//alert(viewPortHeight );
var headerHeight = $('div[data-role="header"]').height();
var footerHeight = $('div[data-role="footer"]').height();
var contentHeight = viewPortHeight - headerHeight - footerHeight-120;
// Set all pages with class="page-content" to be at least contentHeight
$('div[class="page-content"]').css({'min-height': contentHeight + 'px'});
}
function confirmExit(){
alert("exit...");
}
// Call onDeviceReady when Cordova is loaded.
// At this point, the document has loaded but cordova-2.2.0.js has not.
// When Cordova is loaded and talking with the native device,
// it will call the event `deviceready`.
//
function onLoad() { alert("onload");
document.addEventListener("deviceready", onDeviceReady, false);
}
// Handle the back button
function onBackKeyDown() {
alert("onbackkeydown");
console.log("back clicked");
confirmExit();
}
$(document).ready(function(){});
And in the body tag:
<body onload="onLoad();">
But when I load the app I only get the alert in the onLoad method.
What I am doing wrong?
Thanks a lot.
Related
I have this mobile touch indicator, but in Chrome's mobile emulator, how come taps only get registered using mouseup but not touchend orvclick` (http://api.jquerymobile.com/vclick/)?
With vclick (taps don't register): http://jsfiddle.net/frank_o/LnhrF/14/embedded/result/
With mouseup (taps register): http://jsfiddle.net/frank_o/LnhrF/9/embedded/result/
$(document).on('pagecreate', function () {
$('button').on('vclick', function (event) {
showActionIndicator(event, event.pageX - 30, event.pageY - 30);
});
function showActionIndicator(event, pageX, pageY) {
var touchIndicator = $("#touchIndicatorDiv");
touchIndicator.html($("#touchIndicatorTemplate").html());
touchIndicator.css("left", pageX);
touchIndicator.css("top", pageY);
event.preventDefault();
}
});
A common thing we see in many mobile apps is when the user scrolls down the page the header disappears and when they scroll up the page the header appears. How do we achieve this in jQuery Mobile? (I'm answering my own question below)
/**
* Header scroll control
* When the user scrolls down the page hide the header, when they scroll up show it.
*/
var lastScrollPosition;
$(document).scroll( function() {
var scrollPosition = $(this).scrollTop();
// Scrolling down
if (scrollPosition > lastScrollPosition){
// If the header is currently showing
if (!$('[data-role=header].ui-fixed-hidden').length) {
$('[data-role=header]').toolbar('hide');
}
}
// Scrolling up
else {
// If the header is currently hidden
if ($('[data-role=header].ui-fixed-hidden').length) {
$('[data-role=header]').toolbar('show');
}
}
lastScrollPosition = scrollPosition;
});
Variation of Sean Bannisters solution, using Bootstrap 4 and with a transition:
JS:
var lastScrollPosition;
var headerHeight;
$(document).scroll( function() {
var scrollPosition = $(this).scrollTop();
if (scrollPosition > lastScrollPosition){ // Scrolling down
if ($('.sticky-top.show').length) {
$('.sticky-top').removeClass('show');
headerHeight = -$('.sticky-top').height() + 'px';
$('.sticky-top').css('top', headerHeight);
}
} else { // Scrolling up
if (!$('.sticky-top.show').length) {
$('.sticky-top').addClass('show');
$('.sticky-top').css('top', '0');
}
}
lastScrollPosition = scrollPosition;
});
CSS:
.sticky-top { transition: top 0.3s; }
I am currently having issues making iPad work with a :hover event. To clear up what i mean i have uploaded part of the website at http://playing.everythingcreative.co.uk and I have 3 images, that when hovered over a div disappears to show text underneath but this does not work on the iPad at all. I tried:
ontouchstart="touchStart(event);"
But i don't know enough on how it works to use it right.
Any help would be great.
I figured it out anyway using the example on iOS automatic hover fix? and changing:
if(navigator.platform == "iPad") {
to:
if ("ontouchstart" in document.documentElement) {
The final code:
$(document).ready(function() {
if ("ontouchstart" in document.documentElement) {
$("div").each(function() { // have to use an `each` here - either a jQuery `each` or a `for(...)` loop
var onClick; // this will be a function
var firstClick = function() {
onClick = secondClick;
return false;
};
var secondClick = function() {
onClick = firstClick;
return true;
};
onClick = firstClick;
$(this).click(function() {
return onClick();
});
});
}
});
I have an image gallery with a series of thumbs. Both are loaded dynamically depending on how many images are associated with a product. You can click on a thumb to get that series of images. On a mobile device you can swipe left and right to see all the images. That all works fine.
Here's my issue: When you try to scroll down the page and you happen to be touching one of the main images you get stuck and the page doesn't move. For the life of me I cannot figure out a work around for this. I am wondering if anyone has ever encountered this and figured out a solution. I think there could be a way to control this via the touch-punch.js but cannot figure it out. Thank you.
Here is my simplified gallery HTML:
<ul id="Gallery" class="gallery productGalleryInner">
<li>
<a href="#"><img src="img.jpg" />/a>
<a href="#"><img src="img.jpg" />/a>
<a href="#"><img src="img.jpg" />/a>
<a href="#"><img src="img.jpg" />/a>
<a href="#"><img src="img.jpg" />/a>
</li>
</ul>
</div>
css:
#productGalleryWrap {
overflow: hidden;
margin: 7px 10px 0;
}
#productGalleryWrap .productGalleryInner {
white-space: nowrap;
}
#productGalleryWrap .productGalleryInner li {
display: inline;
}
#productGalleryWrap .productGalleryInner img {
display: inline;
width: 50%;
}
I am using touch-punch.js to control the horizontal drag. Here is the code:
(function ($) {
// Detect touch support
$.support.touch = 'ontouchend' in document;
// Ignore browsers without touch support
if (!$.support.touch) {
return;
}
var mouseProto = $.ui.mouse.prototype,
_mouseInit = mouseProto._mouseInit,
touchHandled;
/**
* Simulate a mouse event based on a corresponding touch event
* #param {Object} event A touch event
* #param {String} simulatedType The corresponding mouse event
*/
function simulateMouseEvent (event, simulatedType) {
// Ignore multi-touch events
if (event.originalEvent.touches.length > 1) {
return;
}
event.preventDefault();
var touch = event.originalEvent.changedTouches[0],
simulatedEvent = document.createEvent('MouseEvents');
// Initialize the simulated mouse event using the touch event's coordinates
simulatedEvent.initMouseEvent(
simulatedType, // type
true, // bubbles
true, // cancelable
window, // view
1, // detail
touch.screenX, // screenX
touch.screenY, // screenY
touch.clientX, // clientX
touch.clientY, // clientY
false, // ctrlKey
false, // altKey
false, // shiftKey
false, // metaKey
0, // button
null // relatedTarget
);
// Dispatch the simulated event to the target element
event.target.dispatchEvent(simulatedEvent);
}
/**
* Handle the jQuery UI widget's touchstart events
* #param {Object} event The widget element's touchstart event
*/
mouseProto._touchStart = function (event) {
var self = this;
// Ignore the event if another widget is already being handled
if (touchHandled || !self._mouseCapture(event.originalEvent.changedTouches[0])) {
return;
}
// Set the flag to prevent other widgets from inheriting the touch event
touchHandled = true;
// Track movement to determine if interaction was a click
self._touchMoved = false;
// Simulate the mouseover event
simulateMouseEvent(event, 'mouseup');
// Simulate the mousemove event
simulateMouseEvent(event, 'mousemove');
// Simulate the mousedown event
simulateMouseEvent(event, 'mousedown');
};
mouseProto._touchMove = function (event) {
// Ignore event if not handled
if (!touchHandled) {
return;
}
// Interaction was not a click
this._touchMoved = true;
// Simulate the mousemove event
simulateMouseEvent(event, 'mousemove');
};
/**
* Handle the jQuery UI widget's touchend events
* #param {Object} event The document's touchend event
*/
mouseProto._touchEnd = function (event) {
// Ignore event if not handled
if (!touchHandled) {
return;
}
// Simulate the mouseup event
simulateMouseEvent(event, 'mouseup');
// Simulate the mouseout event
simulateMouseEvent(event, 'mouseout');
// If the touch interaction did not move, it should trigger a click
if (!this._touchMoved) {
// Simulate the click event
simulateMouseEvent(event, 'click');
}
// Unset the flag to allow other widgets to inherit the touch event
touchHandled = false;
};
/**
* A duck punch of the $.ui.mouse _mouseInit method to support touch events.
* This method extends the widget with bound touch event handlers that
* translate touch events to mouse events and pass them to the widget's
* original mouse event handling methods.
*/
mouseProto._mouseInit = function () {
var self = this;
// Delegate the touch handlers to the widget's element
self.element
.bind('touchstart', $.proxy(self, '_touchStart'))
.bind('touchmove', $.proxy(self, '_touchMove'))
.bind('touchend', $.proxy(self, '_touchEnd'));
// Call the original $.ui.mouse init method
_mouseInit.call(self);
};
})(jQuery);
Please let me know if more info is needed. Thanks.
Kind of late answer but I had this same problem on a current project I'm working on.
Comment out:
event.preventDefault();
Add this after:
document.ontouchmove = function(e) {
var target = e.currentTarget;
while(target) {
if(checkIfElementShouldScroll(target))
return;
target = target.parentNode;
}
e.preventDefault();
};
Dolla dolla bills y'all.
Code taken from this thread: document.ontouchmove and scrolling on iOS 5
I have an IOS Web App that can't be scrolled. For that reason I want to deactivate scrolling. To do this, I use an element's ontouchmove attribute and have it call a function that uses element.preventDefault.
However, I am unable to detect any touching event when it starts on a textarea or input element, even when the element is disabled! I have also tried binding the touchmove or touchstart event to these elements via JavaScript's addEventlistener, without success!
And here's my JavaScript:
function onBodyLoad() {
document.addEventListener( "touchstart", doNotScroll, true );
document.addEventListener( "touchmove", doNotScroll, true );
}
function doNotScroll( event ) {
event.preventDefault();
event.stopPropagation();
}
Thanks for any help!
I think I've found a great workaround for this issue using the "pointer-events" CSS property:
function setTextareaPointerEvents(value) {
var nodes = document.getElementsByTagName('textarea');
for(var i = 0; i < nodes.length; i++) {
nodes[i].style.pointerEvents = value;
}
}
document.addEventListener('DOMContentLoaded', function() {
setTextareaPointerEvents('none');
});
document.addEventListener('touchstart', function() {
setTextareaPointerEvents('auto');
});
document.addEventListener('touchmove', function(e) {
e.preventDefault();
setTextareaPointerEvents('none');
});
document.addEventListener('touchend', function() {
setTimeout(function() {
setTextareaPointerEvents('none');
}, 0);
});
This will make Mobile Safari on iOS (others not tested so far) ignore the textareas for scrolling but allows to set focus etc. as usual.
the Thomas Bachem answer is the one!
I rewrote it in jQuery. Just add a class scrollFix to your desired inputs and you are ready to go. Or attach the event handlers to all inputs and textareas using $('input, textarea').
Now when you touch and scroll on an input on iOS 8+, the input get all its pointer-events disabled (including the problematic behavior). Those pointer-events are enabled when we detect a simple touch.
$('.scrollFix').css("pointer-events","none");
$('body').on('touchstart', function(e) {
$('.scrollFix').css("pointer-events","auto");
});
$('body').on('touchmove', function(e) {
$('.scrollFix').css("pointer-events","none");
});
$('body').on('touchend', function(e) {
setTimeout(function() {
$('.scrollFix').css("pointer-events", "none");
},0);
});