It seems as javascript:
$(function() {
setInterval( "slideSwitch()", 5000);
})
never fires while scrolling on the iPad/safari. Is there any workaround for this?
(on android stock browser ok)
It is not so easy as it seems. When I was need functionality like that, I began to use the iScroll library with small changes in the source.
I've used it with the CSS provided in the "ios-perfect-scrollbar" example, and onScrollMove event. But to fire this event even on "momentum scrolling", you'll need to add
if (that.options.onScrollMove) that.options.onScrollMove.call(that, e);
at the end of "animate" function.
Related
I got event listener to the scroll and everything works fine with desktop browsers(when scrolling starts - the event fired straight away) and chrome browser in mobile(chrome latest version + android version 5.0), but with other mobile browsers(ff, android browser) this works differently, and after googling for some I found the reason: it's because the scroll event is not fired until the scrolling action comes to a complete stop(releasing the finger from the screen).
My question is there some workaround for this, perhaps some best practice, so it will fire normally(as for desktop) and without dramatically performance changes?
*JS solution only(no for jquery).
You can use iScroll. It does not depend on jQuery and achieves what you want ( firing scroll events on mobile platforms ~continuously ) among other things.
You can refer to this answer for how to implement this using iScroll.
I agree the answer of Mohit Bhardwaj and I just want to say some important thing about iScroll.
The iScroll runs depend on css3 translate and the js event such as touchMove, touchStart and touchEnd. You can just think it handle the whole scroll system in your page or the element container you set it to handle.
One thing you should know, if you want to listen the scroll event in iScroll, you must import the iscroll-probe.js, and set the probeType param with 2 or 3. Otherwise you would not get the scroll event.
The iScroll version 5 is good, I use it in a lot of project. You can see it docs and code
here
Here's something odd, that I felt sure was working in earlier mobile browsers: In Chrome on Android, and Safari on iOS, it seems the touchstart event is fired after the click event, not before. When did this change?
A simple example:
jQuery(function($) {
var touched = false;
$('#clicky').on('touchstart', function(evt){
touched = true;
evt.preventDefault();
})
.click(function(){
if (!touched) {
alert("somehow touch didn't fire")
}
});
})
Run this fiddle, and you'll see the alert can pop up on Android and iOS, when it should actually never show!
http://jsfiddle.net/quxnxu7d/2/
I ran it through Chrome on Android and it worked as you expected for me. I added an alert to the touchstart handler and it fired to be sure that it was firing first and it did.
Take a look at the touch events mdn article. The article specifically mentions:
calling preventDefault() on a touchstart or the first touchmove event of a series prevents the corresponding mouse events from firing
Click is a mouse event so it "should" work as you expect (and it was working for me). I'd verify that the events are indeed running out of order (use console.log() instead of alert()) on your target browsers. If they are, which is perfectly possible with less than perfect browsers/specs, try using a different mouse event like mouseup. My guess is that you'll be able to find an event that works consistently.
Good luck!
Have you tried using mousedown instead of click? That way you should get different events for touch and click without any double firing. You will also likely need to use keydown to keep this site accessible.
There is a 300ms delay between a physical tap and the firing of a click event on some mobile browsers (e.g. iOS Safari)
I ran into the same issue and FastClick jQuery plugin fixed it for me
Have a look FastClick
I have made a simple carousal using an online script called "simplyScroll".
here is the link to the script:
http://logicbox.net/jquery/simplyscroll/#config
My Problem:
here is the link the page:
http://namdarshirazian.com/exhibition.php
Generally in desktop mode, when I click on each image, it runs a javascript and shows a popup. This javascript is written by myself. Simply a simple action of hide and show.
But when viewed with smartphone (android/firefox), it does not triggers click event. VERY STRANGE. Can anyone please help my why this does not work?
The click action is as simple as :
$("body").on("click", "element", function(){
});
You can experiment with touchup and touchdown events instead. It's actually a right mess caused by people worrying about touches being long. The fastclick library might smooth things out a bit.
i had the same problem when i did my website responsive for any device resolution, the solution is simple, you write your jQuery as standard but u have to include a script that will allow the jQuery to work on touch devices.
add this script into your website and check the magic result:
http://touchpunch.furf.com/
I am working with AngularJS calendar (Which is essentially jQuery Full Calendar by Adam Shaw wrapped for angular). Here, the calendar event-item clicks worked both in ipad and desktop fine, until I brought in fastclick.js by ft labs (https://github.com/ftlabs/fastclick). Now, calendar event-item clicks works only on desktop, but not working at all on the ipad!
However, other ng-clicks work fine with fastclick both on desktop and iPad.
I understand how fastclick.js works by simply adding touch-end event listeners and calling click events within them, and cannot understand why this would fail with calendar event-item clicks.
Note: I tried using ngTouch instead of fastclick, but their, the ng-click doesn't become fast. According to google, ngTouch's ng-click cannot be used with jQuery
if all else fails you can inspect which events are linked to your elements with visual event: http://www.sprymedia.co.uk/article/visual+event
This adds an overlayer to any web page and let you visually inspect the JS code that's linked to an element (it shows you the piece of code in a pop up).
this way you can easily see if everything is set up correctly.
PS: I have no link to this tool or it's makers.
I had similar issue. fastclickjs blocks every jQuery .click() . But if you dispatch event without jQuery everything works fine.
Well this is an old question, but maybe it helps somebody.
I had a similar problem, and even fastclick.js didn't help and wasn't fast enough on the iPad.
The problem is that on a normal browser click event (on an iPad) has a delay of 300ms on touchstart and again 300ms on touchend.
fastclick.js also had some conflicts like yours with the calendar.
So i just wrote an own directive and called it ng-mobile-click.
Directive ngMobileClick:
App.directive("ngMobileClick", [function () {
return function (scope, elem, attrs) {
elem.bind("touchstart click", function (e) {
e.preventDefault();
e.stopPropagation();
scope.$apply( attrs["ngMobileClick"] );
});
}
}]);
Usage in templates:
<input type="button" value="somevalue" ng-mobile-click="someFunction(someParam)"/>
Advantage:
Will never conflict with standard click events.
Disadvantage
You have to refactor your code where you need it
I've read that mobile Safari has a 300ms delay on click events from the time the link/button is clicked to the time the event fires. The reason for the delay is to wait to see if the user intends to double-click, but from a UX perspective waiting 300ms is often undesirable.
One solution to eliminate this 300ms delay is to use jQuery Mobile "tap" handling. Unfortunately I'm not familiar with this framework and don't want to load some big framework if all I need is a line or two of code applying touchend in the right way.
Like many sites, my site has many click events like this:
$("button.submitBtn").on('click', function (e) {
$.ajaxSubmit({... //ajax form submisssion
});
$("a.ajax").on('click', function (e) {
$.ajax({... //ajax page loading
});
$("button.modal").on('click', function (e) {
//show/hide modal dialog
});
and what I'd like to do is to get rid of the 300ms delay on ALL those click events using a single code snippet like this:
$("a, button").on('tap', function (e) {
$(this).trigger('click');
e.preventDefault();
});
Is that a bad/good idea?
Now some mobile browsers eliminate 300 ms click delay if you set the viewport. You don't need to use workarounds anymore.
<meta name="viewport" content="width=device-width, user-scalable=no">
This is currently supported Chrome for Android, Firefox for Android and Safari for iOS
However on iOS Safari, double-tap is a scroll gesture on unzoomable pages. For that reason they can't remove the 300ms delay. If they can't remove the delay on unzoomable pages, they're unlikely to remove it on zoomable pages.
Windows Phones also retain the 300ms delay on unzoomable pages, but they don't have an alternative gesture like iOS so it's possible for them to remove this delay as Chrome has. You can remove the delay on Windows Phone using:
html {
-ms-touch-action: manipulation;
touch-action: manipulation;
}
Source: http://updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away
UPDATE 2015 December
Until now, WebKit and Safari on iOS had a 350ms delay before single taps activate links or buttons to allow people to zoom into pages with a double tap. Chrome changed this a couple of months ago already by using a smarter algorithm to detect that and WebKit will follow with a similar approach. The article gives some great insights how browsers work with touch gestures and how browsers can still get so much smarter than they are today.
UPDATE 2016 March
On Safari for iOS, the 350 ms wait time to detect a second tap has been removed to create a “fast-tap” response. This is enabled for pages that declare a viewport with either width=device-width or user-scalable=no. Authors can also opt in to fast-tap behavior on specific elements by using the CSS touch-action: manipulation as documented here (scroll down to the 'Styling Fast-Tap Behavior' heading) and here.
This plugin -FastClick developed by Financial Times does it perfectly for you!
Make sure though to add event.stopPropagation(); and/or event.preventDefault(); directly after the click function, otherwise it might run twice as it did for me, i.e.:
$("#buttonId").on('click',function(event){
event.stopPropagation(); event.preventDefault();
//do your magic
});
i know this is old but can't you just test to see if "touch" is supported in the browser? Then create a variable that's either "touchend" or "click" and use that variable as the event that gets bound to your element?
var clickOrTouch = (('ontouchend' in window)) ? 'touchend' : 'click';
$('#element').on(clickOrTouch, function() {
// do something
});
So that code sample checks to see if the "touchend" event is supported in the browser and if not then we use the "click" event.
(Edit: changed "touchend" to "ontouchend")
I've come across a hugely popular alternative called Hammer.js (Github page) which I think is the best approach.
Hammer.js is a more full-featured touch library (has many swipe commands) than Fastclick.js (most upvoted answer).
Beware though: scrolling fast on mobile devices tends to really lock up the UI when you use either Hammer.js or Fastclick.js. This is a major problem if your site has a newsfeed or an interface where users will be scrolling a lot (would seem like most web apps). For this reason, I'm using neither of these plugins at the moment.
Somehow, disabling zoom seems to disable this small delay. Makes sense, as double-tap isn't needed anymore then.
How can I "disable" zoom on a mobile web page?
But please be aware of the usability impact this will have. It may be useful for webpages designed as apps, but shouldn't be used for more general-purpose 'static' pages IMHO. I use it for a pet project that needs low latency.
Unfortunately there is no easy way to do this. So just using touchstart or touchend will leave you with other problems like someone starts scrolling when click on on a button for example. We use zepto for a while, and even with this really good framework there are some issues that came up over the time. A lot of them are closed, but it seems is not a field of simple solution.
We have this solution to globally handle clicks on links:
$(document.body).
on('tap', 'a',function (e) {
var href = this.getAttribute('href');
if (e.defaultPrevented || !href) { return; }
e.preventDefault();
location.href= href;
}).
on('click', 'a', function (e) {
e.preventDefault();
});
I searched for an easy way without jquery and without fastclick library. This works for me:
var keyboard = document.getElementById("keyboard");
var buttons = keyboard.children;
var isTouch = ("ontouchstart" in window);
for (var i=0;i<buttons.length;i++) {
if ( isTouch ) {
buttons[i].addEventListener('touchstart', clickHandler, false);
} else {
buttons[i].addEventListener('click', clickHandler, false);
}
}
In jQuery you can bind "touchend" event, witch trigger code inmediatly after tap (is like a keydown in keyboard). Tested on current Chrome and Firefox tablet versions. Don't forget "click" also, for your touch screen laptops and desktop devices.
jQuery('.yourElements').bind('click touchend',function(event){
event.stopPropagation();
event.preventDefault();
// everything else
});
Just to provide some extra information.
On iOS 10, <button>s on my page could not be triggered continuously. There was always a lag.
I tried fastclick / Hammer / tapjs / replacing click with touchstart, all failed.
UPDATE: the reason seems to be that the button is too close to the edge! move it to near the center and lag gone!
You're supposed to explicitly declare passive mode :
window.addEventListener('touchstart', (e) => {
alert('fast touch');
}, { passive : true});