1

Por qué al obtener el elemento con id "get" no lanza ningún error, pero si obtengo otro, sí lanza error ? soy consciente de que no estoy llamandolo desde el objeto, pero entonces.. no debería también get lanzar error, además entiendo que get es una palabra reservada, pero por qué sucede esto, entonces le estoy cambiando el real valor de get, si es así me gustaría una aclaración documentada?

(function () {
var us = {get: document.getElementById("get"),
          h6: document.getElementById("h6text")};
get.addEventListener("click", function() { console.log("No error") });
h6.addEventListener("click", function(){ // error ?

});
})();
<input value="Obtener" type="button" id="get">
<h6 id="h6text">Bienvenidos</h6>
Eduardo Sebastian
  • 4,908
  • 7
  • 30
  • 70
  • No entiendo la pregunta, el codigo hace lo que debería. Esa forma de ejecutar es para crear un entorno que no interfiera con funciones o variables globales externas. Ademas, h6 no existe. Lo que tienes es h6text que al tener id, deberia ser accesible como variable porque lo dice el estandard. – derloopkat Nov 27 '17 at 10:28
  • no se si me explico, tu agregas un tag en html, le pones id, y automáticamente lo puedes acceder como variable sin tener que usar getElementById() y eso es porque los tipos que crearon el estandard para Javascript lo pusieron en la especificación – derloopkat Nov 27 '17 at 10:37
  • Oh verdad, alguna vez lo escuche, gracias ! – Eduardo Sebastian Nov 27 '17 at 10:38

2 Answers2

1

La documentación

Si revisas la documentación de addEventListener verás que dice lo siguiente:

addEventListener() Registra un evento a un objeto en específico. El Objeto específico puede ser un simple elemento en un archivo, el mismo documento , una ventana o un XMLHttpRequest.

Verás también que la sintaxis es así:

target.addEventListener(tipo, listener[, useCapture]);

Aquí, target puede ser sustituido sin ningún problema por cualquier id de un elemento válido en el DOM.


Lo que ocurre en tu código

De lo leído en la doc, podemos concluir que al agregar un listener de esta forma: elId.addEventListener, JS buscará en el DOM el elemento cuyo id sea igual a elId. Si lo encuentra bien, y si no lo encuentra dará error.

Por eso en tu código:

  • Esto funciona: get.addEventListener porque en el DOM hay un elemento con un id igual a get
  • Esto no funciona: h6.addEventListener porque no hay en el DOM ningún elemento con un id igual a h6.
  • He agregado al DOM un elemento con id="h6". Verás que tu anterior código erróneo, ya no lo es, porque se agrega un listener a ese elemento.

He hecho cosas a propósito en el código para que te des cuenta de lo que ocurre en realidad.

(function(e) {
  var us = {
    get: document.getElementById("gets"),
    h6: document.getElementById("h6text")
  };
  gets.addEventListener("click", function() {
    console.log("No error... Valor del elemento: " + us.get.value)
  });
  h6text.addEventListener("click", function() { // error ?
    console.log("No error... Id del elemento: " + us.h6.id)
  });
 h6.addEventListener("click", function() { // error ?
    console.log("ESTE ES EL LISTENER H6, SU ID ES: " + this.id)
  });
})();
<input value="Obtener" type="button" id="gets">
<h6 id="h6text"><a href="#">Bienvenidos</a></h6>
<h6 id="h6"><a href="#">Esto sí que es H6</a></h6>

¿Palabras reservadas?

En cuanto a la duda sobre palabras reservadas, tuve la misma duda, plantee la pregunta hace un tiempo: ¿Palabras reservadas en HTML? y la respuesta aceptada es muy clara.

A. Cedano
  • 86,578
  • 19
  • 122
  • 221
1

Los navegadores, por temas de compatibilidad con HTML antiguo (creado cuando el navegador mayoritario era Internet Explorer), a menudo han incorporado funcionalidades no estándar o incluso a menudo no recomendadas. Una de estas funcionalidades no recomendadas es poder acceder a cualquier elemento de la página usando su ID como si fuese un atributo de la clase Window. Del repositorio de la W3C en GitHub, si leemos la especificación de HTML5, podemos encontrar esto:

6.3.3. Named access on the Window object

This definition is non-normative. Implementation requirements are given below this definition.

window[name]

Returns the indicated element or collection of elements. As a general rule, relying on this will lead to brittle code. Which IDs end up mapping to this API can vary over time, as new features are added to the Web platform, for example. Instead of this, use document.getElementById() or document.querySelector().

Que viene a significar, en pocas palabras, lo siguiente: funciona, pero no es buena idea usarlo. Es mejor acceder al DOM mediante los métodos document.getElementById() o document.querySelector()

Ejemplo del funcionamiento (lo pongo como muestra, pero recomiendo no usarlo):

console.log(window.get.tagName);
console.log(window.h6text.innerHTML);
window.h6text.addEventListener('click',()=>alert('Has hecho click'));
<input value="Obtener" type="button" id="get">
<h6 id="h6text">Click Me</h6>
Pablo Lozano
  • 45,934
  • 7
  • 48
  • 87
  • Perdona pero esto no es del todo cierto... lo que tú refieres habla de los listeners del `window`... mientras que en el caso expuesto en la pregunta hablamos de elementos que se encuentran en el DOM, no en window... No es lo mismo. La [documentación de MDN](https://developer.mozilla.org/es/docs/Web/API/EventTarget/addEventListener) no afirma nada de lo que concluyes, y de hecho, muestra ejemplos casi similares, almacenando el elemento en una variable y luego añadiéndole el listener. Al menos eso es lo que yo entiendo. – A. Cedano Nov 27 '17 at 14:16
  • Lo que quiero exponer es que, aunque no sea algo aconsejable, `window.` es lo mismo que `document.getElementById('');` – Pablo Lozano Nov 27 '17 at 14:28
  • Esta afirmación: *poder acceder a cualquier elemento de la página usando su ID como si fuese un atributo de la clase Window* no la veo en el enlace. Luego, en tu código de ejemplo `window.h6text.addEventListener('click',()=>alert('Has hecho click'));` confundes `window` y `document`. **La práctica no recomendada es precisamente lo que haces en tu ejemplo**, usar el `window` (que es un elemento superior), para alcanzar un elemento que están en el `document` (inferior). Tu código es contradictorio con los ejemplos de MDN al respecto y tu respuesta es confusa y quizá, no cierta del todo. – A. Cedano Nov 27 '17 at 14:37
  • Mira el enlace que he puesto yo, de la W3C. La documentación de MDN no es fuente primaria, ellos sólo reflejan el estándar y no siempre está actualizada. Me parece normal que no pongan información sobre esta opción porque se recomienda no usarla, pero no significa nada en cuanto a que la fundación Mozilla no define lo que es o no es válido. Y sí, lo que hago en mi ejemplo es lo **no recomendado** – Pablo Lozano Nov 27 '17 at 14:42
  • Precisamente, en el enlace que has puesto no leo lo que afirmas en la respuesta: ***poder acceder a cualquier elemento de la página usando su ID como si fuese un atributo de la clase Window***. En [w3.org](https://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-EventListener) tampoco lo dice cuando habla de los listeners. Creo que cuando se hace esto: `unId.addEventListener(tipo, listener[, useCapture]);` no se invoca para nada a `window` sino que se busca ese elemento en el DOM (`document`). – A. Cedano Nov 27 '17 at 15:04
  • Como ya expliqué [aquí](https://es.stackoverflow.com/questions/116065/por-qu%C3%A9-sucede-esto/116073#116073), [aquí](https://es.stackoverflow.com/questions/106042/var-let-const-o-nada-en-javascript/106067#106067) y [aquí](https://es.stackoverflow.com/questions/100060/encontrar-variables-en-un-documento/100280#100280), no hace falta poner explícitamente `window.propiedad`, puesto que el intérprete ya asume que cualquier variable no declarada es un atributo de `window`. Por tanto `window.` es lo mismo que ``. – Pablo Lozano Nov 27 '17 at 15:31
  • Eso es contradictorio con tu propio enlace: *the value of the id content attribute of any HTML element in the **active document** with a non-empty id content attribute.* Habla del documento activo, no de la ventana activa. Y en el enlace a Active Document dice esto: *Each Document in a browsing context is associated with a Window object.* No leo en ninguna parte de la doc lo que tú afirmas. – A. Cedano Nov 27 '17 at 21:32