Why tap event is suppressed by touchstart event? - jquery-mobile

I have this code:
$('.selector').on({
touchstart: function (e) {
e.preventDefault();
alert(3);
e.stopPropagation();
},
tap: function (e) {
e.preventDefault();
alert(4);
e.stopPropagation();
}
});
Only touchstart is triggered. Can anybody explain why?
P.S. : This is how I include the script for jQuery mobile :
<script src="http://code.jquery.com/mobile/1.4.4/jquery.mobile-1.4.4.min.js"></script>
EDIT:
I want to introduce a hover functionality on one of my div and I thought that with tap event it will be like clicking and with touchstart like hover.
$('.selector').on('tap swipe', function (e) {
e.preventDefault();
if(e.type == 'swipe') {
alert(1);
}
if(e.type == 'tap') {
alert(2);
}
e.stopPropagation();
});
$('.selector .sel1').on('tap swipe', function (e) {
e.preventDefault();
if(e.type == 'swipe') {
alert(3);
}
if(e.type == 'tap') {
alert(4);
}
e.stopPropagation();
});
With this code the swipe event on my div works fine, but for inside element I can't reproduce the swipe event, only tap gets triggered. I really can't figure out why.

Use syntax like this:
$('.selector').on("touchstart tap", function(e){
e.preventDefault();
if(e.type == "touchstart"){
alert(3);
}
if(e.type == "tap"){
alert(4);
}
e.stopPropagation();
});

Touchstart seems to no longer be offered as a native event within jQuery Mobile ver. 1.4.5 Perhaps you can use "tap" and "swipe" (or "swipeleft" / "swiperight") to achieve your goals? Its not entirely clear on what you are creating.
Note: one thing that you can do is easily customize the native jQuery Mobile functions for swipe. See details at http://api.jquerymobile.com/swipe/
Before you make the .on("swipe"...) binding you can change the test values used by jQuery swipe. Its as easy as
$.event.special.swipe.horizontalDistanceThreshold = 100; // in lieu of 30px
You can verify that data setup via alerts or console.log(). Perhaps this will work for you? hmmm.. by working on vertical distance threshold, you could in essence temporarily define "swipe" to function as a "swipe-up", then you'd have swipeleft, swiperight and swipeup to play with.

Related

migrate from jquerymobile 1.2.1 to 1.4.5

I am migrating up from jquerymobile 1.2 to 1.4.5
the content for each of my pages on my app commences with the following syntax,
$("#DemoAccountRegistrationPage").live("pageshow", function() {
I have been able to figure out i need to transition the .live to .on so the above becomes each page reference
$("#DemoAccountRegistrationPage").on("pagecontainershow", function() {
however i realise that the above format is still not compliant for 1.4.5 hence why the content is not loading
can someone please provide me the correct syntax to be able to change
$("#DemoAccountRegistrationPage").on("pagecontainershow", function() {
to the correct syntax for compliance with 1.4.5
I have read over the jquery docs but cannot fully understand what the correct syntax needs to be (very new to jquery mobile)
The jQuery docs are not at all very clear on this, but in a nutshell, pageshow was deprecated in JQM 1.4.0 in favour of using pagecontainershow on the pagecontainer widget.
I was able to get something working by adding the pagecontainershow listener to the document, then inspecting the arguments to figure out if it matched the page I wanted; something like this:
$(document).on('pagecontainershow', function(event, ui) {
if(ui.toPage[0].id == "my_page_id"){
// do some stuff for my_page
}
});
I tried to make it a bit more reusable, like this:
function on_pagecontainershow(page_id, fn){
$(document).on('pagecontainershow', function(event, ui) {
if(ui.toPage[0].id == page_id){
fn();
}
});
}
on_pagecontainershow('test_page', function(){
alert('pagecontainershow triggered');
});
Syntaxes I tried and failed to get working:
$(document).on('pagecontainershow', '#test_page', function(event, ui) {
alert("I don't get called (1)");
});
$(document).delegate("#test_page", "pagecontainershow", function() {
alert("I don't get called (2)");
});
$("#test_page").on("pagecontainershow", function() {
alert("I don't get called (3)");
});
You can try it out in this fiddle.
This works for me, as i'm using it in one of my projects:
$(document).on("pagecontainershow", function(e, ui) {
var pageId = $(":mobile-pagecontainer").pagecontainer("getActivePage").prop("id");
if (typeof ui.toPage == "object") {
/* manipulate page navigating to */
switch(pageId) {
case "page-one":
//do stuff
break;
case "page-two":
// do other stuff
break;
}
}
});

jquery mobile swipe event disable for input range

I am using jquery mobile to close and open a menu in an app like this:
$('body').on('swipeleft', function(event){
if(menuOpen == true){
home.showMenu();
}
});
$('body').on('swiperight', function(event){
if(menuOpen == false){
home.showMenu();
}
});
And I have a input range (slider) in my menu like this:
<input id="changeRadiusRange" type="range" min="5" max="100" step="5" oninput="handleInputVal(value)" onchange="handleChangeVal(this.value)">
Now if I use my slider it stops after some time (I think the 30pixel for swipeleft/right to get fired and menu is closing if it is a swipeleft)
I already tried a few things regarding to this question, that results in this but didn't changed the behavior:
$('#changeRadiusRange').on('swipeleft swiperight', function(e){
e.stopPropagation();
e.preventDefault();
});
How can I force input behavior as normal not to be influenced by swipe-events?
I had the same problem today and found a less hacky solution.
var handleSwipe = function (event) {
// my swipe stuff
}
// regular event listening
$(document).on("swipeleft swiperight", handleSwipe);
// additional workaround
$(".slider").on("mousedown touchstart", function (event) {
// when starting to interact with a .slider, stop listening the event
$(document).off("swipeleft swiperight");
}).on("mouseup touchend", function (event) {
// when interaction stops, re-listen to swipe events
$(document).on("swipeleft swiperight", handleSwipe);
});
It seems that sliders never ever work properly, as long as the swipe events are used anywhere in the document. This is even the case, when there is nothing done in the event handler. Also preventDefault() and/or stopPropagation() doesn't change anything.
With this solution, I kill the previously enabled swipe events while the user interacts with a slider. When interaction is done, I re-enable swipe events. Works great for me.
This worked for me with jqm 1.4.5:
$(document).on('mousedown touchstart', 'input[type=range]',
function(e){
e.stopPropagation();
});
Currently solved it like this:
$('body').on('swipeleft', function(event){
if(event.target.id != "changeRadiusRange"){
if(menuOpen == true){
home.showMenu();
}
}
});
But then slider is stopping after the swipeleft event is called from body. does not move more to the left so I have to release the slider and slide again to the left if I need to till the swipeleft is called etc. Just workaround hope got it fixed soon

Text input inside jQuery UI sortable doesn't work on touch devices

I made a simple page with some divs being sortable by the jQuery UI Sortable, with a little help from Touch Punch to get it working on an iPad running iOS 7.1.2.
Inside each of these divs, I included a text input tag. On desktop browsers the inputs work fine, but the iPad doesn't recognize the click on the input component. The keyboard isn't launched and I can't type into it. Any lights?
My page is here: https://www.dropbox.com/s/5crp55r9jw98var/sortableTest.zip?dl=0
Well, here's what worked for me.
I edited the jquery.js. On jQuery.Event.prototype, inside the preventDefault function, there is:
if ( e.preventDefault ) {
e.preventDefault();
} else {
e.returnValue = false;
}
Basically, I changed the if condition to e.preventDefault && e.target.tagName != "INPUT". It solved the example, but in the real life I needed to add some more conditions to ensure that other input fields won't get caught by this.
Change in jquery.ui.touch-punch.js worked for me.
JS: jquery.ui.touch-punch.js
Method to modify:
//line: 31
function simulateMouseEvent(event, simulatedType) {
//...
}
//changes to add ++
if ($(event.target).is("input") || $(event.target).is("textarea")) {
return;
} else {
event.preventDefault();
}
I know this is an old question but got the following to work for me without modifying the JS files:
let detectTap = false;
$('body').on('touchstart', '#sortableMenu input', () => {
detectTap = true;
});
$('body').on('touchmove', '#sortableMenu input', () => {
detectTap = false;
});
$('body').on('touchend', '#sortableMenu input', (e) => {
if (detectTap) $(e.target).focus();
});
Basically just adding a tap listener on the inputs, and when it gets the tap, focus on that input.

Unable to get touch events on WP 8.1 Webview . jquery mobile

I have a website that uses jquery mobile to detect touch interaction.
It works fine when I test it on the desktop, but when I try to use it embedded in a Windows Phone 8.1 WebView App, no touch events are triggered.
What am I missing here?
-edit-
ok here is some code I am using:
<script>
$(function () {
jQuery(window).on("swipe", function (event) { NotifyApp("Test"); });
});
</script>
The called NotifyApp function looks like this:
function NotifyApp(message) {
if ((typeof (window.external) !== "undefined") && (typeof (window.external.notify) !== "undefined")) {
window.external.notify(message);
}
}
NotifApp() works as expected, the app is notified by this function when I call the it manually by a button.

How to handle longtap on utfgrid with leaflet

I'm trying to get a longtap to work on a utfgrid using leaflet/mapbox.
Normally I'd think jQueryMobiles "taphold" or leaflets "contextmenu" would work (and they do... on the map) but nothing when trying to use it with the utf gridLayer.
I currently use this for a simple tap/click on the grid which works fine.
gridlayer.on('click', function (e) {
console.log(e.data);
});
But what I really want to do is this.
gridlayer.on("contextmenu", function(e){
//do something else
});
or
gridlayer.on("taphold", function(e){
//do something else
});

Resources