Created
February 10, 2016 20:56
-
-
Save thomaswilburn/641d6d7fb5e7ac1ba417 to your computer and use it in GitHub Desktop.
Scroll-triggered effects without jQuery
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This causes any elements with scroll-class attributes to add be updated either when they | |
reach the halfway point of the window, or when a target element (matching the selector in | |
the scroll-trigger attribute) reaches that point. For example: | |
<div class="example" scroll-class="activated" scroll-trigger=".trigger"> | |
This element will gain the "activated" class when the following element scrolls halfway: | |
<span class="trigger">TRIGGER ELEMENT</span> | |
</div> | |
All code is written in ES6, meant to be translated via Babel, but it should be easy to follow. | |
*/ | |
//function that returns an array of matching elements | |
var $ = s => Array.prototype.slice.call(document.querySelectorAll(s)); | |
//turn the elements into objects with target, area, and className properties | |
var elements = $("[scroll-class]").map(function(target) { | |
var area = target.getAttribute("scroll-trigger"); | |
if (area) { | |
area = document.querySelector(area) || target; | |
} else { | |
area = target; | |
} | |
var className = target.getAttribute("scroll-class") || "scroll-activated" | |
return { target, area, className }; | |
}); | |
window.addEventListener("scroll", function() { | |
elements.forEach(function(scroll) { | |
var bounds = scroll.area.getBoundingClientRect(); | |
if (bounds.top < window.innerHeight * .5) { | |
scroll.target.classList.add(scroll.className); | |
} else { | |
scroll.target.classList.remove(scroll.className); | |
} | |
}) | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
General purpose code to be notified when an element enters the viewport. | |
To be used as such: | |
var element = document.querySelector(".example"); | |
subscribe(element, subscribe.VISIBLE, function() { | |
element.classList.add("fade-in"); | |
//return true here to stay subscribed, otherwise the element is removed from further notifications | |
}); | |
*/ | |
var scrollNotified = []; | |
var noop = function() {}; | |
var subscribe = function(el, test, callback = noop) { | |
if (typeof test == "function") { | |
callback = test; | |
test = "visible"; | |
} | |
scrollNotified.push({ el, callback, test }); | |
onScroll(); | |
}; | |
subscribe.VISIBLE = "visible"; | |
subscribe.ENTER = "enter"; | |
subscribe.MIDDLE = "middle"; | |
subscribe.PAST = "past"; | |
var onScroll = function() { | |
scrollNotified = scrollNotified.filter(function(sub) { | |
var bounds = sub.el.getBoundingClientRect(); | |
switch (sub.test) { | |
case subscribe.ENTER: | |
if (bounds.top > 0 && bounds.top < window.innerHeight) { | |
return sub.callback(); | |
} | |
break; | |
case subscribe.MIDDLE: | |
if (bounds.top > 0 && bounds.top < window.innerHeight * .5) { | |
return sub.callback(); | |
} | |
break; | |
case subscribe.PAST: | |
if (bounds.top < window.innerHeight * .5) { | |
return sub.callback(); | |
} | |
break; | |
case subscribe.visible: | |
default: | |
if (bounds.top > 0 && bounds.bottom < window.innerHeight) { | |
return sub.callback(); | |
} | |
} | |
return true; | |
}); | |
}; | |
window.addEventListener("scroll", onScroll); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment