jQuery scroll fade-in crash - javascript

This code works well, but when I scroll up and down after 4-5 times it crashes and all the elements disappear. Why does this happen and how do I fix it?
$(window).on("load",function() {
$(window).scroll(function() {
var winheight = $(window).innerHeight();
$(".fade").each(function() {
/* Check the location of each desired element */
var objectBottom = $(this).offset().top + $(this).outerHeight();
var windowBottom = $(window).scrollTop() + $(window).innerHeight();
/* If the element is completely within bounds of the window, fade it in */
if ( windowBottom > (objectBottom - (winheight*0.65))) { //object comes into view (scrolling down)
if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
}
});
}); $(window).scroll(); //invoke scroll-handler on page-load
});

Ok, I supposed that your html is something like this: https://jsfiddle.net/szdwwdac/
Sometimes, if you are scrolling fast up and down, when the element is fading out, your if doesn't work well.
if ( windowBottom >= (objectBottom - (winheight*0.65))) {
if ($(this).css("opacity")==0) {$(this).fadeTo(300,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(300,0);}
}
It's because of the 500ms of animation.
One of the solutions can be the eneble/disable for 500ms of the scroll page.
You can check this solution: How to disable scrolling temporarily?
EDIT
Another solution can be: add a class "fading" when you are inside your if. Then, in the if, eval if the element hasClass "fading". If not, you can go inside and make the animation.

Related

How to give ease animation when adding scrolleft?

I'm building a horizontal scrolling div, something like a slider.
Something like this
The thing is, this thing is between other contents, so I had to use a custom javascript code that I found online to make this horizontal sliding div act like a vertical div.
`
(function () {
init();
var g_containerInViewport;
function init() {
setStickyContainersSize();
bindEvents();
}
function bindEvents() {
window.addEventListener("wheel", wheelHandler);
}
function setStickyContainersSize() {
document
.querySelectorAll(".sticky-container")
.forEach(function (container) {
const stikyContainerHeight =
container.querySelector(".container").scrollWidth;
container.setAttribute(
"style",
"height: " + stikyContainerHeight + "px"
);
});
}
function isElementInViewport(el) {
const rect = el.getBoundingClientRect();
return (
rect.top <= 0 && rect.bottom > document.documentElement.clientHeight
);
}
function wheelHandler(evt) {
const containerInViewPort = Array.from(
document.querySelectorAll(".sticky-container")
).filter(function (container) {
return isElementInViewport(container);
})[0];
if (!containerInViewPort) {
return;
}
var isPlaceHolderBelowTop =
containerInViewPort.offsetTop < document.documentElement.scrollTop;
var isPlaceHolderBelowBottom =
containerInViewPort.offsetTop + containerInViewPort.offsetHeight >
document.documentElement.scrollTop;
let g_canScrollHorizontally =
isPlaceHolderBelowTop && isPlaceHolderBelowBottom;
if (g_canScrollHorizontally) {
containerInViewPort.querySelector(
".projAnimContainer"
).scrollLeft += evt.deltaY;
}
}
})();
This code works.
It does stick the div when user comes to that div, and its not letting the user go down till he finishes scrolling that horizontal div.
So user scrolls down, comes to the slider div, slides(scrolls down) but it doesn't scroll down but scrolls to right. And after user finishes scrolling in that div and div ends, it leaves the user and user can continue the rest of the website as normal.
It works as I said but the problem is I dont want it to scroll ugly.
I want it to scroll smooth.
containerInViewPort.querySelector(
".container"
).scrollLeft += evt.deltaY;
This is the action that adds the scrolling horizontally to my div.
I've tried changing it with this
document.querySelector(".container").scrollBy({
top: 0,
left: +evt.deltaY,
behavior: "smooth",
});
and
$(".container").animate(
{ scrollLeft: "+=" + evt.deltaY + "" },
1000,
"easeOutSine"
);
this..
Both didn't work.
They try to work but they can't, I mean for example if I change the code with the jquery one (easeoutsine one), it scrolls 1 time with ease thats good but then jumps to the end of the div and scrolling more up or down doesn't work. it stuck.
And if I use the other document.query... one it tries to scroll with ease but the scrolling to right effect ends and it goes to the next content after this slider without finishing the slider completely. I think when I add ease, it adds more px than it should and It finishes the slider before it should.
I hope I managed to describe my question.
Thanks all.
I've tried jquery and normal ease animations.

How to change the scrolling position?

I want to have my content fade in on scrolling, but it reacts to late. How can I change it, to have my content fade in earlier?
I am very new to javascript and couldn't get it worked yet.
$(window).on("load",function() {
$(window).scroll(function() {
var windowBottom = $(this).scrollTop() + $(this).innerHeight();
$(".fade").each(function() {
/* Check the location of each desired element */
var objectBottom = $(this).offset().top + $(this).outerHeight();
/* If the element is completely within bounds of the window, fade it in */
if (objectBottom < windowBottom) { //object comes into view (scrolling down)
if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
} else { //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
}
});
}).scroll(); //invoke scroll-handler on page-load
});
Right now the content space is blank until I scroll to the bottom. I need to have my content fade in when it is on like half of the page or earlier. Maybe changeable to any height with percent or pixel?
The shared portion of code fades element in once they are completely in the viewport (= when bottom of the elements is in the window).
How about fading elements in as soon as their tops get in the viewport?
Fade out logic should remain as is: elements should be faded out once their bottom get out of the viewport.
Adapted code:
$(window).on("load",function() {
$(window).scroll(function() {
var windowBottom = $(this).scrollTop() + $(this).innerHeight();
$(".fade").each(function() {
/* Check the location of each desired element */
var objectTop = $(this).offset().top
, objectBottom = $(this).offset().top + $(this).outerHeight();
/* If the element's top gets within bounds of the window, fade it in */
if (objectTop < windowBottom) { //object comes into view (scrolling down)
if ($(this).css("opacity")==0) {$(this).fadeTo(500,1);}
} else if (objectBottom >= windowBottom){ //object goes out of view (scrolling up)
if ($(this).css("opacity")==1) {$(this).fadeTo(500,0);}
}
});
}).scroll(); //invoke scroll-handler on page-load
});

Full page slider with native scrollbar

I am building a full page slider that keeps the native scrollbar and allows the user to either free scroll, use the mouse wheel or navigation dots (on the left) to switch to a slide.
Once the user is on the last slide and tries to scroll down further, the whole slider moves up to reveal a simple scrollable section. If the user scrolls down and then tries to go back up, then this new section moves out of the way again and returns the slider back into view.
Fiddle: http://jsfiddle.net/3odc8zmx/
The parts I'm struggling with:
Only the first two navigation dots work. The third one DOES WORK if you area looking at the first slide. But doesn't do anything, if you are on slide 2. Note: the purple one is a short-cut to the second section of the page and not related to the slider.
When moving to the last slide (via the dots, if you're on the first slide) it causes the code to make the whole slider move upwards as it sees this as the user has slid past the last slide as per the description above. I have tried to combat this using a variable called listen to stop the scroll event listening when using the showSlide method... but it seems to be true even though I set it to false, and only reset it to true again after the animation...
When scrolling down using the mouse wheel, I can get to the second section and back up, but not to the first third section. I'm wondering if I could use the showSlide method to better handle this instead of the current dirty next and prev functions I have implemented.
Note: If the user has free-scrolled, when they use the mouse-wheel, I want the slider to snap to the nearest slide to correct itself... Any suggestions for how I could do this?
Can anyone offer some help?
Here's the JS:
var listen = true;
function nextSlide()
{
$('#section1').stop(true,false).animate({
scrollTop: $('#section1').scrollTop() + $(window).height()
});
}
function prevSlide()
{
$('#section1').stop(true,false).animate({
scrollTop: -$('#section1').scrollTop() + $(window).height()
});
}
function showSlide(index)
{
var offset = $('#section1 div').eq(index).offset();
offset = offset.top;
if(offset){
listen = false;
$('.slide-dot').removeClass('active');
$('.slide-dot').eq(index).addClass('active');
$('#section1').stop(true,false).animate({
scrollTop: offset
}, 500, function(){
listen = true;
});
} else {
alert('error');
}
}
$(document).ready(function(){
var fullHeight = 0;
$('#section1 div').each(function(){
fullHeight = fullHeight + $(this).height();
});
var lastScrollTop1 = 0;
$('#section1').on('scroll', function(e){
var st = $(this).scrollTop();
if (st > lastScrollTop1){
if( $('#section1').scrollTop() + $(window).height() == fullHeight) {
if(listen){
$('body').addClass('shifted');
}
}
}
lastScrollTop1 = st;
});
$('#section1').on('mousewheel', function(e){
e.preventDefault();
var st = $(this).scrollTop();
if (st > lastScrollTop1){
nextSlide();
} else {
prevSlide();
}
});
var lastScrollTop2 = 0;
$('#section2').on('scroll', function(e){
var st = $(this).scrollTop();
if (st > lastScrollTop1){
} else {
if( st == 0 ){
$('body').removeClass('shifted');
}
}
lastScrollTop1 = st;
});
$('.slide-dots').css({'margin-top':-$('.slide-dots').height() / 2});
$('.slide-dot').first().addClass('active');
$(document).on('click', '.slide-dot', function(e){
e.preventDefault();
showSlide( $(this).index() );
});
$(document).on('click', '.slide-dot-fake', function(e){
e.preventDefault();
$('body').addClass('shifted');
});
});
And for those wondering why I'm not using something like fullPage.js, it's because it can't handle the way I want to transition between the two areas and have two scrollbars (one for each area).
You can use:
e.originalEvent.wheelDelta
instead of:
st > lastScrollTop1
in the mousewheel event for your third problem to check if the user has scrolled up or down. And also change the +/- in prevSlide. I used dm4web's fiddle for your first problem. And I used:
scrollTop: offset - 1
instead of:
scrollTop: offset
for your second problem, because when the scroll reaches to the last pixel of the third element, it automatically goes to the next section, so 1 pixel is enough for it not to.
Here's the fiddle: http://jsfiddle.net/3odc8zmx/3/
As suggested by #chdltest, you could do it by using fullPage.js.
Here's an example. Go to the last section.
Code used for the example:
Javascript
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
scrollOverflow: true,
scrollBar: true,
afterLoad: function (anchor, index) {
//hiding the main scroll bar
if (index == 4) {
$('body, html').css('overflow', 'hidden');
}
//showing the main scroll bar
if (index == 3) {
$('body, html').css('overflow', 'visible');
}
}
});
CSS (in case you prefer to use the normal style for it)
/* Normal style scroll bar
* --------------------------------------- */
.slimScrollBar {
display: none !important;
}
.fp-scrollable {
overflow: auto !important;
}
Advantages of using fullPage.js instead to your own code:
Strongly tested in different devices and browsers. (IE, Opera, Safari, Chrome, Firefox..)
Prevent problems with trackpads, Apple laptops trackpads or Apple Magic Mouse.
Old browser's compatibility, such as IE 8, Opera 12...
Touch devices compatibility (IE Windows Phone, Android, Apple iOS, touch desktops...)
It provides many other useful options and callbacks.

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