jquery touchswipe plugin not working proeperly on iOS - javascript

So basically I'm developing a website where the scroll event's default is prevented and instead each scroll takes you down or up to the next "section". This works really well on PC and some phones but on iOS the scrolling just becomes this jumbled up mess and quite frankly I'm out of ideas.
The scroll API for mobile I'm using is jquery touchSwipe
https://github.com/mattbryson/TouchSwipe-Jquery-Plugin
And the following code is the function that is supposed to do all the work.
if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
$(window).swipe({
swipe:function(event, direction, distance, duration, fingerCount, fingerData) {
if (scrolling == false && direction === "down") {
scrolling = true;
scrollSection = Math.round($(window).scrollTop()/window.innerHeight);
scrollTo_(event,sections[scrollSection-1]);
setTimeout(function() {
scrolling = false;
}, 1000);
}
else if (scrolling == false && direction === "up") {
scrolling = true;
scrollSection = Math.round($(window).scrollTop()/window.innerHeight);
scrollTo_(event,sections[scrollSection+1]);
setTimeout(function() {
scrolling = false;
}, 1000);
}
}
});
}
If you have any questions by all means let me know and I will update this question.

Have you tried with this?
In my web app last days I've worked on Jquery UI slider, that's didn't worked for mobiles, so after attaching that it get's worked.

Related

hammer js > how to block horizontal panning during page scroll

I've got a page where I put some horizontal slideshows, and have added panning and swipe to them. Sadly, when scrolling on mobile devices, if you scroll above the slideshows, hammer will recognize panning and leave slideshows a little panned... Not so beautiful. I'm thinking about various solutions, but the most obvious maybe would be to stop panning during scroll. Is it possible some way? Here's an extract of my current code (sorry there are methods coming from the parent class..):
if(this.options.touch_enabled){
this.hm = new Hammer(this.panels_box, {
recognizers: [
[Hammer.Swipe,{ direction: Hammer.DIRECTION_HORIZONTAL, threshold: 80 }]
,[Hammer.Pan,{ direction: Hammer.DIRECTION_HORIZONTAL, threshold: 80 }, ['swipe']]
]
,domEvents: false
});
this.hm.on('swipeleft', function(e){ if(this.options.next_condition()) this.goto('next', null, true); }.bind(this));
this.hm.on('swiperight', function(e){ if(this.options.prev_condition()) this.goto('prev', null, true); }.bind(this));
this.hm.on('panstart', function(e){ this.disable_transition(); }.bind(this));
this.hm.on('panend', function(e){ this.enable_transition(); }.bind(this));
this.hm.on('panleft', function(e){
if(!this.options.loop){ if(this.data_box.getAttribute('data-current') >= this.bounds.end) return; }
this.panels_strip.style.setProperty('--distance', e.deltaX + 'px');
}.bind(this));
this.hm.on('panright', function(e){
if(!this.options.loop){ if(this.data_box.getAttribute('data-current') <= 0) return; }
this.panels_strip.style.setProperty('--distance', e.deltaX + 'px');
}.bind(this));
}// touch
Solution for me was to check deltaY and deltaX, along with event type (since the issue was not found on desktop computers). Here an extract:
this.hm.on('panleft', function(e){ // ...and same for panright
if(e.pointerType == 'touch' && (Math.abs(e.deltaY) > Math.abs(e.deltaX))){ return false; }
// do stuff
}

Slider with touch function

I have created a simple slider. I want it also for smartphones and not only for desktops. So in this case it should be possible to let it slide when you move your finger from left to right or from right to left. For now it only works when you click on buttons.
I have no idea how to start with it. How can I do this?
var i = 0;
$('.next').bind('click', function() {
if (i < 4) {
$('li').animate({'left': '-=600px'}, 300).delay(600);
i++;
}
console.log($('li:first').position().left);
console.log(i);
});
$('.back').bind('click', function() {
if (i > 0) {
if ($('li:first').position().left < 0) {
$('li').animate({'left': '+=600px'}, 300).delay(600);
i--;
}
}
console.log(i);
});
https://jsfiddle.net/6t1wx95f/11/
PS: It should work without using a plugin.
I updated your fiddle: https://jsfiddle.net/6t1wx95f/13/
Tested in chrome (in responsive view to have the touch events working). Credit goes to this answer.
Basically, you just need to use touchstart and touchmove events. When you touchmove you just take your X position and compare it to where it was when touch-started.
See the touch events docs. It's all in vanilla javascript so you won't have to include any plugin.
// Set up events
var slider = document.getElementsByClassName('slider')[0];
slider.addEventListener('touchstart', handleTouchStart, false);
slider.addEventListener('touchmove', handleTouchMove, false);
..and
if ( xDiff > 0 ) {
/* left swipe */
slideRight();
} else {
/* right swipe */
slideLeft();
}

JQuery window.scroll() not working for mobile

I am working on a Infinite scroll (on a div which have large number of subdiv)
infinite scroll is working for Desktop device but not for mobile devices
i checked that window.scroll function not getting fired for mobile device
i checked for some other events like OnTouchStart etc .. but none is working
Here is infinite scroll fiddle Infinite Scroll Fiddle
Here is infinite scroll project code example
infinitescroll: function() {
var $doc=$(document);
var $win=$(window);
var itemsPerScroll=5;
// hide everything that is out of bound
$('.scroll').filter(function(index){
return (($(this).offset().top) > $win.height());
}).hide();
$(window).scroll(function(event){
#event.preventDefault();
alert("here");
if ($doc.height()-$win.height()-$(this).scrollTop() == 0) {
$('.scroll:hidden:lt('+itemsPerScroll+')').show();
}
});
},
Alter the code to this and it should fix it -
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|Windows
Phone/i.test(navigator.userAgent) == false) {
$(document).height() - window.visualViewport.height;
$('.article').filter(function(index){
return (($(this).offset().top) > $win.height());
}).hide();
$(window).scroll(function(){
if ($doc.height()-$win.height()-$(this).scrollTop() == 0) {
$('.article:hidden:lt('+itemstoshow+')').show();
}
})};

disable click link on touch devices not working as expected

what I'm trying to do
I have dropdown-menus that open on hover and the parent menus have their own landing page link. we're not willing to sacrifice this behavior, but if obviously creates problem for large touch enabled devices. So, I'm detecting touch devices with jquery, and disabling the parent menu click on devices larger than 990px wide. devices below 990px is considered as mobile view and it switches to toggle. This switch between the toggle and the desktop view is expected to continue on screen rotation too.
what is happening
the menu link is disabled on first load and works as expected. Then I rotate the screen (from landscape to portrait) and see the mobile menu as expected and navigate to another page. once the page loads, I rotate it again (from portrait to landscape) and the desktop view is visible, but the parent links are clickable now!
I want to prevent this click event on second rotation too. HTML is standard bootstrap 3 navigation code and my js is like this:
function isTouchDevice() {
return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
$(document).ready(function () {
$(window).resize(function () {
var o = $(window).innerWidth();
function isTouchDevice() {
return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
if ((isTouchDevice() === true) && (o >= 990)) {
$('.navbar .dropdown > a ').each(function () {
$(this).on("click", function(){
return false
})
})
alert('oi!!')
}
else {
$('.navbar .dropdown > a ').each(function () {
$(this).on("click", function(){
location.href = this.href;
})
});
alert ("bad!") //for debugging purpose, not really needed
}
}).resize();
//the mobile menu clicks events
$('#menu .dropdown > a ').click(function () {
location.href = this.href;
});
});
PS this is a website, not an android app. I have found answers that answer this type of questions for android apps.
Update the jsfiddle for my code
I solved it myself. Turns out, the condition for width checking was creating the problem and in my case, unnecessary, because bootstrap is already hiding the menu in smaller screens and I was targeting touch enabled desktop devices anyway. so I took off && (o >= 990) from the if condition and it is working as expected.
full js is below (in case anyone needs it). I used the timer to prevent the event from firing before the resize, but it will probably work without the timer too. :
$(document).ready(function () {
var resizeTimer;
$(window).on('resize', function(e){
clearTimeout(resizeTimer);
resizeTimer = setTimeout(function () {
function isTouchDevice() {
return true == ("ontouchstart" in window || window.DocumentTouch && document instanceof DocumentTouch);
}
if (isTouchDevice() === true) {
$('.navbar .dropdown > a ').click(function () {
return false
});
console.log("landscape")
}
else {
$('.navbar .dropdown > a ').each(function () {
$(this).on("click", function(){
location.href = this.href;
})
});
console.log("portrait")
}
}, 250)
}).trigger('resize');
});
I think this is a problem with the way you are recognizing the mobile device. For checking device sizes I would not suggest using $(window).innerWidth(). What you are doing now does not check the screen size, rather it checks the window size, which fluctuates when switching orientation.
I would like to suggest that instead of checking for only >900px, that you check for the entire area of the device (width x height) so landscape and portrait would act the same way. And I would like to suggest using screen.availHeight * screen.availWidth to determine this.
I really hope this helps you with your problem. Please let me know if not and I'll help you debug.

How to detect user mouse wheel scroll distance?

I am trying to detect user scroll, if to left and to right then trigger and do something.
But if user use trackpad scroll to top or to bottom then it will accidentally scroll to left or to right.
I think, may be not just check timer define per scroll also need to check if user scroll distance smaller than 20, we can differentiate that as accidentally and don't do anything.
I can't find the way check if user scroll distance, the element is not be scrollable so can't use scrollTop scrollLeft....
Any idea?
var scroll_timer;
$('img').bind('mousewheel', function(e) {
if (e.originalEvent.wheelDeltaX < 0) {
clearTimeout(scroll_timer);
scroll_timer = setTimeout(function() {
// .. do something
// console.log('right');
}, 200);
} else if (e.originalEvent.wheelDeltaX > 0) {
clearTimeout(scroll_timer);
scroll_timer = setTimeout(function() {
// .. do something
// console.log('left');
}, 200);
}
});
Here is my JSFiddle
It looks like you can use e.originalEvent.wheelDeltaX to get scroll distance values. You could then use e.originalEvent.wheelDeltaY to see if the user is scrolling vertically more than horizontally and trigger stuff after that is true.
Here's a demo that works by testing if the value of scrolling Y is less that scrolling X and then allowing you to trigger if it's left or right after that. Seems to do the trick on my mac trackpad
var scroll_timer;
$('img').bind('mousewheel', function(e) {
if((Math.abs(e.originalEvent.wheelDeltaX) > Math.abs(e.originalEvent.wheelDeltaY)))
{
if (e.originalEvent.wheelDeltaX < 0) {
clearTimeout(scroll_timer);
scroll_timer = setTimeout(function() {
// .. do something
console.log('right');
}, 200);
} else if (e.originalEvent.wheelDeltaX > 0) {
clearTimeout(scroll_timer);
scroll_timer = setTimeout(function() {
// .. do something
console.log('left');
}, 200);
}
}
});
http://jsfiddle.net/andyface/5CfgT/

Categories