[JS]Passing arguments to event handlers, The Intersection Observer API


コースソース:完全JavaScript Course 2022 Jonas(Udemy)
Passing Arguments to Event Handlers
イベントハンドラにイベント以外のパラメータを追加する必要がある場合の解決+分解テクニック(一般的な論理)
  • 反復コードを関数にします.
  • の重複しない部分を因子とする.ex) opacity
    but! eventHandler関数はeのみをパラメータとして受け入れます!
    コールバック関数をbindにバインドし、パラメータに不透明性を追加します.bind関数は、このパラメータをパラメータに付与します.
  • Menu fade animation
    const handleHover = function (e) {
      if (e.target.classList.contains('nav__link')) {
        const link = e.target;
        const siblings = link.closest('.nav').querySelectorAll('.nav__link');
        const logo = link.closest('.nav').querySelector('img');
    
        siblings.forEach(el => {
          if (el !== link) {
            el.style.opacity = this;
          }
          logo.style.opacity = this;
        });
      }
    };
    
    //Passing "argument" into handler
    nav.addEventListener('mouseover', handleHover.bind(0.5));
    
    nav.addEventListener('mouseout', handleHover.bind(1));
    
    The Scroll Event
    Implementing a Sticky Navigation
    const initialCoords = section1.getBoundingClientRect();
    
    window.addEventListener('scroll', e => {
       //console.log(window.scrollY); //viewport의 top에서 page의 top까지
       if (window.scrollY > initialCoords.top) {
         nav.classList.add('sticky');
       } else {
         nav.classList.remove('sticky');
       }
     });
    注意)スクロールイベントはなるべく書き込まないことをお勧めします.頻繁に起こったから
    The Intersection Observer API
    entries:しきい値配列と見なすこともできます.
    const obsCallback = function (entries, observer) {
      entries.forEach(entry => console.log(entry));
    };
    const obsOptions = {
      root: null, //null : entire view port. root : intersecting 하고 싶은 target
      threshold: [0, 0.2], //view port의 percent  => 이 percent 이상으로 intersecting 하면 callback 함수를 실행한다.
      rootMargin : '10px' //visual margin of root(target element).
    };
    
    const observer = new IntersectionObserver(obsCallback, obsOptions);
    observer.observe(section1);
    Sticky navigation:Scrollイベントに代わるIntersection Observer API
    const header = document.querySelector('.header');
    const navHeight = nav.getBoundingClientRect().height;
    
    const stickyNav = function (entries) {
      const [entry] = entries; // = entry = entries[0] destructuring
      if (!entry.isIntersecting && entry.intersectionRatio === 0) {
        nav.classList.add('sticky');
      } else {
        nav.classList.remove('sticky');
      }
    };
    const headerObserver = new IntersectionObserver(stickyNav, {
      root: null,
      threshold: 0,
      rootMargin: `-${navHeight}px`,
    });
    headerObserver.observe(header);
    
    Revealing Elements on Scroll
    The Intersection Observer APIを使用してスクロールするたびに、適切なセグメント効果サイクルが実行されます.
    const allSections = document.querySelectorAll('.section');
    const revealSection = function (entries, observer) {
      const [entry] = entries; // threshold 하나만 있으므로.
      if (!entry.isIntersecting) return;
      entry.target.classList.remove('section--hidden');
      sectionObserver.unobserve(entry.target); // 한번만 실행하고자. 더이상 관찰할 이유가 없음.
    };
    const sectionObserver = new IntersectionObserver(revealSection, {
      root: null,
      threshold: 0.15,
    });
    
    allSections.forEach(section => {
      sectionObserver.observe(section);
      section.classList.add('section--hidden');
    });
    Lazy Loading Images
    The Intersection Observer APIによるイメージロード機能
    Lazy loading images
    const imgTargets = document.querySelectorAll('img[data-src]');
    
    const loadImg = function (entries, observer) {
      const [entry] = entries;
      console.log(entry);
      if (!entry.isIntersecting) return;
    
      //Replace src with data-src
      entry.target.src = entry.target.dataset.src;
      entry.target.addEventListener('load', () => {
        entry.target.classList.remove('lazy-img'); 
        // img가 다 load 된 다음에 실행시키는 것이 좋다.  
        //느린 컴퓨터에서는 src가 바뀌기도 전에 blur 가 없어지기도 하므로,,
      });
      observer.unobserve(entry.target);
    };
    const imgObserver = new IntersectionObserver(loadImg, {
      root: null,
      threshold: 0,
      rootMargin: '200px',
    });
    
    imgTargets.forEach(img => imgObserver.observe(img));
    画像のsrcを置き換えた後、load eventを実行することを覚えておいてください.画像のロードが完了した後に効果を生成するために.