[javascript] Trigger event when user scroll to specific element - with jQuery

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?

This question is related to javascript jquery html scroll scrollto

The answer is


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


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.


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


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/


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


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);

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


Fire scroll only once after a successful scroll

The accepted answer worked for me (90%) but 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');
                // After Stuff
                $(window).off('scroll');
                doStuff();
            }

        });

Note: By successful scroll I mean when user has scrolled to my element or in other words when my element is in view.


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;
}

You could use this for all devices,

$(document).on('scroll', function() {
    if( $(this).scrollTop() >= $('#target_element').position().top ){
        do_something();
    }
});

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
    }
});

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to jquery

How to make a variable accessible outside a function? Jquery assiging class to th in a table Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Getting all files in directory with ajax Bootstrap 4 multiselect dropdown Cross-Origin Read Blocking (CORB) bootstrap 4 file input doesn't show the file name Jquery AJAX: No 'Access-Control-Allow-Origin' header is present on the requested resource how to remove json object key and value.?

Examples related to html

Embed ruby within URL : Middleman Blog Please help me convert this script to a simple image slider Generating a list of pages (not posts) without the index file Why there is this "clear" class before footer? Is it possible to change the content HTML5 alert messages? Getting all files in directory with ajax DevTools failed to load SourceMap: Could not load content for chrome-extension How to set width of mat-table column in angular? How to open a link in new tab using angular? ERROR Error: Uncaught (in promise), Cannot match any routes. URL Segment

Examples related to scroll

How to window.scrollTo() with a smooth effect Angular 2 Scroll to bottom (Chat style) Scroll to the top of the page after render in react.js Get div's offsetTop positions in React RecyclerView - How to smooth scroll to top of item on a certain position? Detecting scroll direction How to disable RecyclerView scrolling? How can I scroll a div to be visible in ReactJS? Make a nav bar stick Disable Scrolling on Body

Examples related to scrollto

Trigger event when user scroll to specific element - with jQuery How can I update window.location.hash without jumping the document? jQuery Scroll to bottom of page/iframe How can I scroll to a specific location on the page using jquery? How to scroll the window using JQuery $.scrollTo() function