Hello, I want a certain text to appear when I scroll past it or when I scroll until the point where the text is. The effect when appearing should be somewhat like the first effect on the top of the website http://namanyayg.com/.
I want the effect in minimal code with pure CSS and JS i.e no jQuery.
I was thinking that maybe I would use something like a display:none property for a span and then when you scroll past it the display becomes block but I dont know how to trigger the effect using javascript.
Any help would be appreciated.
First wrap whatever your text or content that you want to show on scroll, in one div so that you can show hide the div depending upon the scroll. Write two classes for your target div.
Your CSS:
/*Use this class when you want your content to be hidden*/
.BeforeScroll
{
height: 100px; /*Whatever you want*/
width: 100%; /*Whatever you want*/
.
.
display: none;
}
/*Use this class when you want your content to be shown after some scroll*/
.AfterScroll
{
height: 100px; /*Whatever you want*/
width: 100%; /*Whatever you want*/
.
.
display: block;
}
Your HTML:
<!--Set class BeforeScoll to your target div-->
<div id = "divToShowHide" class = "BeforeScroll">Content you want to show hide on scroll</div>
Your Script:
<!--include these script in head section or wherever you want-->
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.1/jquery-ui.min.js" type="text/javascript"></script>
<script type = "text/javascript">
$(document).ready(function(){
//Take your div into one js variable
var div = $("#divToShowHide");
//Take the current position (vertical position from top) of your div in the variable
var pos = div.position();
//Now when scroll event trigger do following
$(window).scroll(function () {
var windowpos = $(window).scrollTop();
//Now if you scroll more than 100 pixels vertically change the class to AfterScroll
// I am taking 100px scroll, you can take whatever you need
if (windowpos >= (pos.top - 100)) {
div.addClass("AfterScroll");
}
//If scroll is less than 100px, remove the class AfterScroll so that your content will be hidden again
else {
s.removeClass("AfterScroll");
}
//Note: If you want the content should be shown always once you scroll and do not want to hide it again when go to top agian, no need to write the else part
});
});
</script>
Hope it will solve your problem.
I would recommend this plugin
http://johnpolacek.github.io/superscrollorama/
Edit:
I don't know how no one noticed that the solution had to be made without using external libraries like jQuery. However, the solution is extremely easy with basic functionality. Find it here
HTML:
<div id="parent-div">
<div id="child-div">
Psst .. I am here!!
</div>
</div>
CSS:
#parent-div
{
position:relative;
height:3000px;
width:300px;
background-color:red;
}
#child-div
{
color:white;
position:relative;
top:1000px;
width:300px;
display:none;
text-align:center;
}
JS:
var body=document.getElementsByTagName("body")[0];
var parent=document.getElementById("parent-div");
var child=document.getElementById("child-div");
body.onscroll = function(){
//console.log(documenhttps://fiddle.jshell.net/3urv0tp0/#tidyt.getElementById("child-div").style.top)
if(document.documentElement.scrollTop>=child.offsetTop)//Adjust Tolerance as you want
{
child.style.display="block"
}
};
I was looking for this either. Here i was trying to make "show text after scrolling to (number)px with fade effect". I wish it will work as it works for me :) The animation will be playing again if u scroll back to it, idk how to make it just one like in web u showed xd (i will edit if I find out)
window.addEventListener("scroll", function() {showFunction()});
function showFunction() {
if (document.body.scrollTop > 900 || document.documentElement.scrollTop > 900) {
document.getElementById("toptexts2").style.display = "block";
} else {
document.getElementById("toptexts2").style.display = "none";
}
}
.toptexts2 {
animation: fadeEffect 3s; /* fading effect takes 3s */
}
#keyframes fadeEffect { /* from 0 to full opacity */
from {opacity: 0;}
to {opacity: 1;}
}
<div class="toptexts2" id="toptexts2">
<div>Hi!</div>
<div>↓ go down ↓</div>
</div>
I like this:
var doc = document, dE = doc.documentElement, bod = doc.body;
function E(e){
return doc.getElementById(e);
}
function xy(e, d){
if(!d)d = 'Top';
d = 'offset'+d;
var r = e[d];
while(e.offsetParent){
e = e.offsetParent; r += e[d];
}
return r;
}
function x(e){
return xy(e, 'Left');
}
function y(e){
return xy(e);
}
var txt = E('theId'), txtS = txt.style;
onscroll = function(){
var left = dE.scrollLeft || bod.scrollLeft || 0;
var top = dE.scrollTop || bod.scrollTop || 0;
var w = innerWidth || dE.clientWidth || bod.clientWidth;
var h = innerHeight || dE.clientHeight || bod.clientHeight;
if(top > y(txt)-h){
txtS.display = 'none';
}
else{
txtS.display = 'block';
}
}
I left the left stuff in there, just in case, but you can probably remove it.
var div=$("#divtochange");
$(window).scroll(function () {
var windowpos = $(window).scrollTop();
//---check the console to acurately see what the positions you need---
console.log(windowpos);
//---------------------
//Enter the band you want the div to be displayed
if ((windowpos >= 0) && (windowpos <= 114)){
div.addClass("AfterScroll");
}
else{
div.removeClass("AfterScroll");
}
Related
I am attempting to write some JavaScript code that will allow me to center a child element within it's parent using padding. Then using the same function to recalculate the spacing using the 'resize' event. Before you start asking me why i am not doing this with CSS, this code is only a small part of a larger project. I have simplified the code as the rest of the code works and would only serve to confuse the subject.
Calculating the space - This is the function that caculates the amount of space to be used on either side of the child element.
($outer.outerWidth() - $inner.outerWidth()) / 2;
($outer.outerHeight() - $inner.outerHeight()) / 2;
The problem
Although i have successfully managed to get the desired results with margin. Padding is causing me problems.
It appears to be increasing the width on the outer element when resized
It does not center the child element perfectly (there appears to be an offset)
The inner element collapses on resize and becomes invisible.
I realize that there may be some fundamentals regarding padding that are causing my problems however after numerous console logs and observing the data returned i still can't put my finger on the problem. Any suggestion would be very welcome. It may turn out that this is not feasible at all.
HTML
<div id="demo" class="outer">
<div class="inner">
</div>
</div>
CSS
html {
box-sizing: border-box;
}
*, *:before, *:after {
box-sizing: inherit;
}
.outer {
width:97%;
height:400px;
border:1px solid black;
margin:20px;
}
.inner {
width:40%;
height:100px;
background-color:grey;
}
JAVASCRIPT
var $outer = $(".outer");
var $inner = $(".inner");
var getSpace = function(axis) {
if (axis.toLowerCase() == "x") {
return ($outer.outerWidth() - $inner.outerWidth()) / 2;
} else if (axis.toLowerCase() == "y") {
return ($outer.outerHeight() - $inner.outerHeight()) / 2;
}
}
var renderStyle = function(spacingType) {
var lateralSpace = getSpace("x");
var verticalSpace = getSpace("y");
var $element;
if (spacingType == "padding") {
$element = $outer;
} else if (spacingType == "margin") {
$element = $inner;
}
$.each(["top", "right", "bottom", "left"], function(index, direction) {
if (direction == "top" || direction == "bottom") {
$element.css(spacingType + "-" + direction, verticalSpace);
}
else if (direction == "right" || direction == "left") {
$element.css(spacingType + "-" + direction, lateralSpace);
}
});
};
var renderInit = function() {
$(document).ready(function() {
renderStyle("padding");
});
$(window).on("resize", function() {
renderStyle("padding");
});
}
renderInit();
EXAMPLE - link
Although I completely disagree with this approach to horizontally centring an element, hopefully this will help you on your way.
Fiddle: https://jsfiddle.net/0uxx2ujg/
JavaScript:
var outer = $('.outer'), inner = $('.inner');
function centreThatDiv(){
var requiredPadding = outer.outerWidth() / 2 - (inner.outerWidth() / 2);
console.log(requiredPadding);
outer.css('padding', '0 ' + requiredPadding + 'px').css('width','auto');
}
$(document).ready(function(){
// fire on page load
centreThatDiv();
});
$(window).resize(function(){
// fire on window resize
centreThatDiv();
});
HTML:
<div class="outer">
<div class="inner">Centre me!</div>
</div>
CSS:
.outer{ width:80%; height:300px; margin:10%; background: tomato; }
.inner{ width:60px; height:60px; background:white; }
Furthered on from why I disagree with this approach - JavaScript shouldn't be used to lay things out. Sure - it can be, if it really needs to be used; but for something as simple as centring an element, it's not necessary at all. Browsers handle resizing CSS elements themselves, so by using JS you introduce more headaches for yourself further down the line.
Here's a couple of examples of how you can achieve this in CSS only:
text-align:center & display:inline-block https://jsfiddle.net/0uxx2ujg/1/
position:absolute & left:50% https://jsfiddle.net/0uxx2ujg/2/ (this can be used for vertically centring too which is trickier than horizontal)
You can create the new CSS class to adjust for elements size on $window.onresize = function () {
//add your code
};
let's get straight to the point:
My code looks like the following:
<div id="keep_up">
<div id="thread_menu">
<div id="new_thread">
</div>
</div>
</div>
And my css:
#keep_up {
position: fixed;
width: 13%;
}
#thread_menu{
height: 80vh;
width: 100%;
float: left;
position: relative;
}
Now i use this for a forum. and this is basically to show the active and new threads on the side of the screen.
However. When watching a thread, the header disappears (Wich makes sense because we are scrolling down).
but i want the thread menu to stay on my side (So that it is always visible). In this case that is happening because my keep_up div has position: fixed. But i only see half of the thread menu becuase it is too long and won't scroll up.
My question:
I want the thread menu to scroll up, untill it reaches the top of my window. From then on i want it to stay there.
How do i do this?
I saw a few examples but none of them worked for me.
EDIT: Code i tried:
<script src="jquery.min.js">
$(window).scroll(function () {
var margin = null;
$(window).on("scroll", function () {
var scrollHeight = $(document).height(),
scrollTop = $(window).scrollTop(),
offsetBottom = 110, // Offset depending on the height of the footer
offsetTop = 100, // Offset depending on the height of the header
positionTop = $(".keep_up").offset().top,
affix;
if (margin != null && (scrollTop + margin <= positionTop)) {
// The sidebar has reached the bottom and is still on the bottom
affix = false;
} else if (positionTop + $(".keep_up").height() >= scrollHeight - offsetBottom) {
// The sidebar has reached the bottom
affix = 'bottom';
} else if (scrollTop <= offsetTop) {
// The sidebar has reached the top
affix = 'top';
} else {
// The sidebar is midway
affix = false;
}
// If the sidebar hasnot changed his state, return;
if ($(".keep_up").hasClass('at' + (affix ? '-' + affix : ''))) return;
if (affix == 'bottom') {
margin = positionTop - scrollTop;
} else {
margin = null;
}
// If the related class is added to the div
$(".keep_up").removeClass('at at-top at-bottom').addClass('at' + (affix ? '-' + affix : ''))
});
});
</script>
And the CSS:
.keep_up{
/*position: fixed;*/
width: 13%;
}
.keep_up.at {
top: 1px;
position: fixed;
}
.keep_up.at-top{
}
.keep_up.at-bottom {
top: 438px;
position: absolute;
}
modify this on HTML:
<div id="prevent"></div>
<div id="keep_up" data-spy="affix" data-offset-top="200">
Add this CSS:
.affix{position: fixed !important; top:0px; z-index:999;}
.affixpatch{margin-top:100px !important;}
this will fix the div when you scroll down 200px. Change data-offset-top value to reach it on different break point.
.affixpatch is a class that will be loaded with next jquery function. it prevents to hide content behind top fixed div. Change margin-top to another value if this don't solves the "hide content" problem that always generate affixing divs.
<script>
$(function() {
//caches a jQuery object containing the header element
var header = $(".affix");
$(window).scroll(function() {
var scroll = $(window).scrollTop();
if (scroll >= 200) {
$('#prevent').addClass("affixpatch");
} else {
$('#prevent').removeClass("affixpatch");
}
});
});
</script>
Hope it helps. If not, you may have some class that rewrite or impede the correct function of this affix.
I've tested this hundreds of times, usually to fix navbars.
SCROLL:
Using overflow to scroll content:
#keep_up{
max-height:400px;
width: auto;
overflow:auto;}
This will scroll the content inside #keep_up div (or use it in another one)
NOTE: you must declare a fixed max height for this div. Set max-width only if you need.
You can use %, em, rem... no need to be px for fix the max witdth. (to get a responsive effect, use responsive measurements)
If I understand your scenario correctly, the way to do this might be to use jQuery (or native JS, but you've tagged jQuery so I'm assuming that's in play).
There's a plugin that handles this kind of thing: http://leafo.net/sticky-kit/
I'd suggest you look at the plugin source code to see how it works - an event handler function on $(window).scroll() which then toggles classes on your #thread_menu to fix it in place. To keep your code lightweight, you probably don't need everything the plugin provides.
I know how to fix the animation that goes down only when the image is showing up in the window with jQuery, but now I want to do that with JavaScript. Struggling with that. The image must be fluently go down (+50px for 1.6 seconds). Have googling around, but most of them are done with jQuery I suggest and that is not what I want. Furtermore the animation should start when the scrollTop is between 600px and 800px.
function scrollFunction() {
var animate = document.getElementById("picture");
var position = 0;
var top = 0;
var scrollTop = window.pageYOffset || document.documentElement.scrollTop;
if(scrollTop > 600 && scrollTop < 800){
position++;
animate.style.top = position + "50px";
} else {
stop();
}
}
function stop() {
clearTimeout(animate);
}
#picture {
width: 100%;
height: auto;
top: -5px;
position: relative;
display: block;
margin-left: auto;
margin-right: auto;
margin-bottom: 20px;
}
<div class="col-sm-12 col-xs-12">
<h1 class="responsive-h1">Mi<span class="logo-orange"> Pad2</span></h1>
<p class="edition-title above-text-black">Black Edition</p>
<img src="Img/picture.jpg" id="picture"/>
</div>
jsFiddle : https://jsfiddle.net/n1q3fy8w/
Javascript
var imgSlide = document.getElementById('slidedown-image');
var slideDown = setInterval(function() {
var topVal = parseInt(window.getComputedStyle(imgSlide).top, 10);
imgSlide.style.top = (topVal + 1) + "px";
}, 15);
setTimeout(function( ) { clearInterval( slideDown ); }, 1600);
You get the element first, after that you setup a setInterval which will basically move our img downwards, we then also set a setTimeout which after 1600ms remvoes the slideDown interval and the image stops. Your image however may need position: absolute.
The above answer will only work in Chrome, this however should work in all browswers
jsFiddle : https://jsfiddle.net/n1q3fy8w/1/
javascript
var imgSlide = document.getElementById('slidedown-image');
var slideDown = setInterval(function() {
var topVal = parseInt(imgSlide.style.top, 10);
imgSlide.style.top = (topVal + 1) + "px";
}, 15);
setTimeout(function( ) { clearInterval( slideDown ); }, 1600);
Ok so getComputedStyle only works in chrome, so to get this to work on all other browsers, you have to specifically set the css property on the element and not via CSS.
When you use javascript to access an element and change its style like so element.style.bottom = '150px' the .style gets you all of the css values for your inline styles on that element, so any css changes on an element that is done via a .css/.less file you can't access via javascript.
So all the above code does is we set a top: 0 on the element itself and in our code we use imageSlide.style.top instead of chrome's window.getComputedStyle
Have you considered using a CSS transition? if you are changing the value of top you should be able to add transition: top 1.6s in your css (to picture). (Then the vendor prefixed versions when you get it working)
I have these "pages" aka div's inside a scrollable container. On command, I am trying to find out what part of the div in question, is touching the top of .pageContent.
So for example, right when the page loads, no part of #page_1 is touching the top of pageContent, but as I scroll down. #page_1 hits the top of .pageContent and I now want to figure out where that is.
I know I can get the position of .pageContent using $("#pageContent").scrollTop() but these page's could be different sizes and I am not sure how to go about figuring it out.
Could anyone put me in the right direction?
jsfiddle
HTML
<div id="pageContent">
<div id="page_1" class="content"></div>
<div id="page_2" class="content"></div>
<div id="page_3" class="content"></div>
</div>
CSS
#pageContent {
overflow: auto;
width:500px;
height:300px;
padding:10px;
border:1px solid black;
background-color:grey;
}
.content {
height:400px;
width:300px;
margin:0 auto;
background-color:red;
margin-bottom:10px;
}
You can use the jQuery .position() function to compute where each page is in relation to the top of the container. See this Fiddle.
For example, for #page_1,
var page1 = $('#page_1');
$('#pageContent').scroll(function() {
// page1.position().top gives the position of page_1 relative to the
// top of #pageContent
});
ScrollTop can be used, be I wouldn't recommend it.
Attach a scroll event to your main div and listener for all the objects inside:
$('#pageContent').scroll(function(){
var pages = $("#pageContent > .content");
for (var i = 0; i < pages.length; i++)
{
if ($(pages[i]).position().top < 0 && ( $(pages[i]).position().top + $(pages[i]).outerHeight() ) > 0)
{
var outerHeight = $(pages[i]).outerHeight();
var pixels = (outerHeight - (outerHeight + $(pages[i]).position().top));
console.log("These pixels are in view between: " + pixels + " and " + outerHeight );
}
}
})
Every time the div scroll a loop is performed checking the position of all elements. If the elements scroll out of view a the top the if is triggered, calculating the remaining visible pixels of the page currently visible.
This uses jQuery's: position() and outerHeight() and JavaScript's native offsetTop.
http://jsfiddle.net/q5aaLo9L/4/
I tried something like this
$(document).ready(function () {
var divs = $('.content').map(function (i, el) {
return $(el).offset().top - $(el).parent().offset().top;
});
$('#pageContent').scroll(function () {
var index = findIndex($(this).scrollTop(), divs) - 1;
if (index > -1) {
console.log($(this).children().eq(index).attr('id'));
} else {
console.log('outside');
}
});
});
function findIndex(pos, divs) {
return (divs.filter(function (el, et) {
return et <= pos
}).length);
}
It's not super clean code because I had to do it quickly.
DEMO
I hope this helps
I mocked this up, it uses JQuery's each() function to iterate through the pages and return the information of the page that has breached the top of the box.
I wasn't sure from your question exactly what you wanted returned, so I got it to return either the percentage of the page that has cleared the top border, the position (as negative value of pixels) of the top of the "page " in relation to the content container, and also just the ID of that div.
var getCurrentPage = function(){
var page;
var position;
var percentageRead;
$('.content').each(function(){
if($(this).position().top <= 0){
page = $(this);
position = $(this).position().top;
}
});
percentageRead = ((position *-1)/ $(page).height()* 100);
console.log(page.attr('id'));
console.log(position);
console.log(percentageRead + '%');
}
$('#pageContent').on('scroll', getCurrentPage);
You could fire this on any event but I used scroll to build it.
I have an h1 that is far down a page..
<h1 id="scroll-to">TRIGGER EVENT WHEN SCROLLED TO.</h1>
and I want to trigger an alert when the user scrolls to the h1, or has it in it's browser's view.
$('#scroll-to').scroll(function() {
alert('you have scrolled to the h1!');
});
how do I do this?
You can calculate the offset of the element and then compare that with the scroll value like:
$(window).scroll(function() {
var hT = $('#scroll-to').offset().top,
hH = $('#scroll-to').outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
if (wS > (hT+hH-wH)){
console.log('H1 on the view!');
}
});
Check this Demo Fiddle
Updated Demo Fiddle no alert -- instead FadeIn() the element
Updated code to check if the element is inside the viewport or not. Thus this works whether you are scrolling up or down adding some rules to the if statement:
if (wS > (hT+hH-wH) && (hT > wS) && (wS+wH > hT+hH)){
//Do something
}
Demo Fiddle
Combining this question with the best answer from jQuery trigger action when a user scrolls past a certain part of the page
var element_position = $('#scroll-to').offset().top;
$(window).on('scroll', function() {
var y_scroll_pos = window.pageYOffset;
var scroll_pos_test = element_position;
if(y_scroll_pos > scroll_pos_test) {
//do stuff
}
});
UPDATE
I've improved the code so that it will trigger when the element is half way up the screen rather than at the very top. It will also trigger the code if the user hits the bottom of the screen and the function hasn't fired yet.
var element_position = $('#scroll-to').offset().top;
var screen_height = $(window).height();
var activation_offset = 0.5;//determines how far up the the page the element needs to be before triggering the function
var activation_point = element_position - (screen_height * activation_offset);
var max_scroll_height = $('body').height() - screen_height - 5;//-5 for a little bit of buffer
//Does something when user scrolls to it OR
//Does it when user has reached the bottom of the page and hasn't triggered the function yet
$(window).on('scroll', function() {
var y_scroll_pos = window.pageYOffset;
var element_in_view = y_scroll_pos > activation_point;
var has_reached_bottom_of_page = max_scroll_height <= y_scroll_pos && !element_in_view;
if(element_in_view || has_reached_bottom_of_page) {
//Do something
}
});
I think your best bet would be to leverage an existing library that does that very thing:
http://imakewebthings.com/waypoints/
You can add listeners to your elements that will fire off when your element hits the top of the viewport:
$('#scroll-to').waypoint(function() {
alert('you have scrolled to the h1!');
});
For an amazing demo of it in use:
http://tympanus.net/codrops/2013/07/16/on-scroll-header-effects/
Inview library triggered event and works well with jquery 1.8 and higher!
https://github.com/protonet/jquery.inview
$('div').on('inview', function (event, visible) {
if (visible == true) {
// element is now visible in the viewport
} else {
// element has gone out of viewport
}
});
Read this https://remysharp.com/2009/01/26/element-in-view-event-plugin
Fire scroll only once after a successful scroll
Note: By successful scroll I mean when the user has scrolled to the desired
element or in other words when the desired element is in view
The accepted answer worked 90% for me so I had to tweak it a little to actually fire only once.
$(window).on('scroll',function() {
var hT = $('#comment-box-section').offset().top,
hH = $('#comment-box-section').outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
if (wS > ((hT+hH-wH)-500)){
console.log('comment box section arrived! eh');
// This detaches the scroll so doStuff() won't run more than once
$(window).off('scroll');
doStuff();
}
});
You could use this for all devices,
$(document).on('scroll', function() {
if( $(this).scrollTop() >= $('#target_element').position().top ){
do_something();
}
});
Intersection Observer can be the best thing IMO, without any external library it does a really good job.
const options = {
root: null,
threshold: 0.25, // 0 - 1 this work as a trigger.
rootMargin: '150px'
};
const target = document.querySelector('h1#scroll-to');
const observer = new IntersectionObserver(
entries => { // each entry checks if the element is the view or not and if yes trigger the function accordingly
entries.forEach(() => {
alert('you have scrolled to the h1!')
});
}, options);
observer.observe(target);
You can use jQuery plugin with the inview event like this :
jQuery('.your-class-here').one('inview', function (event, visible) {
if (visible == true) {
//Enjoy !
}
});
Link : https://remysharp.com/2009/01/26/element-in-view-event-plugin
This should be what you need.
Javascript:
$(window).scroll(function() {
var hT = $('#circle').offset().top,
hH = $('#circle').outerHeight(),
wH = $(window).height(),
wS = $(this).scrollTop();
console.log((hT - wH), wS);
if (wS > (hT + hH - wH)) {
$('.count').each(function() {
$(this).prop('Counter', 0).animate({
Counter: $(this).text()
}, {
duration: 900,
easing: 'swing',
step: function(now) {
$(this).text(Math.ceil(now));
}
});
}); {
$('.count').removeClass('count').addClass('counted');
};
}
});
CSS:
#circle
{
width: 100px;
height: 100px;
background: blue;
-moz-border-radius: 50px;
-webkit-border-radius: 50px;
border-radius: 50px;
float:left;
margin:5px;
}
.count, .counted
{
line-height: 100px;
color:white;
margin-left:30px;
font-size:25px;
}
#talkbubble {
width: 120px;
height: 80px;
background: green;
position: relative;
-moz-border-radius: 10px;
-webkit-border-radius: 10px;
border-radius: 10px;
float:left;
margin:20px;
}
#talkbubble:before {
content:"";
position: absolute;
right: 100%;
top: 15px;
width: 0;
height: 0;
border-top: 13px solid transparent;
border-right: 20px solid green;
border-bottom: 13px solid transparent;
}
HTML:
<div id="talkbubble"><span class="count">145</span></div>
<div style="clear:both"></div>
<div id="talkbubble"><span class="count">145</span></div>
<div style="clear:both"></div>
<div id="circle"><span class="count">1234</span></div>
Check this bootply:
http://www.bootply.com/atin_agarwal2/cJBywxX5Qp
If you are looking for a javascript version. You can call this method on scroll event listener.
showScrollTop = () =>{
const currentScrollPosition = window.pageYOffset;
let elementID = 'service-selector'
const elementOffsetTop = document.getElementById(elementID).offsetTop
if ( currentScrollPosition > elementOffsetTop){
// place your logic here
} else {
// place your logic here
}
}
window.addEventListener('scroll', showScrollTop)
If you are doing a lot of functionality based on scroll position, Scroll magic (http://scrollmagic.io/) is built entirely for this purpose.
It makes it easy to trigger JS based on when the user reaches certain elements when scrolling. It also integrates with the GSAP animation engine (https://greensock.com/) which is great for parallax scrolling websites
Just a quick modification to DaniP's answer, for anyone dealing with elements that can sometimes extend beyond the bounds of the device's viewport.
Added just a slight conditional - In the case of elements that are bigger than the viewport, the element will be revealed once it's top half has completely filled the viewport.
function elementInView(el) {
// The vertical distance between the top of the page and the top of the element.
var elementOffset = $(el).offset().top;
// The height of the element, including padding and borders.
var elementOuterHeight = $(el).outerHeight();
// Height of the window without margins, padding, borders.
var windowHeight = $(window).height();
// The vertical distance between the top of the page and the top of the viewport.
var scrollOffset = $(this).scrollTop();
if (elementOuterHeight < windowHeight) {
// Element is smaller than viewport.
if (scrollOffset > (elementOffset + elementOuterHeight - windowHeight)) {
// Element is completely inside viewport, reveal the element!
return true;
}
} else {
// Element is larger than the viewport, handle visibility differently.
// Consider it visible as soon as it's top half has filled the viewport.
if (scrollOffset > elementOffset) {
// The top of the viewport has touched the top of the element, reveal the element!
return true;
}
}
return false;
}
I use the same code doing that all the time, so added a simple jquery plugin doing it.
480 bytes long, and fast. Only bound elements analyzed in runtime.
https://www.npmjs.com/package/jquery-on-scrolled-to
It will be
$('#scroll-to').onScrolledTo(0, function() {
alert('you have scrolled to the h1!');
});
or use 0.5 instead of 0 if need to alert when half of the h1 shown.
Quick and fast implementation,
let triggered = false;
$(window).on('scroll',function() {
if (window.scrollY > ($('#scrollTo').offset().top+$('#scrollTo').outerHeight()-window.innerHeight) & !triggered){
console.log('triggered here on scroll..');
triggered = true;
}
});
using global variable triggered = false makes it just to happen once, otherwise, every time crossing past the element, this action is triggered.