w3school - Registro de eventos JavaScript sin usar jQuery
type javascript tag (6)
¿Qué tal algo como esto?
document.getElementById(''someButton'').onclick = function () { alert(''Hello'');}
Cómo hacer correctamente algo como lo siguiente sin usar jQuery.
$(document).ready(function(){
$("#someButton").click(function(){
alert("Hello");
});
});
Gracias.
Esta respuesta no es tan simple sin jQuery, porque hay dos estilos principales (dependiendo del navegador que esté usando) para conectar eventos. Si no usa uno de esos dos estilos, sus eventos pueden sobrescribirse entre sí. Aquí está el estilo más simple / sobrescrito:
window.onload = function() {
document.getElementById("someButton").onclick = function() {
alert("Hello");
}
}
Pero si lo intenta y lo anterior dos veces, solo recibirá una alerta, ya que la segunda vez sobrescribirá la primera. Alternativamente, puede hacer un poco de detección de navegador / función y luego usar los mecanismos de eventos específicos para navegadores específicos; Para más información sobre ese estilo, echa un vistazo a QuirksMode.com:
La forma más fácil es:
// DOM Level 0 way
window.onload = function () {
document.getElementById("someButton").onclick = function() {
alert("Hello");
};
};
Esto funcionará en todos los navegadores, pero tenga en cuenta que con este enfoque solo se puede adjuntar un controlador de eventos a un evento.
También tenga en cuenta que el evento onload
no es completamente equivalente al evento ready
de jQuery, onload
activará cuando todos los recursos de la página estén completamente cargados (imágenes, sub-marcos, etc.), mientras que ready
dispara tan pronto como el DOM ha sido analizado
Si desea adjuntar múltiples controladores de eventos, puede usar el método DOM Level 2 Standard element.addEventListerner
(o element.attachEvent
para IE)
La abstracción más simple para obtener una forma de enlace entre navegadores para vincular eventos es:
function addEvent(el, eventType, handler) {
if (el.addEventListener) { // DOM Level 2 browsers
el.addEventListener(eventType, handler, false);
} else if (el.attachEvent) { // IE <= 8
el.attachEvent(''on'' + eventType, handler);
} else { // ancient browsers
el[''on'' + eventType] = handler;
}
}
Entonces tú puedes:
var button = document.getElementById("someButton");
addEvent(button, ''click'', function () {
alert("Hello");
});
addEvent(button, ''click'', function () {
alert("world!");
});
Tenga en cuenta también que addEventListener
y los métodos attachEvent
de IE tienen sus diferencias, cuando adjunta varios controladores a un evento con addEventListener
se activarán en el mismo orden, ya que los controladores estaban vinculados (FIFO), attachEvent
activará los controladores en el orden contrario (LIFO).
Revisa un ejemplo here .
Por lo que sé, onLoad NO es lo mismo que On DOM Ready.
On Load espera a que se carguen todos los recursos (imágenes, otros archivos externos). mientras que On DOM Ready solo espera que se genere el HTML y no espera que se carguen los activos.
Corrígeme si estoy equivocado.
prueba esto:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test clicks</title>
<script type="text/javascript">
function setClicks() {
var element = document.getElementById(''test'');
element.onclick = function() {
alert(''test'');
}
}
</script>
</head>
<body onload="setClicks();">
<div id="test" name="test">
test
</div>
</body>
</html>
TL; DR
En un navegador moderno:
<input type="button" id="someButton" value="Some Button">
<script>
document.getElementById("someButton").addEventListener("click", function() {
alert("Hello");
}, false);
</script>
Tenga en cuenta que el script está después del botón en el HTML. ¿Por qué importa? Sigue leyendo.
document.getElementById("someButton").addEventListener("click", function() {
snippet.log("Hello");
}, false);
<input type="button" id="someButton" value="Some Button">
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Oh bien, seguiste leyendo.
Hay tres partes en esto:
Cuándo conectar el controlador (la parte para la que está usando el código jQuery)
Cómo encontrar el (los) elemento (s) para conectar (la parte del código jQuery está usando
$("#someButton")
para)Cómo conectar el controlador (la parte que está utilizando
click
para)
Cuando conectar el controlador
Cuando se manejan eventos directamente en un elemento, no se puede conectar el controlador de eventos hasta que el elemento exista. Al tratar con elementos que están en el HTML principal de la página, sabes que existen una vez que su HTML ha sido analizado. Entonces, por ejemplo:
<div>...</div>
<script>
// Here, we know that that div exists
</script>
Entonces, a menos que tenga una buena razón para hacer lo contrario, coloque las etiquetas de secuencia de comandos para su código JavaScript al final del documento, justo antes de la etiqueta de cierre </body>
. Entonces sabes que todos los elementos anteriores (incluido document.body
) existen.
Si no tiene más remedio que poner sus etiquetas de script en otro lugar (como el anti-patrón que las está poniendo en <head>
), entonces tiene que recurrir a conectar un controlador de eventos para cuando se analice el contenido de la página. El estándar es DOMContentLoaded
, que engancha en el document
. Desafortunadamente, IE8 y versiones anteriores no lo admiten, lo cual es parte de por qué jQuery proporciona la devolución de llamada ready
. También puede usar el evento load
en el objeto de la window
, pero eso no se dispara hasta mucho después de que se hayan analizado los elementos de la página, porque espera a que se carguen todos los recursos externos (todas las imágenes, etc.) antes de disparar.
Cómo encontrar el (los) elemento (s) para conectar
En su ejemplo, el elemento tiene un valor de id
, por lo que puede usar document.getElementById
para obtenerlo; que devuelve una referencia al objeto objeto, o null
si no hay ninguno con ese id
.
Los navegadores modernos, y también IE8, admiten document.querySelector
, que encontrará el primer elemento que coincida con cualquier selector de CSS. Entonces, por ejemplo, document.querySelector(''div'')
encuentra el primer div
en el documento, si existe ( null
si no hay). document.querySelector(''div.foo table tr.bar'')
encuentra el primer elemento tr
con la bar
clase que está dentro de una table
que está dentro de un elemento div
con clase foo
.
Los navegadores modernos (y IE8) también proporcionan document.querySelectorAll
, que le proporciona una lista (colección) de todos los elementos que coinciden con un selector de CSS.
querySelector
y querySelectorAll
también están disponibles en elementos; cuando los usas en elementos, solo miran a los descendientes de ese elemento.
También hay varias otras funciones, como getElementsByTagName
(casi universalmente compatible, incluso en el antiguo IE), getElementsByName
(usando el atributo de name
; no tengo idea de cuán ampliamente admitido es), getElementsByClassName
(busque por una sola clase de CSS; IE8 y antes no lo tienen), y algunos otros.
Cómo conectar el controlador
Los navegadores modernos, incluidos IE9 y superiores en modo estándar, admiten addEventListener
. Con IE8 y versiones anteriores, debe usar el attachEvent
original de attachEvent
(que precede a addEventListener
).
theElement.addEventListener("click", function() {
// ...your handler code here
}, false);
// or
theElement.attachEvent("onclick", function() {
// ...your handler code here
});
Tenga en cuenta que addEventListener
solo usa el nombre del evento ( "click"
), pero attachEvent
usa "on"
más el nombre del evento ( "onclick")
. También tenga en cuenta que addEventListener
tiene un tercer argumento que casi siempre quiere establecer en false
. (Los navegadores recientes han hecho que el argumento sea opcional, pero no siempre fue así, por lo que si necesita admitir los más antiguos, inclúyalo).
La principal ventaja de usar addEventListener
o attachEvent
es que al hacerlo se juega bien con otros, porque un elemento puede tener más de un controlador de eventos registrado para el mismo evento cuando se usan estos métodos.
Los elementos también exponen propiedades a las que puede asignar funciones, donde está el nombre de la propiedad seguido del nombre del evento, por ejemplo, en el onclick
:
theElement.onclick = function() {
// Your handler code
};
Esto se admite universalmente en todos los navegadores, pero tiene el problema de que un elemento solo puede tener un controlador conectado de esta manera.
Entonces, podemos implementar su código jQuery de esta manera:
<script>
document.getElementById("someButton").onclick = function() {
alert("Hello");
};
</script>
</body>
</html>
(Observe dónde está esa etiqueta). Pero eso no funciona bien con los demás.
document.getElementById("someButton").onclick = function() {
snippet.log("Hello");
};
<input type="button" id="someButton" value="Some Button">
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
O en un navegador moderno:
<script>
document.getElementById("someButton").addEventListener("click", function() {
alert("Hello");
}, false);
</script>
</body>
</html>
document.getElementById("someButton").addEventListener("click", function() {
snippet.log("Hello");
}, false);
<input type="button" id="someButton" value="Some Button">
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
O en IE8 y anteriores:
<script>
document.getElementById("someButton").attachEvent("onclick", function() {
alert("Hello");
});
</script>
</body>
</html>
document.getElementById("someButton").attachEvent("onclick", function() {
snippet.log("Hello");
});
<input type="button" id="someButton" value="Some Button">
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
Ahora, supongamos que utilizamos querySelectorAll
o similar y obtengamos una lista de elementos, en lugar de un solo elemento. ¿Cómo conectamos un controlador en cada uno de ellos?
Podemos usar las técnicas en esta otra respuesta para recorrer la colección, ya que será un objeto similar a una matriz (pero no una matriz real). Digamos que queremos buscar un manejador en todos los elementos div
con la clase foo
:
var list = document.querySelectorAll("div.foo");
Array.prototype.forEach.call(list, function(element) {
element.addEventListener("click", handler, false);
});
function handler() {
this.innerHTML = "You clicked me";
}
(No se preocupe por eso, lo cubro en "Más para explorar" a continuación).
var list = document.querySelectorAll("div.foo");
Array.prototype.forEach.call(list, function(element) {
element.addEventListener("click", handler, false);
});
function handler() {
this.innerHTML = "You clicked me";
}
<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="foo">foo</div>
<div class="bar">bar (no handler)</div>
<div class="bar">bar (no handler)</div>
<div class="bar">bar (no handler)</div>
<div class="bar">bar (no handler)</div>
Más para explorar
El manejo del evento no se trata solo de obtener el evento. Hay otras cuatro cosas que los manejadores de eventos a veces quieren hacer:
Obtenga información sobre el evento (por ejemplo, si se presionó una tecla, ¿qué tecla?)
Impedir la acción predeterminada del evento, si tiene una (por ejemplo, evitar que el valor predeterminado en un evento de
submit
en un formulario impida que sesubmit
)Detener la propagación (burbujeo) del evento a los elementos contenedores.
Haga referencia al elemento en el que se conectó el evento (para que podamos usar el mismo controlador en varios elementos)
# 4 es fácil: en un controlador adjunto con cualquiera de los mecanismos que discutimos anteriormente, dentro del controlador, this
se referirá al elemento en el que se conectó el evento. (Esto no ocurre con las conexiones de atributos HTML, por ejemplo, <div onclick="handler()">
, que es una de las muchas razones para no usarlos.) Si has hecho algo más con this
(lo que puedes), también puede acceder al elemento en el que conectó el evento a través de la propiedad currentTarget
del objeto de evento (más abajo).
Desafortunadamente, la forma en que lo hace es diferente en IE8 y attachEvent
anteriores con attachEvent
y en los navegadores compatibles con los estándares ( addEventListener
). Aquí hay una función, hookEvent
, (que escribí originalmente para esta otra respuesta ) que te permite usar la forma basada en estándares incluso en IE antiguo:
var hookEvent = (function() {
var div;
// The function we use on standard-compliant browsers
function standardHookEvent(element, eventName, handler) {
element.addEventListener(eventName, handler, false);
return element;
}
// The function we use on browsers with the previous Microsoft-specific mechanism
function oldIEHookEvent(element, eventName, handler) {
element.attachEvent("on" + eventName, function(e) {
e = e || window.event;
e.preventDefault = oldIEPreventDefault;
e.stopPropagation = oldIEStopPropagation;
handler.call(element, e);
});
return element;
}
// Polyfill for preventDefault on old IE
function oldIEPreventDefault() {
this.returnValue = false;
}
// Polyfill for stopPropagation on old IE
function oldIEStopPropagation() {
this.cancelBubble = true;
}
// Return the appropriate function; we don''t rely on document.body
// here just in case someone wants to use this within the head
div = document.createElement(''div'');
if (div.addEventListener) {
div = undefined;
return standardHookEvent;
}
if (div.attachEvent) {
div = undefined;
return oldIEHookEvent;
}
throw "Neither modern event mechanism (addEventListener nor attachEvent) is supported by this browser.";
})();
Usando hookEvent
, podemos hacer las tres cosas enumeradas anteriormente en la forma basada en estándares:
Recibimos el objeto de evento como el primer argumento de la función de controlador, lo que significa que podemos usar su
currentTarget
para obtener una referencia al elemento en el que conectamos el evento, utarget
para obtener una referencia al elemento donde se originó el evento, y así enPodemos evitar el valor predeterminado llamando a la función
preventDefault
del objeto de eventoPodemos detener la propagación llamando a la función
stopPropagation
del objeto destopPropagation
Podemos usar
this
(oevent.currentTarget
) para hacer referencia al elemento dondeevent.currentTarget
el evento
hookEvent
no es una función de conexión de eventos completa, de canto y baile. (Por un lado, nunca me molesté en apoyar eventos de enganche con él). Es código de ejemplo, principalmente.
Material de referencia
La mayor parte de esto está ahora cubierto por la especificación HTML5, que es mucho más que HTML
Varios aspectos están definidos por el DOM; Lista de especificaciones aquí , la actual es DOM4
Mozilla Developer Network tiene una amplia gama de material de referencia razonablemente preciso (a diferencia de otros meta sitios, que con frecuencia tienen problemas de precisión).