JSFiddle - React, Tailwind, and code Playground
by jyoze
HTML
<div id="dummy-scroller">
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
<div class="js-ani"></div>
</div>
CSS
body {
margin: 0;
}
#dummy-scroller {
height: 5000px;
}
.js-ani {
width: 100px;
height: 100px;
padding: 10px;
background: red;
margin: 100px auto;
opacity: 0.3;
transition: opacity 500ms;
}
.js-ani.js-ani-on {
opacity: 1
}
JavaScript
$(function () {
// 繰り返し使うものは、毎回計算せずに変数に保存しておきます
var $window = $(window);
var $targets = $('.js-ani');
// あとでクラスを変えたい時、ここだけ編集すればいいようにしておきます
var onClass = 'js-ani-on';
// ページ更新などで、画面の途中から表示される場合のテスト
// $window.scrollTop(500);
var options = {
offset: function ($target) {
return $target.outerHeight()
}
}
// 初期表示で各要素の座標を判定して処理する
toggleClassOnScreenEdges(options);
// スクロールするたびに各要素の座標を判定して処理する
$window.on('scroll', function () {
toggleClassOnScreenEdges(options);
});
function toggleClassOnScreenEdges (options) {
if (!options) {
options = {
offset: 0
}
}
var scrollTop = $window.scrollTop();
var scrollBottom = scrollTop + $window.outerHeight();
$targets.each(function () {
var $target = $(this);
var targetTop = $target.offset().top;
var targetBottom = targetTop + $target.outerHeight();
var offset = typeof options.offset === 'function'
? options.offset($target)
: options.offset
// 要素の上辺(+offset)が画面の下辺よりも上にあり、
// 要素の下辺(-offset)が画面の上辺よりも下にあるとき、
// 要素のすべてが画面の中にあると判定する
if ((targetTop + offset) < scrollBottom && (targetBottom - offset) > scrollTop) {
$target.addClass(onClass);
} else {
$target.removeClass(onClass);
}
});
}
});