LoginSignup
2
1

More than 5 years have passed since last update.

JavascriptでHTML要素が画面に入った時に処理を実行する

Last updated at Posted at 2018-11-04

WebサイトやUI作成時に使えるようメモ。

・scrollイベントを拾う方法 → scrollごとにイベント発火

・IntersectionObserverを使った方法 → root要素と対象要素が交差した時にイベント発火。

IntersectionObserverの方が発火頻度が少なく軽量らしいので、こちらを使う。

1 サンプル

See the Pen InView by snst.lab (@snst-lab) on CodePen.

2 関数の定義

/**
* @function HTMLElement.prototype.inview HTML要素と画面の交差を判定し処理を実行する
*/
if(!HTMLElement.prototype.inview){
    Object.defineProperty(HTMLElement.prototype, "inview", {
        configurable: true,
        enumerable: false,
        writable: true,
        /**
        * @function callbackInView  HTML要素が画面内に入った時に実行する関数
        * @function callbackOutView  HTML要素が画面から出た時に実行する関数
        */
        value: function(callbackInView, callbackOutView) {
            const options = {
                root: null,  
                rootMargin: '0%', //要素が交差する手前でコールバックを呼び出したい場合はrootMarginに0%以外の値を
                threshold: [0.5] //交差領域が50%変化した時にコールバックを呼び出す
            };
            const observer = new IntersectionObserver((entries) => {
                for(const e of entries) {
                    //要素が画面内に入った時( e.isIntersecting 交差を判定するブール値)
                    if(e.isIntersecting && Object.prototype.toString.call(callbackInView) === '[object Function]'){
                        callbackInView(e);
                    }
                    //要素が画面から出た時
                    else if(!e.isIntersecting && Object.prototype.toString.call(callbackOutView) === '[object Function]'){
                        callbackOutView(e);
                    }
                }
            },options);
            observer.observe(this);
        }
    });
}

3 使用例

HTML

下方向にスクロールすると要素がスライドインします↓
<div class='item' style='margin-left:80%;opacity:0;'></div>

Javascript

const item = document.querySelector('.item');
item.inview(
   function(){
       //要素が画面内に入った時slideinアニメーションを適用
       item.style.animation = 'slidein 1000ms linear forwards';
 },function(){
       //要素が画面内から出たら初期値に戻す
       item.style = 'margin-left:80%;opacity:0;';
 });

CSS

.item{
  width:10rem;
  height:10rem;
  margin-top:100vh;
  border-radius:50%;
}

@keyframes slidein {
  0% {
    opacity:0;
    margin-left: 30vw;
  }
  50% {
    opacity:1.0;
    margin-left: 1vw;
    background:deeppink;
  }
  80%{
    background: yellow;
  }
  100%{
    opacity:1.0;
    margin-left: 1vw;
    background:turquoise;
  }
}

4 ブラウザ対応状況&参考URL

https://developer.mozilla.org/ja/docs/Web/API/Intersection_Observer_API#Browser_compatibility
Chrome >5.1
Edge >15
Firefox >55

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1