[javascript] ID가있는 DOM 트리 요소가 전역 변수가됩니까?

간단한 HTMLElement 래퍼에 대한 아이디어를 연구하면서 Internet Explorer 및 Chrome 에서 다음을 우연히 발견했습니다 .

DOM 트리에 ID가있는 지정된 HTMLElement의 경우 ID를 변수 이름으로 사용하여 div를 검색 할 수 있습니다. 그래서 같은 사업부

<div id="example">some text</div>

인터넷 익스플로러 8 과 크롬 당신은 할 수 있습니다 :

alert(example.innerHTML); //=> 'some text'

또는

alert(window['example'].innerHTML); //=> 'some text'

그렇다면 이것이 DOM 트리의 모든 요소 가 전역 네임 스페이스의 변수로 변환 된다는 의미 입니까? 그리고이 getElementById브라우저 에서 메소드를 대신하여 이것을 사용할 수 있습니까?



답변

발생하는 것은 ‘명명 된 요소’가 document객체의 명백한 속성으로 추가된다는 것입니다 . 요소 이름이의 실제 속성과 충돌 할 수 있기 때문에 이것은 정말 나쁜 생각입니다 document.

IE는 명명 된 요소를 window개체의 속성으로 추가하여 상황을 악화 시켰습니다 . 이것은 객체 document또는 window객체 (또는 프로젝트의 다른 라이브러리 코드)의 멤버가 사용하려고 할 때 요소의 이름을 지정하지 않아야한다는 점에서 두 배로 나쁩니다 .

또한 이러한 요소가 전역 유사 변수로 표시됨을 의미합니다. 운 좋게도이 경우 코드에서 실제 전역 var또는 function선언은 그림자로 표시되므로 이름 지정에 대해 너무 걱정할 필요가 없지만 충돌하는 이름으로 전역 변수에 할당을 시도하고 선언하는 것을 잊어 버린 경우 그것은 var요소 자체에 값을 할당하려고 할 때 IE에서 오류가 발생합니다.

일반적으로 생략 하거나 var명명 된 요소에 표시 window되거나 전역 으로 표시되는 것은 나쁜 습관으로 간주됩니다 . 에 스틱 document.getElementById더 광범위하게 지원하고 덜 모호한된다. 타이핑이 마음에 들지 않으면 더 짧은 이름으로 간단한 래퍼 함수를 ​​작성할 수 있습니다. 어쨌든 브라우저는 일반적으로 getElementById빠른 조회를 사용 하도록 호출을 최적화하기 때문에 id-to-element 조회 캐시 를 사용할 필요가 없습니다. 요소가 변경 id되거나 문서에서 추가 / 제거 될 때 문제가 발생 합니다.

오페라는 IE가, 다음에 합류 웹킷, 그리고 명명 된 요소를 넣어 지금 모두 이전에 unstandardised 연습 복사 document속성 및에 이르렀의 이전 IE 전용 연습 window하는 중인 표준화 누구의 접근 문서이며 모든 표준화 HTML5에 의해 브라우저 작성자가 우리에게 끔찍한 관행을 가해 웹의 일부로 영원히 만들었습니다. 따라서 Firefox 4도이를 지원합니다.

‘명명 된 요소’란 무엇입니까? 와 함께 id, 그리고 name‘식별’목적으로 사용되는 모든 것 , 즉 폼, 이미지, 앵커 및 기타 몇 가지이지만 name폼 입력 필드의 컨트롤 이름, <param>또는 메타 데이터 유형입니다 <meta>. ‘식별하기’ name는 찬성하여 피해야 할 것들입니다 id.


답변

이전 답변에서 언급했듯이이 동작은 창 개체에 대한 명명 된 액세스라고합니다 . 의 값 name일부 요소에 대한 속성과 값 id의 모든 요소에 대한 속성은 세계의 속성으로 사용할 수 있습니다 window객체입니다. 이를 명명 된 요소라고합니다. 이후window브라우저의 전역 객체 각 명명 된 요소는 전역 변수로 액세스 할 수 있습니다.

이것은 원래 Internet Explorer에 의해 추가되었으며 결국이 동작에 종속 된 사이트와의 호환성을 위해 다른 모든 브라우저에서 구현되었습니다. 흥미롭게도 파이어 폭스의 렌더링 엔진 인 Gecko는 이것을 쿼크 모드 에서만 구현하기로 선택 했지만 다른 렌더링 엔진은 표준 모드로 유지했습니다.

그러나 Firefox 14부터 Firefox는 이제window 표준 모드에서도 객체 에 대한 명명 된 액세스지원합니다 . 그들은 왜 이것을 바 꾸었습니까? 표준 모드에서이 기능에 의존하는 사이트가 여전히 많이 있습니다. Microsoft 는 데모를 Firefox에서 사용할 수 없도록 하는 마케팅 데모출시했습니다 .

웹킷은 최근 반대 방향을 고려 하여 window객체의 명명 된 액세스 를 쿼크 모드로만 강등했습니다 . 그들은 Gecko와 같은 추론으로 그것에 반대했습니다.

이 동작은 이제 표준 모드에서 모든 주요 브라우저의 최신 버전에서 사용하는 것이 기술적으로 안전 해 보입니다 . 그러나 명명 된 액세스는 다소 편리해 보일 수 있지만 사용해서는 안됩니다 .

왜? 이 글에서 전역 변수가나쁜지에 대한 많은 추론을 요약 할 수 있습니다 . 간단히 말해서, 추가 전역 변수가 많으면 더 많은 버그가 발생합니다. 실수로 a의 이름을 입력하고 a를 입력한다고 가정 해 봅시다 var.id 하고 DOM 노드 인 SURPRISE .

또한 표준화되었지만 브라우저의 명명 된 액세스 구현에는 여전히 약간의 불일치가 있습니다.

  • IE는 name양식 요소 (입력, 선택 등)에 액세스 할 수 있는 속성 값을 잘못 만듭니다 .
  • Gecko와 Webkit <a>name속성을 통해 태그에 액세스 할 수 없도록 잘못 설정 했습니다 .
  • Gecko는 동일한 이름을 가진 여러 명명 된 요소를 잘못 처리합니다 (참조 배열 대신 단일 노드에 대한 참조를 반환 함).

그리고 가장자리에 명명 된 액세스를 사용하려고하면 더 많은 것이 있다고 확신합니다.

다른 답변에서 언급했듯이에 document.getElementById의해 DOM 노드에 대한 참조를 얻는 데 사용 됩니다 id. name속성 으로 노드에 대한 참조를 가져와야하는 경우 use를 사용하십시오 document.querySelectorAll.

사이트에서 명명 된 액세스를 사용하여이 문제를 전파하지 마십시오. 많은 웹 개발자들이이 마술 을 추적하는 데 시간을 낭비했습니다 행동 . 표준 모드에서 명명 된 액세스를 끄려면 조치를 취하고 렌더링 엔진을 가져와야합니다. 단기적으로는 일부 사이트가 나쁜 일을하게되지만 장기적으로 웹을 발전시키는 데 도움이 될 것입니다.

관심이 있으시면 내 블로그 ( https://www.tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/) 에서 이에 대해 자세히 설명합니다 .


답변

getElementById()예를 들어 다음과 같은 경우에 충실해야합니다 .

document.getElementById('example').innerHTML

IE는을 가진 요소 혼합을 좋아 name 하고 ID 그래서 가장 잘 얻으려고 노력하는지에 대해 명시 적으로, 글로벌 네임 스페이스 특성을.


답변

예, 그렇습니다.

다음 예를 사용하여 Chrome 55, Firefox 50, IE 11, IE Edge 14 및 Safari 10에서 테스트되었습니다 .

<!DOCTYPE html>
<html>
<head>
</head>
<body>
  <div id="im_not_particularly_happy_with_that">
    Hello World!
  </div>
  <script>
    im_not_particularly_happy_with_that.innerText = 'Hello Internet!';
  </script>
  <!-- Looking at you W3 HTML5 spec group _ -->
</body>
</html>

http://jsbin.com/mahobinopa/edit?html,output


답변

질문은 다음과 같이 들릴 것입니다 : “제공된 ID를 가진 HTML 태그가 전 세계적으로 접근 가능한 DOM 요소가됩니까?”

대답은 ‘예’입니다.

그것이 작동하는 방식이고, 이것이 W3C에 의해 ID가 도입 된 이유입니다.
파싱 ​​된 스크립팅 환경에서 HTML 태그의 ID는 해당 DOM 요소 핸들이됩니다.

그러나 Netscape Mozilla는 W3C를 준수하지 않기를 거부했으며 더 이상 사용되지 않는 Name 속성을 사용하여 혼란을 일으켰으므로 W3C의 고유 ID 도입으로 인한 스크립팅 기능과 코딩 편의성을 깨뜨 렸습니다.

Netscape Navigator 4.7이 실패한 이후 개발자들은 모두 W3C에 침투 한 반면, 직원들은 잘못된 관행과 오용 사례로 웹을 대체했습니다. ID 속성과 동등하게 이미 더 이상 사용되지 않는 Name 속성 [! 독특하지 않아야 함]을 사용하고 재사용하여 특정 DOM 요소에 액세스하기 위해 ID 핸들을 사용한 스크립트가 간단하게 중단되었습니다!

그리고 적어도 코딩을 비효율적으로 만들고 브라우저를 단순히 깨지 않았을 때 더 많은 오버 헤드를 제공하는 document.all.ElementID.property대신 광범위한 코딩 레슨과 예제 [그들의 ​​브라우저는 어쨌든 인식하지 못합니다]를 작성하고 게시 할 ElementID.property때처럼 중단했습니다. (현재 [1996-97], 더 이상 사용되지 않음) 이름과 동일한 토큰 값을 제공하는 표준 ID 속성에 동일한 토큰을 사용하여 HTML 도메인.

그들은 무지한 코드 작성 아마추어의 압도적 인 군대가 이름 속성과 ID 속성이 더 짧고 따라서 바이트 이름을 절약하고 고대 이름 속성보다 코더에 더 편리하다는 점을 제외하고는 이름과 ID가 거의 동일하다는 것을 쉽게 설득 할 수있었습니다. 물론 거짓말이었다. 또는-HTML로 대체 된 게시 된 기사에서 스크립팅 엔진이 액세스 할 수 있도록 태그에 이름과 ID를 모두 제공해야하는 기사를 설득합니다.

“코드 명”Mozilla “라는 모자이크 살인자들은 너무 화가 나서”우리가 넘어지면 인터넷도 마찬가지 “라고 생각했습니다.

반면에 상승하는 Microsoft는 너무 순진하여 더 이상 사용되지 않고 삭제 Name 속성을 표시해야하며 고유 한 식별자 인 ID 인 것처럼 처리하여 스크립트 기능을 중단하지 않아야한다고 생각했습니다. Netscape 교육생이 코딩 한 이전 페이지 그들은 치명적이었다 …

ID 충돌 요소의 배열 컬렉션을 반환하는 것은이 의도적 인 인공 문제의 해결책이 아닙니다. 실제로 그것은 모든 목적을 이겼습니다.

그리고 이것이 W3C가 추악하게 변한 유일한 이유 document.getElementById입니다.


답변