Trigger event when scrolling div into view - javascript

I am able to register an event when the user scrolls to the top and bottom of the page, but can't get an event to trigger when the user scrolls below the fold of the page. I have a div in the middle #below-fold, that I need to trigger when it comes into the viewport of the browser on scrolling down.
I need to do this WITHOUT an additional plugin.
HTML
<div class="top">TOP</div>
<div id="below-fold">Fold</div>
<div class="bottom">Bottom</div>
jQuery
$(function () {
var $win = $(window);
$win.scroll(function () {
if ($win.scrollTop() == 0) {
console.log("USER SCROLLED TO TOP");
mixpanel.track(
"User Scrolled To Top", {
"url": window.location.href
});
} else if ($win.height() + $win.scrollTop() >= $('#below-fold').height() - 0 && $win.height() + $win.scrollTop() <= $('#below-fold').height() + 0) {
console.log("VIEWED BELOW THE FOLD");
mixpanel.track(
"User Scrolled Below Fold", {
"url": window.location.href
});
} else if ($win.height() + $win.scrollTop() == $(document).height()) {
console.log("USER SCROLLED TO BOTTOM");
mixpanel.track(
"User Scrolled To Bottom", {
"url": window.location.href
});
}
});
});
JSFIDDLE: LINK

Change the else if to:
else if ($win.scrollTop() >= $('#below-fold').position().top - $win.height() && $win.height() + $win.scrollTop() < $(document).height())
UPDATE: http://jsfiddle.net/rndam8ns/6/
added var triggered = false into the mix, so that it only triggers once on scroll down and when it scrolls to the top, it'll reset and trigger again

You should test [element].offset().top in your IF:
EDIT: To check only the first enter event, you could use a flag like in the example.
$(function () {
var $win = $(window);
var $fold = $('#below-fold');
var inTheFold = false;
$win.scroll(function () {
console.log($win.scrollTop());
console.log($fold.offset().top);
console.log(inTheFold);
if ($win.scrollTop() >= $fold.offset().top && $win.scrollTop() <= $fold.offset().top+$fold.height() )
{
if (!inTheFold) {
inTheFold = true;
console.log("VIEWED BELOW THE FOLD");
mixpanel.track(
"User Scrolled Below Fold", {
"url": window.location.href
});
}
} else if ($win.scrollTop() <= $fold.offset().top || $win.scrollTop() >= $fold.offset().top+$fold.height() ) {
if (inTheFold) {
inTheFold = false;
console.log("EXITED THE FOLD");
mixpanel.track(
"EXITED THE FOLD", {
"url": window.location.href
});
}
}
});
});
demo here: http://jsfiddle.net/rndam8ns/7/

Related

Cannot scroll up from bottom of page

After scrolling to the footer of the page I am not able to scroll upwards, my page gets stuck
I am feeling that that when this.oldScroll == this.scrollY I need to do something to fix this.
$(window).scroll(function () {
if (this.oldScroll > this.scrollY) {
scrollDirection = "up";
userScrolled = true;
}
else if (this.oldScroll == this.scrollY) {
scrollDirection = "none";
userScrolled = false;
} else {
scrollDirection = "down";
userScrolled = true;
}
this.oldScroll = this.scrollY;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
I am expecting that I can scroll up once I reach the bottom of the page

Functions not being triggered on scroll

I have a code which is supposed to trigger various functions as I scroll down (each function draws a chart below another). The thing is that this code works well on my screen but when I run it on a bigger screen the functions are not triggered.
I haven't harcoded anything, I have debugged, and tested each conditions and all throw true.
This is the troublesome snippet:
$(window).scroll(function() {
if ($('#chartdiv').html().length != 0) {
var scrollHeight = $(document).height();
var scrollPosition = $(window).height() + $(window).scrollTop();
if (Math.round((scrollHeight - scrollPosition) / scrollHeight) === 0) {
if ($('#chartdiv2').html().length == 0) {
drawChar2();
}
okas.
else if ($('#chartdiv3').html().length == 0) {
drawChar3();
} else if ($('#chartdiv4').html().length == 0) {
drawChar4();
} else if ($('#chartdiv5').html().length == 0) {
drawChar5();
}
}
}
});
If your screen is very big, you have to add if condition.
Because there is no reason to scroll.
$(window).scroll(function() {
if ($('#chartdiv').html().length != 0) {
var $window = $(window);
var windowHeight = $window.height();
var scrollHeight = $(document).height();
var scrollPosition = windowHeight + $window.scrollTop();
if (windowHeight === scrollHeight || // add this condition!!!
Math.round((scrollHeight - scrollPosition) / scrollHeight) === 0) {
if ($('#chartdiv2').html().length == 0) {
drawChar2();
} else if ($('#chartdiv3').html().length == 0) {
drawChar3();
} else if ($('#chartdiv4').html().length == 0) {
drawChar4();
} else if ($('#chartdiv5').html().length == 0) {
drawChar5();
}
}
}
});

HTML input Search bar is not focusable when clicked by mouse but can only focus by TAB

The Search bar is not focusable when clicked by mouse but can only focus by TAB
The script i got it form here CODEPEN DEMO
The input search bar i used is given below
<input class="searchbar" id="searchbar" name="search" autocomplete="off" type="text" placeholder="Find a name for your idea"/>
I'm using this js scripts in the headers
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery‌​.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.mi‌​n.js"></script>
<script src="https://dl.dropboxusercontent.com/s/zkhrhwpagv1cxqg/jqu‌​ery.hammer.js"></scr‌​ipt>
I'm using this Javascript, which i think this is the problem maker!
I'm using scroll hijacking.
The only problem maker is this javascript given below.
If I removed this js It works perfect.
Please someone help me solve this behavior.
function l(o) {
console.log(o)
}
$(document).ready(function() {
var sections = $('.box').toArray();
var scroll = {
activeSection: 0,
sectionCount: sections.length - 1,
isThrottled: false,
throttleDuration: 1000,
target: $(sections[0]).position().top
}
function setSizes() {
for (var i = 0; i < sections.length; i++) {
$(sections[i]).css({
'top': window.innerHeight * i,
'height': window.innerHeight,
'width': window.innerWidth
});
}
}
setSizes();
$('body').on('resize', setSizes());
function downSection() {
var positionFromTop = $(sections[scroll.activeSection + 1]).position().top;
$("body, html").animate({
"scrollTop": positionFromTop
}, 300);
++scroll.activeSection;
}
function upSection() {
var positionFromTop = $(sections[scroll.activeSection - 1]).position().top;
$("body, html").animate({
"scrollTop": positionFromTop
}, 300);
--scroll.activeSection;
}
$("body").hammer({
preventDefault: true
}).on("swipe", function(event) {
if (event.gesture.direction == 'up') {
if (scroll.activeSection != sections.length - 1) {
downSection();
l('SWIPED UP');
}
} else if (event.gesture.direction == 'down') {
if (scroll.activeSection != 0) {
upSection();
l('SWIPED DOWN');
}
}
});
$(window).on('scroll', function(e) {
e.preventDefault();
});
$(window).on('mousewheel', function(event) {
event.preventDefault();
if (scroll.isThrottled) {
return;
}
scroll.isThrottled = true;
setTimeout(function() {
scroll.isThrottled = false;
}, scroll.throttleDuration);
if (event.originalEvent.wheelDelta > 0) {
if (scroll.activeSection === 0) return false;
upSection();
l('WHEELED DOWN');
} else {
if (scroll.activeSection >= scroll.sectionCount) return false;
downSection();
l('WHEELED UP');
}
});
$(window).keydown(function(e) {
if (e.keyCode == 40 && (scroll.activeSection != sections.length - 1)) {
downSection();
l('ARROW DOWN');
} else if (e.keyCode == 38 && (scroll.activeSection != 0)) {
upSection();
l('ARROW UP');
}
});
}); // end doc ready
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<input class="searchbar" id="searchbar" name="search" autocomplete="off" type="text" placeholder="Find a name for your idea" />

jQuery function - prevent getting returns "for a while"

I'm checking the scroll direction with wheelDelta but it returns lots of scroll properties at once. I only need to know if it's up or down and it shouldn't return a value under 500ms after first trigger. I tried to play with setTimeout but couldn't solve it nicely. Any ideas?
var distance = $('.section-two').offset().top,
$window = $(window);
$window.scroll(function() {
if ( $window.scrollTop() >= distance ) {
$('body').css('overflow', 'hidden');
setTimeout(function(){
$(document).bind('mousewheel', function(evt) {
var delta = evt.originalEvent.wheelDelta;
if(delta > 0){
console.log('scrolled up')
} else {
console.log('scrolled down');
}
})
}, 500);
}
});
Here's the codepen example
Can you try unbinding the 'mousewheel' event before you bind it. It seems like, it binds it over and over again. Add $(document).unbind('mousewheel'); before the $(document).bind('mousewheel', function(evt) { line.
Try using Lodash to throttle the event. You should be able to store the previous offset and figure out the scroll direction from that:
var lastScrollTop = 0;
function scrollHandler() {
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
if (scrollTop > lastScrollTop){
console.info('scrolled down');
} else {
console.info('scrolled up');
}
lastScrollTop = scrollTop;
}
window.addEventListener('scroll', _.throttle(scrollHandler, 500))
<script src="https://cdn.jsdelivr.net/lodash/4.17.4/lodash.min.js"></script>
solved with a more proper setTimeout: codepen example
var doMouseWheel = true;
$(document).bind("mousewheel", function(event, delta)
{
// it'll just not do anything while it's false
if (!doMouseWheel)
return;
// here's where you were unbinding, now just turning false
doMouseWheel = false;
// do whatever else you wanted
var delta = event.originalEvent.wheelDelta;
if(delta > 0){
console.log('scrolled up')
} else {
console.log('scrolled down');
}
// here's where you were rebinding, now wait 200ms and turn on
setTimeout(turnWheelBackOn, 800);
});
function turnWheelBackOn() { doMouseWheel = true; }

trying to make a timer stop when the user reaches the bottom of the page using jQuery

I have a timer that starts counting up when the page is loaded. I want it to stop when the user scrolls to the bottom of the page. Here is the jQuery I've written:
function timerTick(time, stop)
{
if(stop == false)
{
setInterval(function ()
{
time += 1;
var displayTime = time/10;
if(displayTime % 1 != 0)
{
$('.time').text(displayTime.toString());
}
else
{
$('.time').text(displayTime.toString() + ".0");
}
}, 100);
}
else //behavior is the same if i remove the else block
{
return;
}
}
$(document).ready(function () {
var time = 0;
var stop = false;
timerTick(time, stop);
//check if we're at the bottom
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
stop = true;
}
});
});
The timer counts up perfectly, the problem is I can't get it to stop. If I replace the stop = true; line with alert('abc');, the alert shows up when the user reaches the bottom. So all of the pieces are working, just for some reason setting stop to true doesn't stop the timerTick function from going into the if(stop == false) block.
Can someone tell me what I'm doing wrong?
Edit: I made a jsFiddle.
You have to clear interval as soos as user reach the end of page. Otherwise it will continue executing.
Try:
var intervalId;
function timerTick(time, stop)
{
if(stop == false)
{
intervalId=setInterval(function () //Set the interval in a var
{
time += 1;
var displayTime = time/10;
if(displayTime % 1 != 0)
{
$('.time').text(displayTime.toString());
}
else
{
$('.time').text(displayTime.toString() + ".0");
}
}, 100);
}
else //behavior is the same if i remove the else block
{
return;
}
}
$(document).ready(function () {
var time = 0;
var stop = false;
timerTick(time, stop);
//check if we're at the bottom
$(window).scroll(function() {
if($(window).scrollTop() + $(window).height() == $(document).height()) {
stop = true;
clearInterval(intervalId);//HERE clear the interval
}
});
});
DEMO
to determine bottom of the page you could try this
if(window.innerHeight + document.body.scrollTop >= document.body.offsetHeight) {
stop = true;
}
Update:
you need to make your variable stop global, declare it outside of documnet.ready function.
setInterval function returns number that you can later pass into clearInterval to stop the timer.
Declare
var Timeout=0;
check
if(stop == false)
inside the setInterval function
like
Timeout=setInterval(function ()
{
if(stop == false)
{
time += 1;
var displayTime = time/10;
if(displayTime % 1 != 0)
{
$('.time').text(displayTime.toString());
}
else
{
$('.time').text(displayTime.toString() + ".0");
}
}
else
{
clearInterval(Timeout);
}
}, 100);

Categories

Resources