34

I want to show a fade effect as soon as the element appears on screen. There is a lot of content before this element so if I trigger the efect on document.ready, at certain resolutions the vistors wont´t see it.

Is it possible to trigger an event when, after scrolling down, the element becomes visible? I am almost sure I have seen this effect before, but have no idea how to achieve it.

Thank you!

agente_secreto
  • 7,959
  • 16
  • 57
  • 83
  • Duplicate? http://stackoverflow.com/questions/487073/jquery-check-if-element-is-visible-after-scroling – awshepard Jun 15 '10 at 14:02
  • Possibly another duplicate: http://stackoverflow.com/questions/1225102/jquery-event-to-trigger-action-when-a-div-is-made-visible – Anderson Green Apr 03 '13 at 02:17

7 Answers7

19

jQuery Waypoints plugin could be useful. It provides a way to trigger an action when an element becomes visible on the screen.

For instance:

$('.entry').waypoint(function() {
   alert('The element has appeared on the screen.');
});

There are some examples on the site of the plugin.

blizzrdof77
  • 363
  • 4
  • 14
Fedir RYKHTIK
  • 9,844
  • 6
  • 58
  • 68
  • 2
    This work only when we use scroll, but not if we change tabs in browser. – fdrv Feb 16 '14 at 01:42
  • 1
    @Jek-fdrv Normally, when You a changing tabs, You are using "click", so there is no problem to launch Your additional code in the same time. – Fedir RYKHTIK Feb 17 '14 at 08:38
  • 1
    I use hotkeys for change tabs, and click on tab it is not fire event by click bc it is not a DOM model. It is browser tabs. – fdrv Feb 17 '14 at 12:26
7

Jquery.appear plugin is the best way to solve this problem.

demo.

mineroot
  • 1,607
  • 16
  • 23
6

This one works better for me then the others in this post: http://www.teamdf.com/web/jquery-element-onscreen-visibility/194/

Usage is simple:

$('#element').visible()

You can see how this plugin is used to create your effect here:

http://css-tricks.com/slide-in-as-you-scroll-down-boxes/

function viewable() {
    $(".module").each(function(i, el) {
        var el = $(el);
        if (el.visible(true)) {
            el.addClass("come-in");
        });
    }
$(window).scroll(function() {
    viewable();
});
$(window).blur(function() {
    viewable();
});

If u use tabs. (for example jQuery UI tabs) you must check if tab is active.

$(window).scroll(function() {
    if($('#tab-1').hasClass('active')) {
        viewable();
    }
});
fdrv
  • 852
  • 1
  • 11
  • 21
5

If you want a simple and working sollution:

function elementInView(elem){
  return $(window).scrollTop() < $(elem).offset().top + $(elem).height() ;
};

$(window).scroll(function(){
  if (elementInView($('#your-element')))
  //fire at will!
    console.log('there it is, wooooohooooo!');
});
Aurora
  • 725
  • 1
  • 8
  • 17
  • Nice. Tweak to start a load _just as_ element begins to appear `return ($(window).height() + $(window).scrollTop()) > $(obj).offset().top;` – SushiGuy Aug 25 '18 at 22:42
1

A quick search turned up this viewport extension for jQuery that will allow you to check an element's visibility in the viewport. If your element is not in the viewport, don't do your fade-in animation.

James Sumners
  • 14,485
  • 10
  • 59
  • 77
1

I think you're referring to the jQuery plugin "Lazy Load": http://www.appelsiini.net/2007/9/lazy-load-images-jquery-plugin

From looking at the source code, it looks like the plugin is doing something like this:

$('#item').one('appear', function () {
    // Do stuff here
});
S Pangborn
  • 12,593
  • 6
  • 24
  • 24
0

If you're looking to fire an event when a specified, or target, element scrolls into view, you can do this by determining the following values:

  1. the window height
  2. the scroll distance value from the top of the window
  3. the specified, or target, element's distance from the top of the window

Consider the following:

jQuery(window).on('scroll', function(){

    var elValFromTop = Math.ceil(jQuery('.target-el').offset().top),
        windowHeight = jQuery(window).height(),
        windowScrollValFromTop = jQuery(this).scrollTop();

   // if the sum of the window height and scroll distance from the top is greater than the target element's distance from the top, it should be in view and the event should fire, otherwise reverse any previously applied methods
   if ((windowHeight + windowScrollValFromTop) > elValFromTop) {
        console.log('element is in view!');
        jQuery('.target-el').addClass('el-is-visible');
   } else {
        jQuery('.target-el').removeClass('el-is-visible');
   }

});

Code Snippet Demonstration:

The below snippet demonstrates a working example of a common issue: fixing an element to the viewport when a specified element scrolls into view.

/* Sticky element on-scroll */
jQuery(window).on('scroll', function(){

    var elValFromTop = Math.ceil(jQuery('.target-el').offset().top),
        elHeight = jQuery('.target-el').outerHeight(),
        windowHeight = jQuery(window).height(),
        windowScrollValFromTop = jQuery(this).scrollTop(),
        headerHeightOffset = jQuery('.fixed-header').outerHeight();
        
   if ((windowHeight + windowScrollValFromTop) > elValFromTop) {
        console.log('element is in view!');
        console.log(headerHeightOffset);
        jQuery('.will-change-el').addClass('fixed-el').css('top',headerHeightOffset).text('fixed');
   } else {
        jQuery('.will-change-el').removeClass('fixed-el').css('top','0').text('static');
   }
   
   // using template literals for multi-line output formatting
   // comment out to observe when target element comes into view
   console.log(`
        how far is the target element from the top of the window: ${elValFromTop}
        what is the target element's height: ${elHeight}
        what is the window height: ${windowHeight}
        what is the window's scroll value distance from the top: ${windowScrollValFromTop}
        what is the sum of the window height and its offset value from the top: ${windowHeight + windowScrollValFromTop}
        `);
        
});
/* || Reset & Defaults */
body {
  margin: 0;
}

* {
  box-sizing: border-box;
  font-family: arial;
}

/* || General */
.target-el {
  border-top: 1px solid #ccc;
}

.target-el,
.will-change-el {
  transition: .7s;
  text-align: center;
  background: #ededed;
  border-bottom: 1px solid #ccc;
}

.fixed-el {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
}

.fixed-header {
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  height: 100px;
  text-align: center;
  background: #ededed;
  border-bottom: 1px solid #ccc;
  z-index: 9;
}

.buffer-el {
  height: 1000px;
  padding-top: 100px;
  background: whitesmoke;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="fixed-header">
  <h1>Fixed Header</h1>
</div>
<div class="buffer-el">
  <div class="will-change-el">static</div>
</div>
<div class="target-el">the target element</div>

Sandbox Example: CodePen

NOTE:
This will only apply to scroll actions on the document and not to any nested elements contained within a scroll view pane.

UncaughtTypeError
  • 8,226
  • 4
  • 23
  • 38