Check 'mousewheel' event direction with scroll locked - javascript

I currently have a slick slider on top of my page that should change slides on scroll, and after a certain point it should go back to normal scroll behaviour.
What I want to do is to initially lock the scroll (yeah, I know that changing scroll behaviour is a terrible thing for UX, but this was a mandatory request that came directly from the client), check the amount of times the scroll event was fired, check if it was up or down, and then switch slides accordingly.
My code currently looks like this:
$('body').on('DOMMouseScroll mousewheel', function(e) {
var viewportHeight = $(window).height(),
firstWaypoint = viewportHeight / 2,
secondWaypoint = viewportHeight,
thirdWaypoint = 3/2 * viewportHeight,
unlockPoint = viewportHeight * 2,
$slider = $('.home-hero__inner__text');
if (/* Y scroll position < thirdWaypoint lock scroll */) {
e.preventDefault();
} else if (/* If Y scroll position < secondWaypoint show first slide */) {
$slider.slick('slickGoTo', 0);
} else if (/* If Y scroll position > secondWaypoint show second slide */) {
$slider.slick('slickGoTo', 1);
} else if (/* If Y scroll position > thirdWaypoint show third slide */) {
$slider.slick('slickGoTo', 2);
} else {
// Unlock scroll
}
});
The thing is that as I currently lock scroll capabilities using preventDefault(), I can no longer check my page scrollTop() position since it is always at the top, returning a 0 value.
Is there a way to check how many pixels should've been scrolled on normal behaviour, and whether it was up or down? 'cause I need to keep a track of the assumed scroll position to trigger each step of the if statement.

You could just check if the wheelDelta is positive or negative
$(document).on('DOMMouseScroll mousewheel', function(e) {
var moved = e.originalEvent.wheelDelta || e.originalEvent.detail * -1 || 0;
if (moved > 0) {
// scrolled up
} else if (moved < 0) {
// scrolled down
}
});
FIDDLE

Related

Get scroll value on element with position:fixed

I have a page with a header section. In it, two blocks that move sideways after scrolling or dragging on the mobile.
I am trying to set the scrolling for the header, but I want too that the rest of the page stays in place until the side blocks reach left: -50% and right:-50%.
I have an event scroll set to header, with pageYoffset values.
I tried to set the rest of the content the page gives to the section with the position:fixed, but then the scroll does not work anymore, and do not count pageYoffset.
Do you have any ideas how to get around it, so that the rest of the page would scroll only after the full unveiling of the header?
(in short, the pink section should be on top and wait until the header disappears)
let current = $(window).scrollTop();
let windowHeight = $(window).height();
let eleLeft = $(".cd-half-left");
let eleRight = $(".cd-half-right");
let currPositionLeft = eleLeft.position().left;
let currPositionRight = eleRight.position().right;
let headerHeaight = $(".cd-section").height();
let halfBlockWidth = $(".cd-half-block").width();
let windowWidth = $(window).width();
$(window).scroll(function (event) {
current = $(window).scrollTop();
console.log({total:total,current:current});
var newPosition = ((current / headerHeaight)*100) / 2;
console.log(newPosition);
eleLeft.css({left:"-"+newPosition+'%'});
eleRight.css({right:"-"+newPosition+'%'});
});
FIDDLE
A solution would be not to use window scroll but instead handle scroll gesture (from mousewheel and touchmove) to control left and right panel, and prevent actual scroll when the panels are not fully opened.
so instead of $(window].scroll(handler), try with $('.cd-block').bind('mousewheel', handler) and $('.cd-block').bind('mousewheel', handler)
The handler being:
function updateCurrent(event) {
if (current >= 50) {
current = 50;
} else {
if (current <= 0) {
current = 0;
}
// if below 50 we cancel the event to prevent the scroll
event.originalEvent.preventDefault();
}
eleLeft.css({left:"-"+current+'%'});
eleRight.css({right:"-"+current+'%'});
}
Here is a buggy but working solution (keyboard space, up and down should be handled too):
fiddle

mouse over event within certain window y range

I am working on a project that requires the full length logo shrink to short initial in 2 situations:
A) when page scroll down past 300px.
and
B) if page hasn't scroll past 300px (meaning full length logo still showing), shrink the full length logo to initial to accommodate pulldown menu when mouse over the top menu items.
Here is the code I tried:
it is working but when page scroll past 300px the mouse out should not happen. It should keep the logo as the smaller initial format. Right now the mouse out will happen no matter the page is scroll past 300px or not.
/* shrink logo when page scroll past 300px by adding .smaller class to #logo. */
window.onscroll = function() {myFunction()};
function myFunction() {
if (document.body.scrollTop > 300 || document.documentElement.scrollTop > 300) {
document.getElementById("logo").className = "smaller";
} else {
document.getElementById("logo").className = "";
}
}
/* shrink logo when mouse over top menu items (.showlp) only if page has NOT scroll past 300px */
$(document).ready(function(){
$(".showlp").mouseover(function(){
if (document.body.scrollTop < 300 || document.documentElement.scrollTop < 300) {
document.getElementById("logo").className = "smaller";
}
})
$(".showlp").mouseout(function(){
if (document.body.scrollTop < 300 || document.documentElement.scrollTop < 300) {
document.getElementById("logo").className = "";
}
})
});
Any help is appreciated.
Pass parameters via data attribute in the body tag and access that value via you javascript code.
Eg.
then on your javascript
var ctrl=
$("body").attr("
data-var");
then on your window scroll function set the attribute value to 1, aand listen to it on your mouse over function to know when to
add the functionality.
Eg.
Function
myfunction(){
if(document.bo
dy.scrollTop>3
00){
// swap urclass
// then do
$("body").attr("
data-var", 1);
}
then on your mouse over function do:
$(document).re
ady(function(){
$(".showIp").mo
usover(functio
n(){
var ctrl=
$("body").attr("
data-var");
if(ctrl==1){
//swap class
}
else{
//keep swap
}
});
});

Enabling/triggering mousewheel effect ONLY on certain div (not fullpage)

I'm writing this after searching for mousewheel events in jQuery, but perhaps I'm not asking the right questions due to my lack of knowledge, and that's why I'm not finding any useful answers yet.
What I would like to achieve is a mousewheel effect that I can trigger only inside a certain div called #scroller. I'm using the jquery mousewheel plugin by Brandon Aaron and a script that updates the top value to the next or previous .js-slide whenever I delta scroll.
FIDDLE LINK:
I created this fiddle link. As you can see, it "jumps" from slide to slide, but then the content outside #scroller is not accesible anymore! I would like it to have a normal wheelmouse behaviour :S. I also have a working url where I would like to apply this effect, if you think that's of any use.
To better explain the structure and desired effect, here's an image:
I have already tried bounding my script only to $('#scroller').mouseover(function(){ my script }); but that didn't work. The mousewheel started out ok, it switched into jumping mode ok, but it never went back to normal after leaving the div #scroller and I don't find how to reset this behaviour.
My script right now is this:
jQuery(document).ready(function($) {
var slide = $('.js-slide');
var sectionHeight = $(window).height();
var slideHeight = $(slide).height();
var scrollingScreen = false;
$('#scroller').mouseover(function(){
$(slide).mousewheel(function(event, delta) {
if ( !scrollingScreen ) {
scrollingScreen = true; // prevent call
var top = $("body").scrollTop() || $("html").scrollTop();
// Chrome places overflow at body, Firefox places whacks at html...
// Finds slide headers above/below the current scroll top
var candidates = $(slide).filter(function() {
if ( delta < 0 )
return $(this).offset().top > top + (1);
else
return $(this).offset().top < top - (1);
});
// one or more slides found? Update top
if ( candidates.length > 0 ) {
if ( delta < 0 )
top = candidates.first().offset().top;
else if ( delta > 0 )
top = candidates.last().offset().top;
}
// Perform animated scroll to the right place
$("html,body").animate({ scrollTop:top }, "easeInOutQuint", function() {
scrollingScreen = false; // Release call
});
}
return false;
}); // closes mousewheel
}); // closes mouseover
});
Any help or insight on how to achieve this would be greatly appreciated.
Thank you!
Ok. Finally I found it!! I reviewed the web where the plugin author records different mousewheel events, including deactivating all of them and reseting a normal scrolling mouse. There's where I found the use of the function .unmousewheel(), just what I wanted!
But now, as the script is not able to find further slides past de last when scrolling down, and before the first when scrolling up, it became impossible to access content before and after #scroller with the scrolling wheel. That's why I had to change a bit the script and force a jump while on the first slide or the last.
Anyway, here's the script:
jQuery(document).ready(function($) {
var slide = $('#scroller .sectioncontainer');
var sectionHeight = $(window).height();
var slideHeight = slide.height();
var scrollingScreen = false;
slide.mousewheel(function(event, delta) {
if ( !scrollingScreen ) {
scrollingScreen = true; // prevent call
var top = $("body").scrollTop() || $("html").scrollTop();
// Chrome places overflow at body, Firefox places whacks at html...
// Finds slide headers above/below the current scroll top
var candidates = slide.filter(function() {
if ( delta < 0 )
return $(this).offset().top > top + (1/120);
else
return $(this).offset().top < top - (1/120);
});
// one or more slides found? Update top
if ( candidates.length > 0 ) {
if ( delta < 0 )
top = candidates.first().offset().top;
else if ( delta > 0 )
top = candidates.last().offset().top;
} else{ // no more slides found
if ( delta < 0 )
top = $("#contact").offset().top;
else if ( delta > 0 )
top = $("#about").offset().top;
}
// Perform animated scroll to the right place
$("html,body").animate({ scrollTop:top }, "easeInOutQuint", function() {
scrollingScreen = false; // Release call
});
}
return false;
});
$("#contact").unmousewheel();
$("#about").unmousewheel();
$("#div1").unmousewheel();
$("#div2").unmousewheel();
$("#div3").unmousewheel();
$("#div4").unmousewheel();
$("#div5").unmousewheel();
// . . .
//and all other divs and sections that don't use the mousewheel
});
And here's the result.

Stop scrolling page, scroll div

I'm creating this landing page: http://tag4share.com/landing/#
Where is located the two galaxy s3 (one white with "Organizador" label on it and a black with "Participante" label), I want to stop scrolling the page and automatically start scrolling the content inside the mobile (an iFrame, div, anything).
Is it possible?
Basically I want to "focus" the scrolling inside a div (and make it work even if the cursor isn't hovering it). Or animate while scrolling without scrolling the body.
Example: http://www.google.com/nexus/5/
On the "Everything you need to capture the moments that matter." part.
My attempt:
var lastScroll;
var currentScroll = $(window).scrollTop();
$(window).scroll(function() {
lastScroll = currentScroll;
currentScroll = $(window).scrollTop();
if($(window).scrollTop() >= 2024 && $(window).scrollTop() < 2500)
{
var difference = currentScroll - lastScroll;
$(".main").css({"margin-top":"-="+currentScroll});
}
});
I've tried to move the main div along with scrolling. It works but it looks really strange (keeps shaking).
Thanks!
I've just tidied up your code a tad, fixed indentation etc.
As for actually scrolling your div when you hit the position, use animate to actually mimic the scrolling effect, once you know you have reached the bottom, you can put another if statement within the scroll function to stop resetting the scroll position.
var lastScroll;
var scrollPosition = $(window).scrollTop();
var reachedBottom = false;
var phonePositionTop = $('#phoneContainerID').position().top;
var phonePositionBottom = phonePositionTop + $('#phoneContainerID').height();
$(window).scroll(function() {
if(scrollPosition >= phonePositionTop && scrollPosition < phonePositionBottom && reachedBottom == false){
var difference = currentScroll - lastScroll;
// Keep resetting scroll to the phoneContainerTop position
$(".main").css({"margin-top": phonePositionTop});
var scrollLimit = -100;
if ($('#phoneContainerID').position().top < scrollLimit) {
//Once the scroll limit is less than -100 (scrolled up 100 pixels)
// Disable our 'pause' effect, and continue
reachedBottom = true;
}
}
});
I haven't tested this, however I was just giving you an idea of where to go from here.
I hope I have helped a little!

Jquery when the user hits bottom of the page

I've been working on a scroll to top function for my website, and that part of it works fine. My problem is however that I have a fixed div that is overlapping my footer when it hits the bottom of the page.
Here is the function that I have working.
$(document).scroll(function (e) {
if (document.body.scrollTop >= 800) {
$('#beamUp').show(1000);
} else {
$('#beamUp').hide(1000);
return false;
}
});
Is there somehow I could detect when I hit that part of the page and stop the div from moving past that.Help is much appreciated!
jsFiddle: http://jsfiddle.net/zazvorniki/RTDpw/
Just get the height of the page, minus the height of the div in question, as well as the footer... make sure the top is never greater than that value... you'll also need an onresize event handler re-evaluate that value.
looking at your jsfiddle... here are my edits
In your scroll listener, I am checking for the position of the page, and adjusting the bottom position of the floater appropriately. I also set the initial display:none, so you don't need to call .hide() in your initial script. In addition, resizing the window has the effect of scrolling for your use, so I changed the listener for both events.
$(document).on('scroll resize', function (e) {
var viewHeight = $(window).height();
var viewTop = $(window).scrollTop();
var footerTop = $("footer").offset().top;
var baseline = (viewHeight + viewTop) - footerTop;
var bu = $("#beamUp").css({bottom: (baseline < 0 ? 0 : baseline) + 'px'});
if (viewTop >= 50) {
bu.show(1000);
} else {
bu.hide(1000);
}
});

Categories

Resources