I'm experiencing a ~500ms delay in Safari for iOS when binding the touchstart event to a KineticJS circle object. I've tried calling event.preventDefault() within the on function, thinking that this would override the default iOS behavior, but it made no difference. I'm not sure whether this has anything to do with KineticJS, which is why I left that out of the title (but included it as a tag). Note: there is no delay using the iOS simulator – the delay is only happening on the actual device (iPhone 4). Any ideas?
var stage = new Kinetic.Stage({
container: "container",
width: $(window).width(),
height: $(window).height(),
});
var layer = new Kinetic.Layer();
var circle = new Kinetic.Circle({
x: stage.getWidth() / 2,
y: stage.getHeight() / 2,
radius: 70,
fill: "black",
});
layer.add(circle);
stage.add(layer);
circle.on("touchstart", function() {
this.setFill("red");
layer.draw();
});
There is a ~300ms delay on mobile browsers while the browser waits to see if it's a single or double tap (since double-tap is for zoom).
This can be removed on recent builds of Android devices by using:
<meta name="viewport" content="width=device-width">
However, Mobile Safari doesn't follow this same logic, and there's no way to disable this delay.
You can read more about this here: http://updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away
Related
I have an iOS app that compiles and works fine with Titanium SDK 5.1.1GA but it would not work correctly with either of 5.1.2 GA or 5.2.0 GA.
The issue is with a scrollView in which events are not being fired with the newer SDKs. It is a lot of code to post all of it. The scrollView is the last of four in a ScrollableView and it is being created like this:
function SettingsView() {
var self = Ti.UI.createScrollView({
width: Ti.UI.FILL,
});
var helpButton = Ti.UI.createButton({
title: "HELP",
width: Ti.UI.FILL,
height: Ti.UI.FILL,
color: "black",
});
self.add(helpButton);
helpButton.addEventListener("click", function(){
Ti.API.info("helpButton> Clicked!!");
});
helpButton.addEventListener("touchstart", function(){
Ti.API.info("helpButton> touchstart!");
});
helpButton.addEventListener("touchend", function(){
Ti.UI.info("helpButton> touchend!");
});
return self;
}
The default animation on the button is working - I can see the color changing as I tap on it - but none of the events are fired.
Elsewhere in the code events on views and buttons are working with the newer SDKs.
I have tried all sorts of things but have not been able to make the events on objects inside that scroll view fire. The only thing that has worked so far is changing the SDK to 5.1.1 or earlier.
I would appreciate any help.
Thank you!
This is a bug, tracked at the Appcelerator JIRA:
https://jira.appcelerator.org/browse/TIMOB-20493
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)
Has any one encountered this already ? I put iAd with the code below in titanium studio and when the app loads in show a white rectangle which is where iAd should go thent it disappears ?
var iads = Ti.UI.iOS.createAdView({ width: 320, top: 100, backgroundColor: 'transparent', zIndex:200 });
t1 = Titanium.UI.createAnimation({bottom:0, duration:750});
iads.addEventListener('load', function(){
iads.animate(t1);
});
Titanium.UI.currentWindow.add(iads);
If you didn't change anything else (like switching to a different Titanium Mobile SDK) then this must have been something between you and Apple. Perhaps something going wrong between their sandbox and your simulator.
How can I use JavaScript to set the zoom level on mobile safari?
[UPDATED] It seems that you want to capture double taps in mobile Safari. You could do that by handling the touchend event, or use an available framework, such as provided in this site.
Take a look at the revised demo: http://jsbin.com/atayo4/20
<p id="tap">double tap to zoom</p>
<input id="zoomWidth" type="text" value="400" />
<p id="feedback"></p>
$(document).ready(function(){
$('#tap').doubletap(
// double tap handler
function(e) {
$('#feedback').addClass('red').html('double tap! Zoom width: ' + $('#zoomWidth').val());
var zoomWidth = $('#zoomWidth').val();
// zoom with the new width
$('meta[name="viewport"]').attr('content', 'width=' + zoomWidth + ', user-scalable:no');
$('#zoomWidth').val(parseInt(zoomWidth, 10) - 25);
},
// single tap handler
function(e) {
$('#feedback').removeClass('red').html('single tap! Zoom width: ' + $('#zoomWidth').val());
},
// double tap delay, default 500
400
);
});
As far as I know, you can change the zoom factor the text size by changing the style '-webkit-text-size-adjust' of body element.
Check this link for more information:
http://developer.apple.com/library/safari/#documentation/AppleApplications/Reference/SafariCSSRef/Articles/StandardCSSProperties.html%23//apple_ref/doc/uid/TP30001266--webkit-text-size-adjust
I tried manipulating the min/max scales and width in the meta tag with JavaScript to no avail. Instead of trying to set the zoom level with code (I'm thinking it's not possible), I'm going to create small invisible boxes on top of my relatively large image. This will allow users to zoom in (and out) via native double-tap on interesting sections of the image.
Try this:
<meta name="viewport" content="width=device-width; initial-scale=1.0; user-scalable:no;">
Source
I'm using the jquery ui dialog for a modal popup dialog. It's working great in Firefox/Chrome but terrible in ie6.
Problem:
When I show the dialog in ie6, the browser window grows and automatically scrolls down to the bottom. The height increase and automatic scroll-down is equal to the height of the jquery dialog.
I can scroll up and then use the dialog as normal, but the behavior where it grows the window and drops is maddeningly unacceptable.
Here is how I'm launching the window:
<div id="dialogWindow"></div>
...
$(document).ready(function() {
var $dialog = $("#dialogWindow").dialog({
autoOpen: false,
modal: true,
minWidth: 560,
width: 560,
resizable: "true",
position: "top"
});
$('.addButton').click(function(e) {
e.preventDefault();
$('#dialogWindow').load('http://myurl');
$dialog.dialog('open');
});
});
I am already using the bgiframe plugin for jquery which is key for ie6 overlay issues. But this seems unrelated to that. Has anyone seen this before and found a work around?
I've seen this behavior before and it is usually caused by the overlay. When you use the {modal: true} option an overlay is created and rendered with bgiframe support if the plug-in is loaded.
First off, try turning {modal: false} and see if you aren't getting page blow-out then we know it's the overlay.
there are a few things to check if that is the culprit;
check that the styles for the overlay are loading correctly, you'll need to include the jquery-ui dialog.css
try experimenting with position: and float: styles
try moving your dialog markup just above the < / body> tag, allowing the modal overlay to escape correctly.
I had a similar problem at one point.
$('.addButton').click(function(e) {
e.preventDefault();
$('#dialogWindow').load('http://myurl');
var y = window.pageYOffset;
var x = window.pageXOffset
$dialog.dialog('open');
window.scrollTo(x, y); // horizontal and vertical scroll targets
});
What the above should do is grab your current scroll coordinates and saves them. Once the dialog opens you then scroll back to the prior position in memory. Should be near instant and unseen by the user.