배경 이미지
728x90
반응형

스크롤에 따른 효과를 어떻게 줄 수 있을까?

작업업을 하다 보면 스크롤할 때 현재 화면에 어떤 요소가 보이는지 확인하고 싶을 때가 있다.

이런 기능은 아래와 같이 화면에 보이기 시작할 때 특정 위치에서 보여주거나 어떤한 효과를 주고 싶을 때 특히 유용하다.

 

직접 계산하는 방법

현재 창의 스크롤 위치와 요소의 위치, 크기를 계산하여 요소가 뷰포트에 보이는지를 확인하는 방법도 있습니다. 하지만 이러한 방법은 리플로우를 발생시켜 성능에 영향을 줄 수 있다.

 

Intersection Observer API

따라서 자바스크립트에서는 이러한 기능을 쉽게 구현하기 위한 Intersection Observer API가 있다.

이 API는 메인 스레드에 영향을 주지 않으며 비동기적으로 동작하기 때문에 성능이 더욱 효율적입니다.

또한스크롤 이벤트나 리사이즈 이벤트를 사용하지 않고도 요소가 화면에 얼마나 보이는지를 추적할 수 있다.

Intersection Observer API는  뷰포트(화면)에 요소가 들어왔는지 나갔는지를 비동기적으로 감지하는 자바스크립트 기능. 이 API는 스크롤 이벤트나 리사이즈 이벤트를 사용하지 않고도 요소가 화면에 얼마나 보이는지를 추적할 수 있게 해준다.

 

 

IntersectionObserver 객체를 생성할 때 콜백 함수를 첫 번째 인수로 전달.

이 콜백 함수는 관찰 중인 요소의 가시성 변화가 발생할 때마다 호출 됨

const io = new IntersectionObserver(function(entries) {
  entries.forEach(function(entry) {
    if (!entry.isIntersecting) {
      return;
    }
    console.log(entry.isIntersecting, entry.target);
  });
});

 

관찰할 요소들을 선택하고 관찰을 시작

const h1Els = document.querySelectorAll('h1');
h1Els.forEach(function(el) {
  io.observe(el);
});

 

마무리

Intersection Observer API는 스크롤에 따른 다양한 효과를 성능 저하 없이 구현할 수 있는 효율적인 방법입니다.

이 API를 사용하면 레이지 로딩(Lazy Loading), 무한 스크롤(Infinite Scroll), 광고 노출 추적, 애니메이션 트리거 등 다양한 스크롤 관련 기능을 쉽게 구현할 수 있습니다.

 IE, Opera Mini 를 제외한 대부분의 현대적인 브라우저에서 지원하므로, IE를 지원하지 않아도 된다면  API를 활용해보면 좋을 거 같다.

 

 

 

-끝-

 

 

728x90
반응형
728x90
반응형

 

문제 상황

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>iPad</title>
    <script defer type="module" src="./js/main.js"></script>
</head>
<body>
   
</body>
</html>

위와 같은 html 파일을 로컬환경에서 크롬 브라우져로 실행시켰더니

 

다음과 같이 에러 발생

 

에러 메시지 설명

Access to script at 'file:///C:/경로/js/module.js'  from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome, https, chrome-untrusted.

  • file://: 로컬 파일 시스템에서 로드하려고 시도함.
  • origin 'null': 로컬 파일 시스템에서의 출처는 null로 간주됨.
  • CORS policy: 다른 출처의 리소스에 접근할 때 CORS 정책에 의해 차단됨.
  • 지원되는 프로토콜: http, https, data 등 프로토콜을 통해서만 접근이 허용됨.

왜?

매번 'CORS 란게 있구나' 정도로 넘어갔기 때문에 이번 기회에 제대로 한번 알아봐야 겠다고 생각.

일단 핵심은 브라우저 보안 정책인 동일 출처 정책(SOP) 때문

 

동일 출처 정책 (SOP):란?

브라우저는 보안을 위해 동일 출처 정책(Same-Origin Policy, SOP)을 사용함.

이 정책은 한 출처(origin)에서 불러온 문서나 스크립트가 다른 출처에서 불러온 리소스와 상호작용하는 것을 제한함.

이를 통해 악성 스크립트가 사용자의 데이터를 훔치거나 변경하는 것을 방지하기 위함.

이때 출처를 구분하는 기준은 URI의 `프로토콜, 호스트, 포트`가 같은가를 통해 구분한다.

 

참고) 일반적인 HTTP(S) URL의 구성 요소

예: http://www.example.com:80/path/to/file.html

protocol host (port) resource
http:// www.example.com (:80) /folder/file.html

 

로컬 파일 시스템의 경우

예:  file:///C:/경로/js/module.js

protocol host (port) resource
file null null C:/경로/js/module.js

로컬 파일 시스템에서 file:// 프로토콜을 사용할 때는 프로토콜이 file로 고정되고,

호스트와 포트가 없기 때문에 출처가 null로 간주된다.

 

! 여기서 드는 의문 !

근데 여기서 사용한 html 파일과  html에서 불러온 JavaScript  파일은 둘다 파일 시스템에서 로드된  동일 출처 인데, 왜 CORS 오류 나는 거임?

HTML과 JavaScript 파일 로드 차이점

  1. HTML 파일 로드:
    • 브라우저는 로컬 파일 시스템(file:// 프로토콜)에서 HTML 파일을 열 수 있습니다.
    • HTML 파일은 다른 리소스(이미지, CSS, JavaScript 등)를 포함할 수 있습니다.
  2. JavaScript 파일 로드:
    • HTML 파일이 <script> 태그를 통해 JavaScript 파일을 로드하려고 할 때, type="module"이 없는 경우에는 일반 스크립트로 처리됨
      • 일반 스크립트는 로컬 파일 시스템에서 문제없이 직접 로드할 수 있으며, 상대적으로 덜 엄격한 보안 정책이 적용  
    • type="module" 속성이 있는 경우에는 ES6 모듈로 처리되어 CORS 정책이 적용됨. 
      • 모듈 스크립트는 CORS 정책을 따르기 때문에 file:// 프로토콜을 사용할 때 문제가 발생
      • 브라우저는 보안상의 이유로 로컬 파일 시스템에서 직접 모듈 스크립트를 로드하는 것을 차단함
      • 이로 인해 CORS 오류가 발생하며, null 출처에서 다른 리소스를 로드할 수 없슴

즉,

<script  src="./js/main.js"></script>

이렇게 쓰면 문제가 안됨

<script  type="module" src="./js/main.js"></script>

type="module" 쓰는 경우 CORS 정책 적용

왜 같은  JavaScript인데  type="module" 속성이 있는 경우에만 CORS 정책이 적용되는가?

  • 모듈 스크립트는 ES6 모듈의 특성상, 다른 모듈을 가져오기 위해 네트워크 요청을 사용한다. 이를 통해 브라우저는 더 엄격한 보안 정책을 적용하여, 동일 출처 정책(Same-Origin Policy, SOP)을 강제함.

 

type="module" 쓰고 싶은데 해결 방법은?

로컬 서버 사용하면 됨 ㅇㅇ

그러면 로컬 파일 시스템 대신 로컬 서버를 사용하여 파일을 제공함

쉽게 말해 로컬 서버에서 올려 `프로토콜, 호스트, 포트`를 같게 만들어 CORS 에러를 해결함. 

 

어떻게?!

http-server , live-server  등 여러가지 로컬 서버들 중에 골라서 사용하면 됨!

npm install -g http-server
or
npm install -g live-server

 

터미널 창에서 위와 같은 명령어를 통해 전역으로 설치

http-server
or
live-server

이후에는 해당 명령어만으로 로컬 서버를 실행할 수 있음. 기본적으로 8080 포트에서 실행

 

 

요약

  • 문제: type="module"을 사용한 스크립트가 로컬 파일 시스템에서 열릴 때 CORS 오류 발생.
  • 이유: 브라우저 보안 정책인 동일 출처 정책(SOP) 때문.
  • 해결책: 로컬 서버를 사용하여 파일을 제공. Node.js의 http-server를 사용하여 간단히 로컬 서버를 설정할 수 있다.

 

 

 

 

 

 

 

 

728x90
반응형

'Vanilla JS' 카테고리의 다른 글

[Vanilla JS] Intersection Observer API  (0) 2024.07.26

+ Recent posts