getElementById로 id값을 가져오지 않고, script에서 바로 id를 지목하여 이벤트를 등록할 수 있는지 궁금합니다!!

우선 여기에서 drag & drop event 관련 공부를 하고 있었는데 그거랑 별개로…

getelementbyid 로 img 태그의 id값을 가져오지 않고,
script에서 'ball’이란 img 태그의 id를 지목하여 이벤트를 등록할 수 있는지 궁금해서 이렇게 질문을 답니다

<html lang="ko">
  <head>
    <title>Vanilla Components</title>
  </head>
  <body>
    <p>Drag the ball.</p>
    <img
      src="https://js.cx/clipart/ball.svg"
      style="cursor: pointer"
      width="40"
      height="40"
      id="ball"
    />
    <script>
      ball.onmousedown = function (event) {
        //여기서 ball이 어떻게 module로 정의됐는지...
        ball.style.position = "absolute";
        ball.style.zIndex = 1000;

        document.body.append(ball);
      
        function moveAt(pageX, pageY) {
          ball.style.left = pageX - ball.offsetWidth / 2 + "px";
          ball.style.top = pageY - ball.offsetHeight / 2 + "px";
        }
      
        moveAt(event.pageX, event.pageY);
      
        function onMouseMove(event) {
          moveAt(event.pageX, event.pageY);
        }
      
        document.addEventListener("mousemove", onMouseMove);
      
        ball.onmouseup = function () {
          document.removeEventListener("mousemove", onMouseMove);
          ball.onmouseup = null;
        };
      
        ball.ondragstart = function () {
          return false;
        };
      };
    </script>
  </body>
</html>

그리고 그 ball.onmousedown에 마우스를 올리면

그림1

이렇게 module이라고 나오는데…
여기서 제 질문은 총 세 가지 입니다

  1. 어떻게 getelementbyid 로 img 태그의 id값을 가져와서 따로 선언하지 않고,
    script 태그에서 'ball’이란 img 태그의 id를 지목하여 이벤트를 등록할 수 있는지?

  2. 위의 캡쳐짤에서 ball에 마우스를 올리면 ’ module ball '이라고 나오는데
    따로 변수로 지정된게 아닌 module 키워드는 어떤걸 의미하는지?

  3. 여기선 img 태그의 id 값이 ball이라서, script에도 ball에 메서드를 지정하였지만
    ball 대신 다른 문자나 집어넣어도 아무 error가 발생하지 않습니다

그림2

img태그와 script의 ball이란 이름으로 지정한 module(?)이 어떻게 나중에 이어지게 되는건지 궁금합니다.

  1. 에 대한 답변 :

이 예제를 보고 저도 이유를 몰라서 찾아봤는데 아래 thread 를 찾을 수 있었습니다.

자세한 내용은 아래 링크를 참고하세요.

질문하신 내용과 같은 질문인데

document 의 DOM element id 가 global properties 가 되는가?

입니다.

결론은 ‘element 에 name 또는 id 값을 지정하면 지정된 이름의 property 가 window 객체에 추가된다’ 는 것입니다.
(name 의 경우 몇몇 element 인 경우에만 window 객체에 추가되고, id 인 경우에는 모든 element 가 window 객체에 추가된다고 합니다.)

window 전역객체는 생략이 가능하기 때문에 위 원본 예제에서 ball 로 접근하면 이것은 window.ball 이 되어 img 객체를 가리키게 되는 것입니다.

따라서 document.getElementById 를 사용하지 않고 img 객체를 사용할 수 있는 것 같습니다.

하지만 이렇게 사용하는 것은 피해야 한다고 합니다.
전역 변수와 구분이 되지 않고, 또 window 객체에 원래 있던 property 와 구분이 되지 않아 혼란을 야기할 수 있습니다.
다행히도 var 로 선언된 전역변수 또는 함수 ‘ball’ 이 있는 경우에는 window.ball 보다 먼저 접근 되기 때문에 ‘ball’ element 가 DOM 상에 존재하더라도 ball 이라는 이름을 사용할 수 있습니다.

옛날 IE 가 id 를 가진 element 를 window 전역 객체에 property 로 추가했고 이것이 아주 나쁜 아이디어였음을 나중에 알게 됐지만, 이미 해당 스팩으로 개발된 사이트를 새로운 브라우져가 제대로 표시할 수 없는 문제 때문에 아직도 최신 브라우져가 이 스팩을 유지하고 있는 것 같습니다…

  1. 에 대한 답변:

‘module’ 로 표시되는 것은 아마도 IDE(제 경우에는 vscode) 가 타입을 추론했기 때문인 것으로 보입니다.
ball 이라는 변수를 그냥 사용하면 IDE 는 ball 에 대한 정보가 없고 javascript 코드상으로는 type을 알 수 없기 때문에 type 을 ‘Any’ 로 추론 할 것입니다.
그런데 ball 에 onmousedown property 를 추가하고 거기에 function 을 대입했기 때문에 IDE 가 그것을 ‘module’ 로 추론한 것입니다.

IDE 는 해당 변수가 어떤 타입 인지 소스 코드만 보아서는 알지 못하기 때문에 아무 구현이 없는 ball 을 ‘Any’ 로 추론했다가 추후에 어떤 구현이 추가되면 그것을 적절하게 다른 type 으로 추론해주는 것 같습니다.

  1. 에 대한 답변 :

img 의 id 가 ballImage 인데 shit 으로 변경하면 아마 오류가 발생할 것입니다.
오류가 발생하지 않은 이유는 잘 모르겠습니다…
새로고침 해서 ball 이미지가 드래그로 잘 움직여지는지 확인해보세요.
제 경우에는 오류로 인해 동작하지 않았습니다.

img 태그와 shit 변수는 자동적으로 이어지지 않고 id 값과 같은 이름의 변수가 img 태그와 이어지게 됩니다.

1개의 좋아요

감사합니다~!!