Horizontal swipe gesture and vertical page scroll - javascript

I am building a mobile site and I have a slide show of images that allows sliding through images horizontally. The javascript library I'm using is bxslider. However, if one touches the slide show and wants to scroll the page up/down, the slide show blocks vertical scrolling and hence another section of the site must be touched.
Could someone please tell me how I could keep vertical scroll enabled (i.e, not allow the slideshow to block the normal scroll?)
Thanks!

Try this, Change the onTouchMove fn in the bxslider library to this
var onTouchMove = function (e) {
if (slider.settings.mode != 'fade') {
var orig = e.originalEvent;
var value = 0;
// if horizontal, drag along x axis
if (slider.settings.mode == 'horizontal')
{
var hchange = orig.changedTouches[0].pageX - slider.touch.start.x;
var vchange = orig.changedTouches[0].pageY - slider.touch.start.y;
if(Math.abs(hchange)>20 && Math.abs(hchange)>Math.abs(vchange))
{
value = slider.touch.originalPos.left + hchange;
setPositionProperty(value, 'reset', 0);
e.preventDefault();
}
// if vertical, drag along y axis
} else{
e.preventDefault();
var change = orig.changedTouches[0].pageY - slider.touch.start.y;
value = slider.touch.originalPos.top + change;
setPositionProperty(value, 'reset', 0);
}
}
}

If you goto the options page for the bxslider website, search for preventDefaultSwipeX, and preventDefaultSwipeY
Those are what you are looking for.

Related

How to 'prioritise' a vanilla javascript if statement?

Currently experimenting for the first time with javascript. I'm trying to make a simple nav bar that disappears when the user scrolls down, reappears when they scroll up and does the same for when the mouse is in/out of the nav bar's area. Good news! Got that bit done.
The trouble comes when I then scroll up to make the nav bar appear, I move my mouse to click on it and then obviously a mouse event is triggered with the mouse outside of the hotspot and makes the nav bar disappear while you're on your way to it. It does reappear when I'm at the top with the mouse, but I'd like it to stay there once I've scrolled up to make it appear.
I have two if statements, one for the scroll and one for the mouse position. I'd like to make the site prioritise the effect of the scroll if statement over the mouse if statement.
This is the code I've stuck together after reading a hell of a lot of articles:
// Hide nav when scrolling down, show nav when scrolling up
var scrollCtrl = false;
var navbar = document.getElementById("navbar");
var prevScrollPos = window.pageYOffset;
window.onscroll = function() {
var currentScrollPos = window.pageYOffset;
if (prevScrollPos > currentScrollPos) {
navbar.classList.add('show');
var scrollCtrl = true;
} else {
navbar.classList.remove('show');
var scrollCtrl = false;
}
prevScrollPos = currentScrollPos;
}
// Get the height of the nav bar
var navHeight = getComputedStyle(document.getElementById("navbar")).height;
navHeight = navHeight.substring(0, navHeight.length -2);
navHeight = parseInt(navHeight, 10);
// Show nav when mouse is at the top
window.addEventListener('mousemove', function(e) {
var ypos = e.y;
if (ypos <= navHeight && scrollCtrl == false) {
navbar.classList.add('show')
}
else {
navbar.classList.remove('show')
}
});
What I've tried to do is use a boolean called scrollCtrl (because I want the scroll to be in control over the mouse position) but no matter what tweaks I make, I can't seem to get it to work.
The show/hide classes are just a CSS transform.
I am quite new to javascript, so please excuse any etiquette faux pas's!

Start Animations When Revolution Slider Scrolls Into View

I need to use Slider Revolution to animate content when the slider is scrolled into view. I already have working solution - http://www.themepunch.com/faq/start-animations-when-slider-scrolls-into-view/ but it has one serious bug.
When user already seen slider it start to animate again when user scrolling it again.
I want to make slide not to re-animate when user scroll to it after he already seen it.
Clarification: user scrolls down to slide - slide start to animate - (super!) - user go down to the end of the page - then go back - and slider start to animate from the beginning (bad (for me)). I want to make slider stop after he played the animation for first time.
Update with relevant code:
var win, slider, sliderHeight, sliderPaused = true, winHeight,
// Change the "revapi6" part here to whatever "revapi" name that your slider uses
slider = revapi6.on('revolution.slide.onloaded', function() {
win = jQuery(window).on('scroll', checkScroll).on('resize', sizer);
sizer();
});
function sizer() {
sliderHeight = slider.height();
winHeight = win.height();
checkScroll();
}
function checkScroll() {
var scrTop = win.scrollTop(),
offset = slider.offset().top;
if(offset <= scrTop + winHeight && offset + sliderHeight >= scrTop) {
if(sliderPaused) slider.revshowslide(2);
sliderPaused = false;
}
else {
if(!sliderPaused) slider.revshowslide(1);
sliderPaused = true;
}
}
It's in "Custom JavaScript" block in my slider settings. All just like here - http://www.themepunch.com/faq/start-animations-when-slider-scrolls-into-view/.
Site - uhhu.net
Resolve. Maybe it's not the best way, but it works and i don't know better
Comment this part
/*else {
if(!sliderPaused) slider.revshowslide(1);
sliderPaused = true;
}*/
I let you here my solution:
1- Go to Slider Revolution:
2- Select your slider:
3- Click on Slider Settings Tab:
4- In the right panel click on "Parallax and 3D" and compare with your current configuration:
5- In the right panel click on "Scroll Effects"(bellow of "Parallax and 3D") and compare with your current configuration:
6- To finish Save the configurations:

how to ignore lots of scroll-events due to smooth scrolling of browser?

i'm trying to implement such a feature:
webpage has two columns. narrow left one - with menu and some info, and wide right one - with the main content of page. height of the left column is much smaller than the right's one
so when user scrolls down the webpage and the left narrow column is already above the viewport, it gets hidden giving extra width for right column.
after i hide the left column i should scroll browser's window little bit upper in order to corresponding element on the right gets placed on the top of viewport (it jumps upper when i hide the left col, because the width of right col gets increased)
i've implemented this, but the problem is in smooth scrolling in all modern browsers. when you press down key or page down or mousewheel or use your finger in touch-devices, browser generates a lot of scroll-events during one scroll.
it looks like this:
scrollTop == 500
scrollTop == 520
scrollTop == 530
scrollTop == 535
scrollTop == 537
and the moment when my script realises that left col should get hidden corresponds to scrollTop of 500, and at this very moment my script tries to set scroll top to the new value, but it gets instantly overridden by following browser smoothscroll events:
scrollTop == 500 //browser
scrollTop == 450 //mine! i need to save this position!
scrollTop == 520 //browser
scrollTop == 530 //browser
scrollTop == 535 //browser
scrollTop == 537 //browser
so how can i cancel all changes of scrollTop below?
this is my code if needed:
$(function() {
//height of left column
window.main_left_height1 = $('#main_left_div').height();
var ar = $.grep($('.page_container > div'), function(item) {
return $(item).position().top >= window.main_left_height1;
});
//anchor element on the right which placed on the same height with the end of left col
window.main_left_anchor = ar[0];
//we will toggle left column on this scroll height
window.main_left_height1 = $(window.main_left_anchor).position().top;
window.main_left_state = true;
window.ignore_scroll = false;
window.ignore_scroll_value = -1;
});
if (is_mobile || true)
{
$(window).scroll(function(e) {
var scroll_top = $(this).scrollTop();
//i've tried to ignore browser scrolling after i set its value manually in the script but this doesn't work
if (window.ignore_scroll)
{
if (Math.abs(window.ignore_scroll_value - scroll_top) < 50)
{
window.ignore_scroll = false;
window.ignore_scroll_value = -1;
return true;
}
e.preventDefault();
return false;
}
if (window.main_left_state)
{
if (window.main_left_height1 && scroll_top >= window.main_left_height1)
{
$('#main_left').hide();
window.main_left_state = false;
if (!window.main_left_height2)
window.main_left_height2 = $(window.main_left_anchor).position().top;
window.ignore_scroll = true;
window.ignore_scroll_value = window.main_left_height2;
$(this).scrollTop(window.main_left_height2);
}
}
else
{
if (window.main_left_height2 && scroll_top < window.main_left_height2)
{
$('#main_left').show();
window.main_left_state = true;
window.ignore_scroll = true;
window.ignore_scroll_value = window.main_left_height1;
$(this).scrollTop(window.main_left_height1);
}
}
});
}
any suggestions? thanks!
As I see since browser got input (like mouse scroll or key press) and scroll event is generated you can do nothing with it. If events are generated window will be scrolled and if even there will be page rearrangement scroll offset wouldn't be changed. It means you will have jumpy scrolling if you will change scrollTop value after.
Try to change your right column position (Top) and not scrollTop. For example, when user scrolls down and you calculated that scrollTop need to be changed for -60px, just add those 60px to your right panel's top (you can even animate it). I think it might help.
And the second suggestion is to handle mouse and keyboard input by your self to generate scrolling, like it is done here: How to disable scrolling temporarily? (NIGHTMARE! I think :))

How to scroll always on same offset?

I have a titanium scrollView. If i make scroll action, the content is moving depending on the force of my finger scroll action. I need to make it scroll for defined value always (i.e. 400 pixels). How can i realize this?
I've tried it with $.scrollTo() and scrollingEnabled = false, but it's really not so smoothy.
Any other proposals?
ADDED
here is video of similar idea (sorry for quality)
If you want to do a kind of scrollableView, but vertical (the user can pull the scrollView, if the pull is longer than a threshold, the scrollView switch to the next vertical view, if not, the scrollView returns to its current vertical view), you can do it by using the "scroll" and "dragend" events. Here's an example for a drag down, and a scrollView with two 400px views stacked vertically:
var scrollView.top = -400; //Size of the view
var threshold = -100; // Threshold to pull for changing view
var changingPageTriggered = false;
var pulling = false;
scrollView.addEventListener('scroll',function(e) {
var offset = e.y;
if (offset <= threshold && !pulling) {
pulling = true;
changingPageTriggered = true;
} else {
pulling = false;
changingPageTriggered = false;
}
});
scrollView.addEventListener('dragend',function(e) {
if (pulling && changingPageTriggered) {
changingPageTriggered = false;
pulling = false;
changePage()
}
});
function changePage() {
scrollView.scrollTo(0,-400)
scrollView.top = 0
}
I used something similar in a project but I didn't try the code above. You'll need to tweak it and add support for the drag up, it should get you started.

Prevent scrolling when done too quickly with jQuery

In order to prevent mousewheel scrolling to scroll the entire page when reaching the top/bottom of an element with its own scrollbars, I'm using Brandon Aaron's Mousewheel plugin.
This works fine, as long as I don't scroll too quickly. It seems that when scrolling really quickly, two events will pass the "I haven't reached the top/bottom" check yet and will both be executed. However, one of them will then scroll the element to the top/bottom and the next one will then scroll the entire page, which was what I was trying to prevent.
I'm currently doing this
$('.popupContents').bind('mousewheel', function (e, d) {
var t = $(this);
if (d > 0 && t.scrollTop() === 0) {
e.preventDefault();
} else if (d < 0 && (t.scrollTop() == t.get(0).scrollHeight - t.innerHeight())) {
e.preventDefault();
}
});
(As posted in Prevent scrolling of parent element? )
How do I make it so that the function properly stops all events at the top/bottom even when the user scrolls quickly?
I ended up manually tracking the desired scroll position and disallowing the normal scroll event altogether.
var wantedScrollTop = 0;
$('.popupBody').bind('mousewheel', function (e, d) {
var t = $(this);
var scrollTo;
if (d > 0) {
scrollTo = Math.max(0, wantedScrollTop - 30);
} else if (d < 0) {
scrollTo = Math.min(t.get(0).scrollHeight - t.innerHeight(), wantedScrollTop + 30);
}
if (typeof scrollTo !== "undefined") {
wantedScrollTop = scrollTo;
t.scrollTop(wantedScrollTop);
//t.stop().animate({ scrollTop: wantedScrollTop + 'px' }, 150);
}
e.preventDefault();
});
d is the scroll direction, so I'm manually keeping track of the wanted scroll position here. In my case there is only one popup at a time, so I didn't bother sticking the wantedScrollTop in a data- attribute or something similar on the element, which could be useful when youdo have multiple elements that need to track their own scroll position.
It is not doing a fluent scroll like your browser would, but it will change the vertical scroll position by 30 pixels for each time the scrollwheel triggers the event. I left the commented out line in the code to show how that could be achieved. However, for me this resulted in scrolling which feeled very lagged when scrolling quickly.

Categories