다른 js파일에 있는 변수 사용을 위해 export, import를 넣었는데 웹페이지에 오류가 났어요

조회수 290회

안녕하세요 간단한 로또 추첨 프로그램을 만들고있는 코린이입니다. 동작원리는 lotto.html에서 랜덤으로 당첨번호 여섯자리가 나오고, 로또 구매 버튼을 누르면 팝업창으로 popUp.html 이 나오면서 다섯 줄의 랜덤한 여섯자리 숫자가 나오는데 이 떄, lotto에서 나온 랜덤 숫자와 popUp에서 나온 숫자를 비교해서 일치하는 순으로 1등~5등, 낙첨 문구를 표시하는게 목표인데요 (로또 자동 처럼)

그래서 lotto.js에 있는 numbers 변수(로또 당첨번호 배열)를 popUp.js에 가져와 쓰고 싶어서 export와 import를 입력하니 popUp.html에 추첨결과 문구를 제외하고 랜덤숫자가 만들어놓은게 다 안뜨더라구요..?

뭐가 문제인가 싶어 데브툴로 살펴보니 lotto.js:12 Uncaught TypeError: Cannot read properties of null (reading 'appendChild') at randomMachine (lotto.js:12:13) at lotto.js:15:1 라는 창이 떴습니다. (갑자기 appendChild는 왜 걸고 넘어짐? imort export를 지우면 또 에러없이 정상작동합니다)

html에서 script 연결도 마지막에 했고 type도 module로 바꿔봤는데 안되더라구요,. 방법을 도저히 모르겠어서 질문드립니다.

[💩코드 더러움 주의]

< lotto.html >

//<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="/css/lotto.css" />
    <title>Lotto</title>
    <h2 id="remain-time"></h2>
  </head>
  <body>
    <div id="winNumBox">
      <h1>금주의 당첨 번호</h1>
      <ul id="win-nums"></ul>
    </div>

    <div id="remainBox">
      <p>다음 추첨일 까지:</p>
      <h3 id="remain-time"></h3>
    </div>

    <button id="buy-btn">로또 구매</button>

    <script type="module" src="/js/lotto.js"></script>
  </body>
</html>

< lotto.js >

export let numbers = new Array(6) // 로또번호 배열

let ul = document.getElementById('win-nums');


// 당첨 번호 랜덤 생성
function randomMachine() {
    for(let i = 0; i < numbers.length; i++) {
        numbers[i] = Math.floor(Math.random() * 45 + 1);
        let li = document.createElement('li');
        li.textContent = numbers[i];
         ul.appendChild(li);
    }
}
randomMachine();

// 팝업창
document.getElementById('buy-btn').onclick = popUp;

function popUp() {
    window.open("popUp.html", "pop", "width= 500, height= 600, left= 100, top= 200");
}

< popUp.html >

//<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="stylesheet" href="/css/popUp.css" />
    <title>로또 추첨결과</title>
  </head>
  <body>
    <div id="main">
      <h1>추첨 결과</h1>
      <div id="numContainer">
        <div class="numBox">
          <h3 id="result-1"></h3>
          <ul id="nums-1" class="nums"></ul>
        </div>
        <ul id="nums-2" class="nums"></ul>
        <ul id="nums-3" class="nums"></ul>
        <ul id="nums-4" class="nums"></ul>
        <ul id="nums-5" class="nums"></ul>
      </div>
    </div>

    <script type="module" src="/js/popUp.js"></script>
  </body>
</html>

< popUp.js >

//// 팝업창 랜덤 번호 생성
let numbers2 = new Array(6); // 로또번호 배열

let ul1 = document.getElementById('nums-1');
let ul2 = document.getElementById('nums-2');
let ul3 = document.getElementById('nums-3');
let ul4 = document.getElementById('nums-4');
let ul5 = document.getElementById('nums-5');


// 당첨 번호 랜덤 생성
function randomMachine1() {
    for(let i = 0; i < numbers2.length; i++) {
        numbers2[i] = Math.floor(Math.random() * 45 + 1);
        let li1 = document.createElement('li');
        li1.textContent = numbers2[i];
         ul1.appendChild(li1);
    }
}

function randomMachine2() {
    for(let i = 0; i < numbers2.length; i++) {
        numbers2[i] = Math.floor(Math.random() * 45 + 1);
        let li2 = document.createElement('li');
        li2.textContent = numbers2[i];
         ul2.appendChild(li2);
    }
}

function randomMachine3() {
    for(let i = 0; i < numbers2.length; i++) {
        numbers2[i] = Math.floor(Math.random() * 45 + 1);
        let li3 = document.createElement('li');
        li3.textContent = numbers2[i];
         ul3.appendChild(li3);
    }
}

function randomMachine4() {
    for(let i = 0; i < numbers2.length; i++) {
        numbers2[i] = Math.floor(Math.random() * 45 + 1);
        let li4 = document.createElement('li');
        li4.textContent = numbers2[i];
         ul4.appendChild(li4);
    }
}

function randomMachine5() {
    for(let i = 0; i < numbers2.length; i++) {
        numbers2[i] = Math.floor(Math.random() * 45 + 1);
        let li5 = document.createElement('li');
        li5.textContent = numbers2[i];
         ul5.appendChild(li5);
    }
}

randomMachine1();
randomMachine2();
randomMachine3();
randomMachine4();
randomMachine5();

import {numbers} from './lotto.js';

1 답변

  • 좋아요

    1

    싫어요
    채택 취소하기

    popUp.js의 아래 부분:

    import {numbers} from './lotto.js';
    

    는 단순히 lotto.js에서 numbers만 쏙 빼오는 기능이 아닙니다. 다른 파일에서 내보내는 뭔가를 가져오는건 맞지만, 그 다른 파일의 전체 실행이 필수로 선행됩니다.

    1. lotto.html을 불러옴
    2. 버튼을 누르면 새 윈도우에서 popUp.html을 불러옴
    3. popUp.html에서 popUp.js 실행
    4. popUp.js에서 lotto.js 실행

    그리고 lotto.js를 보면:

    // 당첨 번호 랜덤 생성
    let ul = document.getElementById('win-nums');
    function randomMachine() {
      for(let i = 0; i < numbers.length; i++) {
        numbers[i] = Math.floor(Math.random() * 45 + 1);
        let li = document.createElement('li');
        li.textContent = numbers[i];
        ul.appendChild(li);
      }
    }
    randomMachine();
    

    randomMachine() 함수를 선언하면서 다음 줄에 바로 호출하죠?

    이 호출이 lotto.html을 불러온 윈도우에서 발생하면 괜찮겠지만, popUp.html을 불러온 윈도우면 문제가 됩니다.

    popUp.html에는 id가 win-nums인 태그가 없어서 ul은 null이 되기 때문입니다.

    • 친절한 답변 감사합니다! doltangdoltang@gmail.com 2022.10.19 16:23
    • 그러면 제가 의도했던대로 팝업창과 메인창을 연동할 수있는 다른 방법은 없을까요? 아니면 팝업창을 포기하고 그냥 한 html에 쓰는게 답인걸까요,, doltangdoltang@gmail.com 2022.10.19 16:27
    • 윈도우 팝업을 유지하되 js 파일을 더 쪼개거나, 언급하신 것처럼 윈도우 팝업이 아닌 레이어 팝업을 쓰는 방법이 있죠. 편집요청빌런 2022.10.20 11:01

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)