프론트엔드/JavaScript

크롬 확장 프로그램을 만들면서 겪은 에러

홍수성찬 2023. 7. 17. 21:45

가끔, 프로그래밍을 하거나 디자인 연습을 할 때, 특정 페이지에서 원하는 색상을 발견할 때가 있다.

그러나, 그 색상의 정확한 RGB 값을 찾으려면 이미지를 저장하고 포토샵을 실행해서 스포이드로 RGB 값을 찾아야 하는 번잡한 방법을 선택해야 했다.

 

물론, 더 편한 방법이 있었겠지만 나는 찾지 못했고, 그래서 이를 해결하기 위한 나만의 확장 프로그램을 만들기로 했다.

그래서 브라우저에서 색상 값을 찾을 수 있는 API를 활용해서 프로그램 구현을 하기로 계획했다.

 

const button = document.querySelector(".button");

우선, 클릭할 버튼 요소를 가져오고 나서, 해당 버튼을 클릭하면 RGB 값을 선택할 수 있는 기능이 실행되도록 구현하고자 했다.

 

const pickColor = async () => {
  const eyeDropper = new EyeDropper();
  const { sRGBHex } = await eyeDropper.open();

  console.log(sRGBHex);
  alert(sRGBHex);
}

button.addEventListener("click", pickColor);

"EyeDropper()" API를 사용해 브라우저에서 특정 픽셀을 선택하여 RGB 값을 확인하려고 했다.

그래서 위 처럼 구현하였고, HTML를 로컬 환경에서 실행했을 때, 버튼을 클릭하면 제대로 동작하였다.

 

그러나, 확장 프로그램으로 로드할 때는 위의 기능이 실행되지 않고, 에러가 발생하였다.

Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')

 

"아니! 왜 클릭하면 값을 찾을 수 없어서 읽을 수 없다고 하지?"

나는 왜 Null값이 발생하며, 해당 함수를 읽을 수 없는지 이해할 수 없었다.

 

이 문제를 해결하기 위해, 구글 검색을 했고 원인과 해결 방법을 찾을 수 있었다.

 

해당 문제의 원인은 스크립트를 body의 상단에 작성하게 되면, 간혹 HTML이 로드되기 전에 스크립트를 먼저 불러오는 경우가 발생한다. 나는 body 내 하단에 선언을 했음에도 이러한 문제가 발생한 것을 보니, 꼭 body 상단이 아닌 body 내 하단에서도 발생할 수 있는 문제인 것 같았다.

 

그렇기 대문에, addEventListener을 부여할 DOM을 찾지 못해 에러가 발생한 것이었다.

스크립트를 body의 하단에 작성하면 해결할 수 있다고는 하나, 직접 해보니 결과는 같은 것을 보니 이러한 경우에도 발생할 수 있는 문제인 것 같다.

 

이 문제를 해결한 방법은 자바스크립트 파일에서 코드를 추가하는 것이었다.

window.onload = function() {}

위의 함수를 이용하면, 웹 브라우저의 모든 구성 요소에 대한 로드가 끝났을 때, 브라우저에 의해서 호출되도록 하는 함수이다. 즉, HTML을 모두 로드한 후에 함수를 호출하도록 하는 것이다. 그렇다면, 위의 문제를 해결할 수 있는 방법이 된다.

 

window.onload = function () {
    const pickColor = async () => {
        const eyeDropper = new EyeDropper();
        const { sRGBHex } = await eyeDropper.open();

        console.log(sRGBHex);
        alert(sRGBHex);
    }

	button.addEventListener("click", pickColor);
}

위 처럼, window.onload 함수를 사용해 HTML이 모두 로드되고 나서 함수를 실행하도록 하고 나니, 기존에 발생했던 Null 문제를 해결할 수 있었다.

기능 실행 결과

 

HTML이 모두 로드되기 전에 스크립트가 실행될 수 있다는 내용을 이전에 배웠지만 잊고 있었다. 이번 기회에 다시 한 번 복습한 기회가 되었고, 다음에 같은 문제가 발생할 경우, HTML이 모두 로드되기 전에 스크립트가 실행되는 것이 아닌지부터 고민할 수 있을 것 같다.