Skip to content

Instantly share code, notes, and snippets.

@Sjeiti
Created March 7, 2017 08:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sjeiti/f5910d0e5679b4bd76d952bb4041179b to your computer and use it in GitHub Desktop.
Save Sjeiti/f5910d0e5679b4bd76d952bb4041179b to your computer and use it in GitHub Desktop.
Simple HTML / pure JS example for element in viewport detection
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
</head>
<body>
<main>
<section data-in-view>
<h3>consectetur</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet consequatur consequuntur dolores praesentium quisquam saepe, ut. Adipisci alias commodi consequuntur enim, expedita iusto magni officiis pariatur repellat, sequi temporibus totam.</p>
</section>
<section>
<h3>laboriosam</h3>
<p>Ad, atque autem commodi doloremque explicabo fugiat laboriosam laborum magni nemo nihil odit perferendis placeat possimus quisquam rem reprehenderit, sed totam voluptatem!</p>
</section>
<section>
<h3>architecto</h3>
<p>Consectetur adipisicing elit. Accusantium animi architecto aspernatur atque, debitis eligendi est et impedit inventore iste laudantium nisi non perferendis quo sint. Ad natus porro quaerat!</p>
</section>
<section>
<h3>praesentium</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet consequatur consequuntur dolores praesentium quisquam saepe, ut. Adipisci alias commodi consequuntur enim, expedita iusto magni officiis pariatur repellat, sequi temporibus totam.</p>
</section>
<section data-in-view>
<h3>perferendis</h3>
<p>Ad, atque autem commodi doloremque explicabo fugiat laboriosam laborum magni nemo nihil odit perferendis placeat possimus quisquam rem reprehenderit, sed totam voluptatem!</p>
</section>
<section>
<h3>magni</h3>
<p>Consectetur adipisicing elit. Accusantium animi architecto aspernatur atque, debitis eligendi est et impedit inventore iste laudantium nisi non perferendis quo sint. Ad natus porro quaerat!</p>
</section>
<section>
<h3>praesentium</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet consequatur consequuntur dolores praesentium quisquam saepe, ut. Adipisci alias commodi consequuntur enim, expedita iusto magni officiis pariatur repellat, sequi temporibus totam.</p>
</section>
<section>
<h3>aspernatur</h3>
<p>Ad, atque autem commodi doloremque explicabo fugiat laboriosam laborum magni nemo nihil odit perferendis placeat possimus quisquam rem reprehenderit, sed totam voluptatem!</p>
</section>
<section data-in-view>
<h3>eligendi</h3>
<p>Consectetur adipisicing elit. Accusantium animi architecto aspernatur atque, debitis eligendi est et impedit inventore iste laudantium nisi non perferendis quo sint. Ad natus porro quaerat!</p>
</section>
</main>
<style type="text/css">
body {
font-family: Arial, sans-serif;
font-size: 24px;
}
h3 { font-size: 34px; }
main {
width: 400px;
max-width: 100%;
margin: 20px auto 40px;
}
section {
box-shadow: 0 0 0 0 white inset;
transition: box-shadow 500ms linear;
}
.in-view {
box-shadow: 0 0 0 200px red inset;
}
</style>
<script>
(function(document,window){
//var isMobile = !window.matchMedia("(min-device-width : 768px)").matches
var html = document.documentElement
,body = document.body
,className = 'in-view'
,views = Array.prototype.map.call(body.querySelectorAll('*[data-in-view]'),function(el){
return {
el: el
,was: {
above: false
,below: false
,left: false
,right: false
}
,isInView: false
}
})
,viewW
,viewH
setSize()
window.addEventListener('resize', handleResize,false)
window.addEventListener('touchmove',handleScroll,false)
window.addEventListener('scroll',handleScroll,false)
testViews()
setTimeout(testViews,40)
function handleResize(){
setSize()
testViews()
}
function handleScroll(){
testViews()
}
function setSize(){
viewW = window.innerWidth || html.clientWidth || body.clientWidth
viewH = window.innerHeight || html.clientHeight|| body.clientHeight
}
function testViews(){
views.forEach(testView)
}
function testView(view){
var el = view.el
,was = view.was
,isInView = view.isInView
,rect = el.getBoundingClientRect()
,isElmInView = getIsInView(rect)
if (isInView!==isElmInView) {
view.isInView = isElmInView
if (isElmInView) {
el.classList.add(className+'-active')
was.above&&el.classList.add(className+'-active-above')
was.below&&el.classList.add(className+'-active-below')
was.left&&el.classList.add(className+'-active-left')
was.right&&el.classList.add(className+'-active-right')
setTimeout(function(){
el.classList.remove(className+'-active')
el.classList.remove(className+'-active-above')
el.classList.remove(className+'-active-below')
el.classList.remove(className+'-active-left')
el.classList.remove(className+'-active-right')
el.classList.add(className)
},40)
} else {
el.classList.remove(className)
}
} else if (!isElmInView) {
was.above = rect.bottom<0
was.below = rect.top>viewH
was.left = rect.right<0
was.right = rect.left>viewW
}
}
function getIsInView(rect){
return rect.top<viewH
&&rect.bottom>0
&&rect.left<viewW
&&rect.right>0
}
})(document,window);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment