jQuery scrollTop won't let me scroll after executed - javascript

I have a landing image, that has two functions - one is a click function that once the landing image is clicked it scrolls down to reveal the next section. The second function is a scroll function, where the user scrolls/ swipes down and the scroll is hijacked to the next section. Once one of these functions is activated the landing image is hidden and cannot be seen again until a new tab is opened.
I have the click and scroll function working, the issue is once the scroll effect is finished I cannot resume scrolling the rest of the page.
I realize that the scroll function may still be running which is keeping the scroll at the top, but do not know what to add to my code?
Additionally, I am using the Divi theme, so difficult to add HTML markup
(function ($) {
$(document).ready(function () {
let header = $('.cf_bal-header');
let page = $('html, body');
// Check for first timers
if (!sessionStorage.returnVisitor) {
// No flag, this is the first visit.
// Set a flag so that next time we know they have been here before.
sessionStorage.returnVisitor = 'true';
// Handle Hero image click.
$('.cf_news_link').click(function () {
$(page).animate({
scrollTop: $(".news").offset().top
}, 1000);
return false;
});
// Handle scrolling (this is our scroll jacker)
$(window).on('scroll', function () {
if ($(page).animate({
scrollTop: $(".news").offset().top
}, 1000));
return false;
});
} else {
// Not our first time, hide header.
header.hide();
}
});
})(jQuery);

Related

How to activate elements at different points of scroll down page

I am trying to 'activate' or 'click' on different elements as the user scrolls down the page. I.e. as the user scrolls down the page, element 1 should deactivate and element 2 should activate. Then 2 should deactivate and 3 should activate. It is important that these elements get 'clicked' and not just have a CSS change.
It works on the first one (it clicks .no2 and the tab activates) but then as you scroll down, .no3 and .n04 don't click, so I assume once the first if statement is true, it no longer checks the next if statement.
Please see my code here:
<script>
$(function() {
$(window).scroll(function () {
var scroll = $(window).scrollTop();
if (scroll >= 200) {
$('.no2').triggerHandler('click');
}
if (scroll >= 250) {
$('.no3').triggerHandler('click');
}
if (scroll >= 300) {
$('.no4').triggerHandler('click');
}
});
});
</script>
You can use libraries to help you achieve it easily try AOS
https://wesbos.com/javascript/06-serious-practice-exercises/scroll-events-and-intersection-observer
Else you can use Intesection Observer
https://wesbos.com/javascript/06-serious-practice-exercises/scroll-events-and-intersection-observer

Detecting weather user scrolls the bottom of the div or not in react js and javascript

I want to implement infinite scrolling in the table, so I am calculating div height in one possible way, you can see below
let fixedCh = e.target.clientHeight;
let calCh = e.target.scrollHeight - e.target.scrollTop;
if (fixedCh === calCh) {
alert('load more');
}
In this approach,calCh is varied from different resolutions. Is there any other way of doing this, so that it can work through all kind of browser and screen resolution
Your approach is good; you need to call your function initially when the user loads the page to check if the user's screen resolution is already to the end of the scroll, call "alert('load more')".
The problem is that for some users, based on their screen, the scrollbar will not be visible to scroll, so your event of scroll won't check the element. To fix this, as I said above, you need to initially load your screen check function when the "Dom is ready".
Here is the basic implementation:
function loadMore (e) {
let fixedCh = e.clientHeight;
let calCh = e.scrollHeight - e.scrollTop;
if (fixedCh === calCh) {
alert('load more');
}
}
// listen on scroll and check target element fixedCh === calCh
function listenOnScroll() {
document.getElementById('app').addEventListener('scroll', (e) => {
loadMore(e.target)
})
},
window.onload = (event) => {
loadMore(document.getElementById('app').target)
};
I will call the function "loadMore" when the dom is ready or loaded and pass the targetted Dom element.
Later, I'll call the "listenOnScroll" function to listen on the target element scroll and then call the "loadMore" function from it.

jQuery scroll to next element via up/down buttons - how to add handling for manual scrolling that would otherwise confuse this?

I am trying to implement two static buttons for navigating up or down between about 10 containing div tags on a single fairly deep page of content.
I want the buttons to smoothly scroll to the next part of the page (next containing div) whenever they are clicked on.
The problem with this solution is that if you manually scroll up and down the page using the browser scroll bar or the mouse wheel then the logic of the code is not aware of this and when you next click next/prev a scroll takes place that is not actually relevant to the viewable area you see, totally ruining the user experience.
You can test this in this demo: http://jsfiddle.net/aVJBY/ . If you click NEXT once it works. Now scroll down to near the bottom of the content and click PREV. In theory the page should go one step back from the bottom of the page. Instead it returns to the top of the page.
Maybe I just need to scrap this code and use some external library which is fine, but I can't find anything appropriate. Anyone have an idea on how to make my code resolve this issue?
The code I am using so far is here:
$('div.section').first();
$('a.display').on('click', function(e) {
e.preventDefault();
var t = $(this).text(),
that = $(this);
if (t === 'next' && $('.current').next('div.section').length > 0) {
var $next = $('.current').next('.section');
var top = $next.offset().top;
$('.current').removeClass('current');
$('body').animate({
scrollTop: top
}, function () {
$next.addClass('current');
});
} else if (t === 'prev' && $('.current').prev('div.section').length > 0) {
var $prev = $('.current').prev('.section');
var top = $prev.offset().top;
$('.current').removeClass('current');
$('body').animate({
scrollTop: top
}, function () {
$prev.addClass('current');
});
}
});
I resolved this with the wonderful jQuery inview plugin - https://github.com/protonet/jquery.inview An overview of what I did follows...
I first setup some variables, the pageItems array contains all the divs I need to monitor...
var posNext=0;
var posPrev=0;
var pageItems = ["pageone", "pagetwo", "pagethree", "pagefour", "pagefive"];
I then setup the following in document ready. Thanks to the inview plugin and the jQuery bind event, on a page scroll (of any kind, either by my buttons, manually or via mouse wheel) the plugin is run. I first search the array of page items for a match with what is returned by the $(this).attr("id") value. I then adjust the posNext/posPrev variables with values based on the current div in view.
$(document).ready(function (){
$(".divclass").bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
if (isInView) {
matchPos = pageItems.indexOf($(this).attr("id"));
// Determine prev/next positions now we have an index. The position values used in click events later
if ( (matchPos+1)==pageItems.length ){
posNext=matchPos;
posPrev=matchPos-1;
}else if (matchPos==0){
posNext=matchPos+1;
posPrev=0;
}else{
posNext=matchPos+1;
posPrev=matchPos-1;
}
} else {
// dont update index
}
});
});
Finally also within document.ready I have binds to catch clicks on the buttons I have on screen all the time. These use a jQuery animate call to scroll to the div id value specified via the array index values in posNext/posPrev.
$(".down-button").click(function(e){
event.preventDefault();
$('html, body').stop().animate({
scrollTop: $("#"+pageItems[posNext]).offset().top
}, 500);
});
$(".up-button").click(function(e){
event.preventDefault();
$('html, body').stop().animate({
scrollTop: $("#"+pageItems[posPrev]).offset().top
}, 500);
});

How to synchronize setTimeout and mobile.navigate using jQuery Mobile?

I'm creating a small quiz, mobile app using jQuery Mobile, and I'm displaying a 3 second GIF at certain points. Though, because it is shown many times, I don't want to bother the user each time, and if he/she clicks anywhere on the page it goes to the next page, but I also have set up a setTimeout, which waits for three seconds, meaning of the GIF to display completely and then moves to the next page. As you can see this makes a problem. If I click the GIF, it moves to the next page, and then if I again move to the other page, after three seconds are passed it sends me back to the previous page, due to the setTimeout. I have the following code:
EDIT :
$(document).on("pagechange", function(event, ui) {
var clicked = false;
// Here comes some if-else statements checking which page is currently active
else if ($.mobile.activePage[0].id == "correctGIF") {
correct++;
nextpage = hashtag.concat(page, 'Correct');
$('#correctGIF').append('<img src="images/Correct1.gif">');
$('#correctGIF').click(function() {
clicked = true;
$.mobile.navigate(nextpage);
alert("alert from click");
});
setTimeout(function() {
if (!clicked) {
$.mobile.navigate(nextpage);
alert("alert from timeout");
}
}, 3000);
}
So, I need to somehow synchronize it. If there is a click it should ignore the setTimeout part, and if there is no click it should wait for three seconds for the GIF to finish, meaning should activate the setTimeout part. Also please note that this GIF is displayed many times during the quiz, not just once. Any ideas about this?
Have you tried this approach:
$(document).ready(function () {
$('#correctGIF').off('click').on('click', function () {
alert('navigate from click');
console.log('navigate from click');
if (!$('#correctGIF').hasClass('clickedImageClass')) {
$('#correctGIF').addClass('clickedImageClass');
}
});
setTimeout(function () {
if (!$('#correctGIF').hasClass('clickedImageClass')) {
alert('navigate from timeout');
console.log('navigate from timeout');
}
}, 3000);
});
JsFiddle demo here: http://jsfiddle.net/e35pn/13/

How to stop jQuery delay timer based animation?

So I'm building this modal / timed animation with slide navigation from scratch.
I have a function for the buttons that navigate the slides, and also a function to animate the frames every 5 secs. My problem is I'm not sure how to "break" the delay function if the user decides to take over by clicking the navigation buttons. As soon as the user clicks any of those buttons the delay based animation function needs to stop working.
// Timer for Animating Frames
// Need a kill timer function
var animateFramesTimer = function(){
$('#tour_1')
.delay(5000).fadeOut('fast', function() {
$('#tour_2')
.fadeIn('fade').delay(5000).fadeOut('fast', function() {
$('#tour_3')
.fadeIn('fade').delay(5000).fadeOut('fast', function() {
$('#tour_4')
.fadeIn('fade').delay(5000).fadeOut('fast', function() {
$('#tour_modal').fadeOut('fast');
// END
});
});
});
});
}
animateFramesTimer();
So I run animateFramesTimer and if a certain button is clicked I need the function to stop working, I tried a while loop which seemed like the correct path to go, but it kept breaking in the browser :(
var autoAnimate = true;
while(autoAnimate){
// delay animation
}
Do you know of a better way to accomplish this?
$('[id^="tour_"]').stop(true, true); // kills current animations
animateFramesTimer = function() {}; // removes function

Categories