GithubHelp home page GithubHelp logo

xtianmiller / emergence.js Goto Github PK

View Code? Open in Web Editor NEW
1.9K 31.0 62.0 317 KB

Detect element visibility in the browser

Home Page: https://xtianmiller.github.io/emergence.js/

License: MIT License

JavaScript 100.00%
viewport visibility reveal animation javascript scroll element

emergence.js's Introduction

Emergence.js - detect element visibility in the browser

Emergence.js is a lightweight, high-performance JS plugin for detecting and manipulating elements in the browser.

Emergence.js - detect element visibility in the browser


License: MIT NPM version CDNJS version

  • Dependancy-free
  • IE8+ and all modern browsers
  • 1KB minified and gzipped

View Demo


Why Use It?

This plugin is designed to allow manipulation on elements depending on their visibility in the browser. It gives the developer the freedom to use their own CSS or JS to determine what happens; whether it's animation or a change in state. It leverages HTML5 data-* attributes instead of classes for ease and developer clarity. Emergence.js is one of the lightest and most compatible plugins of its kind.


Getting Started

Reference emergence.js just before your closing </body> tag, then simply call emergence.init.

<script src="path/to/emergence.min.js"></script>
<script>
  emergence.init();
</script>

Grab the latest code from the following locations:


How To Use

Add data-emergence="hidden" to any element you wish to watch:

<div class="element" data-emergence="hidden"></div>

When the element becomes visible within the viewport, the attribute will change to data-emergence="visible". Now you can leverage CSS, for example, to animate the element:

.element[data-emergence=hidden] {
  /* Hidden state */
}
.element[data-emergence=visible] {
  /* Visible state */
}

Custom Options

Emergence.js has a number of options you can customize. Below are the defaults:

emergence.init({
  container: window,
  reset: true,
  handheld: true,
  throttle: 250,
  elemCushion: 0.15,
  offsetTop: 0,
  offsetRight: 0,
  offsetBottom: 0,
  offsetLeft: 0,
  callback: function(element, state) {
    if (state === 'visible') {
      console.log('Element is visible.');
    } else if (state === 'reset') {
      console.log('Element is hidden with reset.');
    } else if (state === 'noreset') {
      console.log('Element is hidden with NO reset.');
    }
  }
});

Options Explained

container

By default, the visibility of elements will be determined by the window's viewport dimensions and X/Y scroll position (when set to window). However, it's possible to change it to a custom container. For example:

var customContainer = document.querySelector('.wrapper');

emergence.init({
  container: customContainer
});

throttle

Throttle is a method that prevents performance issues associated with scroll and resize events. The throttle will create a small timeout and steadily check element visibility every set amount of milliseconds during the event. The default is 250.

reset

Determines whether the data-attribute state will reset after it's been revealed. Set reset to false if you wish for the element to stay in its revealed state even after leaving the viewport. The default is true.

handheld

Emergence will do a check for most handheld device models such as phones and tablets. When set to false, the plugin will not run on those devices. The default is true.

elemCushion

The element cushion will determine how much of the element needs to be within the viewport to count as "visible". A value of 0.5 would equate to 50% of the element needing to be visible. The default is 0.15.

offsetTop, offsetRight, offsetBottom, offsetLeft

Provide an offset (in pixels) on any edge of the viewport. This is useful if you have a fixed component such as a header, for which you can offset the same value as the height of the header. A value of 100 applied to offsetTop will mean elements will only count as visible when they are greater than 100 pixels from the top of the viewport. The default for all is 0.

callback

Useful for providing callbacks to determine when an element is visible, hidden and reset. The possible states are visible, reset, and noreset.


Advanced

Engage

If you want to refire visibility checks outside of the load, scroll and resize events already baked into the plugin, use the following:

emergence.engage();

Disengage

If you want to disable Emergence, use the following:

emergence.disengage();

Browser Support

Emergence.js is dependent on the following browser APIs:


Issues & Contributions

Issues can be resolved quicker if they are descriptive and include both a minimal test case and a set of steps to reproduce.

While new features are welcome, any contributions that can fix bugs, maximize compatibility, and improve performance are preferred.


Release history

  • 1.1.2
    • Added handheld detection for Kindle Fire and PlayBook
    • Updated comments
    • Updated npm packages
    • Optimized animations on demo
    • Optimized responsive styles on demo
    • Added release history to README.md

emergence.js's People

Contributors

extend1994 avatar jdoleary avatar watermelonpizza avatar xtianmiller avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

emergence.js's Issues

Per-item options

Would be nice to be able to define the options on an individual element. For instance, you might want one element to grow when it's 50% visible, and some other to only react when it's 60% visible.

destroy method

Hey. I am using your script in a project and want to ask you, if there is any option to destroy emergence.

cheers
Marco

DOM re-render implications?

How does this lib function with libs like React, which might re-render an element under the hood? Would .engage() need to be called again?

Reset: false not working?

Hey there,

I've specified in the settings reset:false, but the emergence status is still resetting after it's left the viewport. I'm using Chrome version 56.0.2924.87, and it's happening in 2 separate projects.

Any clues as to what might be causing this?

Code below:

(function($, document) {

var six_inview = {

    on_ready: function() {
        six_inview.initEmergence();
    },

    initEmergence: function() {
        emergence.init({
            reset: false
        });
    },
}

$(document).ready( six_inview.on_ready );

}(jQuery, document));

Multiple Instances of `emergence`?

Is it possible to have multiple instances of the emergence object with different options active?

Consider the following:

import * as emergeOnce from 'emergence.js'
import emergence from 'emergence.js'

emergeOnce.init({ reset: false })
emergence.init()

This is possible, but is there an option for the queryselector data-emergence to be set? If no, how about setting inline options, such as data-emergence-reset="false" for unique conditions?

Define "visible"

The README never really defines the complete criteria it uses to determine whether an element is visible. From what I can determine looking at the code, the element's CSS visibility, opacity, and transform are not considered for example, but the display property is checked. Intersection with the viewport is the primary criterion.

Feature Request?

Thanks for the lightweight and awesome plugin and I have 1 question?

Instead of changing the [data-emergence=visible] can we add the Class Toggle? Example:

I am using the animate.css and want to add some animate class to enter visible viewport.

Current condition is ok and I can customize the Classes but if I do this then I will duplicate this CSS file for [data-emergence=visible] right?

I hope you can understand me :)

Thanks.

Offset in percentage or em?

Thank you for a great and simple plugin to use! Would you consider adding support for percentage based or vh based offsets (if that's even possible)?

The problem I am having is that px result in very different timings on a smaller screens vs larger screens. On smaller screens 400px is a lot of the viewport height, but on a large screen it's not. I need a way to trigger the visibility when users reach the same area, regardless of screen size.

Property override support per element

Allow the user to override offsets/cushion properties with a data attribute on specific elements. For example:

<p data-emergence="hidden" data-offset-top="100" data-cushion="0.5">Emergence rock's!</p>

This will allow more flexibility on complex websites.

Doesn't work on load

When element is in viewport on loading ( initial view ), sometimes it doesn't work. Can't find any 'rule' when this is happening, anyone had similar problem ?

Staggering `data-emergence` Toggle

When multiple items are suddenly made visible, it would be great to have an option that would stagger the [data-emergence=visible] change based on source order. This allows for some really appealing intro animations for sections of a site. This prevents having to hard-code transition-delay or animation-delay in the CSS, which will cause unnecessary delays if items are not made visible at the same time.

For example:

<body>
<div class="scene-1" data-emergence="hidden" style="height: 33vh"></div>
<div class="scene-2" data-emergence="hidden" style="height: 33vh"></div>
<div class="scene-3" data-emergence="hidden" style="height: 33vh"></div>
</body>

JS:

emergence.init({
   stagger: 100 // Delay in ms between item attribute changes
});

Because all items are revealed in the viewport at the same time and the stagger option is set:
.scene-1 gets data-emergence=visible change right away
.scene-2 gets data-emergence=visible after 100ms
.scene-3 gets data-emergence=visible after 200ms

Uncaught TypeError: viewport.addEventListener is not a function...

Hi, I'm playing your package. It seams that it sweats my needs. Good job. :) Back to the issue. I'm using Laravel Mix for handling all js and css assets.

In my main js file app.js I have just added these simple lines:

import emergence from 'emergence.js';
emergence.init();

After the Mix compilation npm run dev I included the final js file in my html. Here is the error I get:

app.js:292 Uncaught TypeError: viewport.addEventListener is not a function
    at Object.emergence.init (app.js:292)
    at Object.<anonymous> (app.js:79)
    at __webpack_require__ (app.js:20)
    at Object.<anonymous> (app.js:364)
    at __webpack_require__ (app.js:20)
    at Object.defineProperty.value (app.js:66)
    at app.js:69

Hope you can help me.

IntersectionObserver

Why not feature check for IntersectionObserver support and use it when available?

Watched elements not visible when scrolled to on mobile

Hi, thanks for the awesome plugin. I found an issue where I have data-emergence="hidden" on my watched element and works fine on desktop. However, on mobile (Android OS) the elements are not being revealed like they are on desktop, they stay hidden.

Trigger animation when div is visible

I have a little paper plane and want to satrt its animation qhen the div enters de viewport. This is what i have in the css:
@Keyframes example {
0% {left:0%; top:75%;}
25% {left:25%; top:75%;}
50% {left:75%; top:75%;}
100% {left:100%; top:75%;}
}

.target[data-emergence=visible] {
animation-name: example;
animation-duration: 5s
}

Do i have to attach this to the div or to the image i want to animate?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.