Is it possible to write the following, in order to cover all eventualities in terms of making something clickable on desktop and mobile (with jQuery Mobile)?
$('.persOpen').on('click vclick tap', function() {
// do stuff
});
Related
Selection of words in an autocomplete input field (within a dialog) is not working properly when using JQuery UI in combination with Touch Punch. It seems to work if the autocomplete field is directly on the HTML page, but not in a dialog.
Note that selection by mouse is working perfectly in all cases, but selection by touch (i.e. on mobile device) not.
I have reduced the whole case to a few lines of HTML and JavaScript code.
Once with JQuery UI Touch Punch, once without JQuery UI Touch Punch.
I am able to reproduce the error with all combinations of browser and OS, e.g. Chrome on an iPhone, Chrome on an Android mobile as well as with Safari on an iPad,
Would be nice if somebody knows a workaround.
I think this behavior is a result of the fact that on one the one hand Touch Punch developers are not that smart and on the other hand jQuery UI seems to be not very cooperative with Touch Punch.
There are two ways how mouse event might be triggered:
browser might simulate click events after touch events
some library might simulate click events after touch events
Your example without Touch Punch works because mobile browsers currently simulate click events.
So how Touch Punch works and how it messes things up? If you look at the source code https://github.com/furf/jquery-ui-touch-punch/blob/master/jquery.ui.touch-punch.js you'll see that it wraps $.ui.mouse.prototype._mouseInit with its own code and the main intention is to attach various touch-related listeners for all widgets that inherit $.ui.mouse. So far so good. But what exactly those listeners do? The _touchStart handler runs a check using $.ui.mouse internal API:
self._mouseCapture(event.originalEvent.changedTouches[0])
to check if it needs to simulate mouse events. The logic is: if there is no click handler in the widget, there is no need to simulate click. It looks OK at the first glance but what's going wrong? The autocomplete widget puts its dropdown menu to the outside context of the containing dialog and thus touch events on the menu items actually hit listeners registered by touch-punch for the dialog (or rather for its draggable and resizable sub-components). But the dialog subcomponents have no click listeners and thus events are not simulated by the library. Moreover, draggable in your version (see https://github.com/jquery/jquery-ui/blob/1-11-stable/ui/draggable.js) calls
this._blurActiveElement( event );
unconditionally and this seems to stop browser from generating mouse events. So now neither browser nor library simulate click event.
It seems that in the development branch of jQuery UI the bug is fixed https://github.com/jquery/jquery-ui/commit/8c66934434214ab92cbcf46240beb739154fdfbf but for a bit different reason. This fix seems to be available in the jQuery UI 1.12.1 but not in your 1.12.0
So the simplest solution seems to be to upgrade jQuery UI to 1.12.1
See working demo with jQuery UI 1.12.1 at https://jsfiddle.net/cjvgv102/1/ and http://jsfiddle.net/cjvgv102/1/embedded/result/
Ugly hack (stop here unless you really have to)
If for some reasons you can't upgrade jQuery UI, you can do a hack by explicitly creating a fake mouse object on the dropdown and calling its _mouseInit so event will not be handled by dialog's sub-components.
$( "#demoDlg" ).dialog({
autoOpen: false,
modal: true,
buttons: {
"Close": function() {
$( this ).dialog( "close" );
}
},
open: function(event, ui) {
$( "#words" ).autocomplete({
source: ["these", "are", "some", "words"]
});
// super-hack
$( "#words" ).autocomplete("instance").menu.element.mouse().mouse("instance")._mouseInit();
}
});
See full demo at
https://jsfiddle.net/3ptgks3t/1/
I've got a small jsfiddle - http://jsfiddle.net/qhguktsn/5/. When you tap the text at the top of the link (iOS mobile Safari), you get only the mouse events- no touch events at all, not even on the body. If you tap it on the bottom of the text, you get touch events. We depend on touch events for handling 300ms delay.
How can we get touch events for tapping on the top of the text as well as the bottom?
HTML:
<div style="margin-left:200px;margin-top:200px">
<a style="vertical-align:center;height: 20px, width: 20px;font-size:100px" href="javascript: void 0">text</a>
</div>
JS:
jQuery("a").on("mousedown", function() { document.body.appendChild(document.createTextNode("mousedown ")); });
jQuery("a").on("mouseup", function() { document.body.appendChild(document.createTextNode("mouseup ")); });
jQuery("a").on("touchstart", function() { document.body.appendChild(document.createTextNode("touchstart ")); });
jQuery("a").on("touchend", function() { document.body.appendChild(document.createTextNode("touchend ")); });
jQuery("a").on("click", function() { document.body.appendChild(document.createTextNode("click ")); });
jQuery(document.body).on("touchstart", function() { document.body.appendChild(document.createTextNode("body touchstart ")); });
jQuery(document.body).on("touchend", function() { document.body.appendChild(document.createTextNode("body touchend ")); });
This is know bug in Mobile Safari. https://bugs.webkit.org/show_bug.cgi?id=105406
There is another one as well with adding node form different document. https://bugs.webkit.org/show_bug.cgi?id=135628
In order to fix them there are several ways.
The first one is to use a small library called fastclick, which supports many mobile devices and OS.
The second options is to add event.stopPropagation(); event.preventDefault(); like that. You need both of them.
jQuery("a").on("mousedown", function(event) {
event.stopPropagation();
event.preventDefault();
document.body.appendChild(document.createTextNode("mousedown "));
});
The third option is by using the viewport meta tag like that <meta name="viewport" content="width=device-width, user-scalable=no">. This will eliminate all touch delays, without any workarounds. But, again on Safari it may not act like in the other browsers, because hey Safari is the new IE
There is also touch-action, but it's not supported in most of the mobile browsers. :(
The touch events on the body are due to the body element being shifted down by the margin-top, putting an outline on the body element outlines the touch-target:
body { outline: 1px solid red; }
http://jsfiddle.net/qhguktsn/11/
The second part of the mystery seems to be that the click target expands outside the touch-target:
Touching the red outline will not trigger a touch event on the body element, but the click event seems to fire when tapped anywhere within the grey -webkit-tap-highlight-color region which expands outside the anchor itself. Taps at the very top will therefore trigger click events on the anchor, but not touch events on the body.
I found that the touch event is not fired when clicking on an element contained by a position:fixed element that extends beyond the window. I handled this by making the parent container shorter (used JS to get the exact window height).
This problem was in an app UIWebview using iOS 10. (Yes, still using UIWebview)
I'm using jQuery BlockUI Plugin, and it pops up an image over the homepage. I want to be able to click outside of the image anywhere and be able to close it on smart phones.
I set this code, and it only works on Desktop, but NOT on Mobile:
$(document).ready(function() {
$('#demo9').click(function() {
$.blockUI();
$('.blockOverlay').attr('title','Click to unblock').click($.unblockUI);
});
});
Try binding the event with .on() in case there is a timing issue where the overlay does not exist yet:
$(".blockOverlay").on("click", function(){ $.unblockUI });
or
$(document).on("click", ".blockOverlay", function(){ $.unblockUI });
Also, does it make any difference if you use vclick instead of click?
Using touchstart with click works on Iphone, Kindle, Ipad
$('.blockOverlay').attr('title','Click to unblock').on('click touchstart',$.unblockUI);
(Note I have not yet tested this in IE FF or Safari, I'm hoping there is some setting on the autocomplete to make this work...)
In Chrome, when I type some text into a box that triggers a jQuery UI autocomplete dropdown to appear, the dropdown disappears when I switch focus to another application (my programming app Visual Studio).
Is there a setting to make the autocomplete drop down menu "stick" and remain visible when the browser loses focus in the operating system?
When you switch to another application an onblur event will be fired by the browser which is what hides the autocomplete menu. Your best bet to accomplish this "sticky" behavior is to attach an onfocus event handler to the window and open the autocomplete menu then.
$(function() {
var autocomplete = $( 'whatever' ).autocomplete();
$( window ).on( 'focus', function() {
autocomplete.autocomplete( 'search' );
});
});
I have a live example of this here - http://jsfiddle.net/RmALY/1/show/.
All I want to do is capture the event that a user taps an and clear it. I can't get anything to work with iPhone 3GS.. There is barely any documentation on how to actually use jQuery mobile.. that I can find anyway.. so theese are my guesses mostly:
$("#wrap").live('pageinit', function() {
$('#search_field').live('tap',function(event) {
if ($(this).val() == "Search Applications") {
$(this).val('');
}
});
});
This borks my design and adds a "loading" header at the bottom of the page....
Edit: Seems like it randomly works on the 3GS but the most annoying is that just jQuery mobile destroys my site layout!! my submit button jumps down
()
just looking over you code are you trying to use a place holder and clear it if the user taps it? If so you can simply add an attribute to your HTML5 like this:
<imput type="text" placeholder="Search Applications" />
Live example:
http://jsfiddle.net/KVuvm/
http://jsfiddle.net/KVuvm/1/ (With jQM Look and Feel)
http://jsfiddle.net/KVuvm/14/ (if you still wanted to use JS)