¿Cómo simular un clic con JavaScript?

291

Me pregunto cómo puedo usar JavaScript para simular un clic en un elemento.

Actualmente tengo:

<script type="text/javascript">
function simulateClick(control)
{
    if (document.all)
    {
        control.click();
    }
    else
    {
        var evObj = document.createEvent('MouseEvents');
        evObj.initMouseEvent('click', true, true, window, 1, 12, 345, 7, 220, false, false, true, false, 0, null );
        control.dispatchEvent(evObj);
    }
}
</script>

<a href="http://www.google.com" id="mytest1">test 1</a><br>

<script type="text/javascript">
    simulateClick(document.getElementById('mytest1'));
</script>

Pero no funciona :(

¿Algunas ideas?

Pez Belgin
fuente
99
"Los cinco errores de codificación más comunes": javascript.about.com/od/hintsandtips/a/worst_4.htm : ya casi nadie ejecuta IE4, por lo que ya no es necesario el soporte para el documento. Todos los DOM. Sin embargo, es realmente sorprendente cuántas personas todavía lo usan en su codificación. Peor aún es que el soporte para el documento. A menudo se prueba todo DOM para determinar el navegador que se está utilizando y, si es compatible, el código supone que el navegador es Internet Explorer (que es un uso completamente incorrecto ya que Opera también reconoce ese DOM) .
zaf
1
Ver stackoverflow.com/questions/1421584/…
Crescent Fresh el

Respuestas:

418

Esto es lo que cociné. Es bastante simple, pero funciona:

function eventFire(el, etype){
  if (el.fireEvent) {
    el.fireEvent('on' + etype);
  } else {
    var evObj = document.createEvent('Events');
    evObj.initEvent(etype, true, false);
    el.dispatchEvent(evObj);
  }
}

Uso:

eventFire(document.getElementById('mytest1'), 'click');
KooiInc
fuente
12
@ Anderson Green: He agregado un ejemplo a este jsfiddle: jsfiddle.net/KooiInc/W4BHD
KooiInc
44
Prueba de que esto funciona (en cromo): +1 con document.querySelector('[value="2706236"]').nextSibling.nextSibling.dispatchEvent(ev);:)
PointedEars
58
Bueno, probé tu script java en el botón de voto :) (funcionó, por supuesto)
0fnt
1
Para simular el comportamiento exacto del usuario, debe ajustar las invocaciones dispatchEvento , ya que parece que es sincrónico . clicksetTimeoutdispatchEvent
Lev Kazakov
16
Event.initEventahora está en desuso developer.mozilla.org/en/docs/Web/API/Event/initEvent
artnikpro
392

¿Qué pasa con algo simple como:

document.getElementById('elementID').click();

Compatible incluso con IE.

Darren Sweeney
fuente
@HermannIngjaldsson Sí, funciona perfectamente en IE - msdn.microsoft.com/en-us/library/ie/ms536363%28v=vs.85%29.aspx
Darren Sweeney
66
La pregunta era "¿funciona, es decir, también?" - la respuesta es sí - AFAIK al menos hasta 8, no he marcado 7
Darren Sweeney
24
¿Esto no existía antes? ¿Por qué las respuestas de 2010 no mencionan esta solución simple? Simplemente curioso ...
Parth
3
@ NinoŠkopac Funciona muy bien actualmente para computadoras de escritorio, pero no hay garantía para trabajar con navegadores móviles. Incluso el sitio para desarrolladores de mozilla no muestra soporte móvil.
le0diaz
8
@Parth Quizás lo hizo, simplemente no hizo clic para ellos.
Andrew
78

¿Has considerado usar jQuery para evitar toda la detección del navegador? Con jQuery, sería tan simple como:

$("#mytest1").click();
BradBrening
fuente
21
Esto solo activa los controladores de eventos jQuery, no el comportamiento predeterminado (el navegador va a href en ese caso)
Romuald Brunet
12
No sé acerca de triste pero seguro que puede ser conveniente no tener que seguir recodificando las mismas rutinas de detección del navegador una y otra vez.
BradBrening
99
@ErikAigner: Me preguntaba lo mismo, pero me alegra que la respuesta aceptada en este caso sea JavaScript simple y no jQuery. Visto eso demasiadas veces en SO. Una vez más: jQuery es JavaScript, pero JavaScript no es jQuery. Aunque me gusta usar jQuery, veo cada vez más que los desarrolladores no entienden la verdadera realidad. Mis 2 centavos, no pude resistirme a comentar. ;)
Sander
58
También hay muchos humanos que no sabrían por dónde comenzar si tuvieran que lavar su ropa a mano, ya que la mayoría de los hogares posee una lavadora, y casi la mayoría tiene una secadora. jQuery, al igual que los electrodomésticos modernos, ha hecho una tarea vieja mucho más fácil y menos propensa a errores. Sin embargo, no es la solución para todos, rechazar una respuesta que responda con precisión a la pregunta usando una sintaxis más concisa y comprensible, mientras que ser compatible con varios navegadores parece ser al revés. +1.
FreeAsInBeer
2
@FreeAsInBeer Entonces tampoco deberías caminar a ningún lado ya que conducir es mucho más fácil. Pero sabemos que es una tontería. Caminas si no necesitas ir lejos. Utiliza JavaScript simple si necesita hacer algo simple y no desea cargar una biblioteca completa para hacerlo. No hay necesidad de gastar gas / ancho de banda por algo simple.
Jacob Alvarez
18
var elem = document.getElementById('mytest1');

// Simulate clicking on the specified element.
triggerEvent( elem, 'click' );

/**
 * Trigger the specified event on the specified element.
 * @param  {Object} elem  the target element.
 * @param  {String} event the type of the event (e.g. 'click').
 */
function triggerEvent( elem, event ) {
  var clickEvent = new Event( event ); // Create the event.
  elem.dispatchEvent( clickEvent );    // Dispatch the event.
}

Referencia

mnishiguchi
fuente
Creo que esta debería ser la mejor respuesta hoy en día
DavidTaubmann
15

Podrías ahorrarte un montón de espacio usando jQuery. Solo necesitas usar:

$('#myElement').trigger("click")
Adam Salma
fuente
10
OP solicitó JavaScript. Aunque esto es compacto y funcional, algunas personas prefieren JS sin biblioteca sobre cosas como jQuery.
Canal
43
¿Ahorrar espacio descargando jquery?
MH
99
Algunas personas prefieren el montaje, también.
Dan Nissenbaum
@MH Creo que un argumento más válido sería "para que sea simple". Su perfil predeterminado aquí en SO es aproximadamente del mismo tamaño que jQuery.
adelriosantiago
7

¡La mejor respuesta es la mejor! Sin embargo, no estaba activando eventos de mouse para mí en Firefox cuando etype = 'click'.

Por lo tanto, he cambiado el document.createEventque 'MouseEvents'y que solucionó el problema. El código adicional es para probar si otro bit de código estaba interfiriendo o no con el evento, y si se cancelaba, lo registraría en la consola.

function eventFire(el, etype){
  if (el.fireEvent) {
    el.fireEvent('on' + etype);
  } else {
    var evObj = document.createEvent('MouseEvents');
    evObj.initEvent(etype, true, false);
    var canceled = !el.dispatchEvent(evObj);
    if (canceled) {
      // A handler called preventDefault.
      console.log("automatic click canceled");
    } else {
      // None of the handlers called preventDefault.
    } 
  }
}
brianlmerritt
fuente