Como simular um clique com JavaScript?

291

Só estou me perguntando como posso usar o JavaScript para simular um clique em um elemento.

Atualmente tenho:

<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>

Mas não está funcionando :(

Alguma ideia?

Belgin Fish
fonte
9
"Cinco erros de codificação mais comuns": javascript.about.com/od/hintsandtips/a/worst_4.htm - quase ninguém executa mais o IE4 e, portanto, o suporte ao document.all DOM não é mais necessário. É realmente surpreendente, porém, quantas pessoas ainda o usam em sua codificação. Pior é que o suporte para o document.all todo o DOM é frequentemente testado para determinar o navegador que está sendo usado e, se for suportado, o código assume que o navegador é o Internet Explorer (que é um uso completamente errado, pois o Opera também reconhece esse DOM) .
Zaf

Respostas:

418

Aqui está o que eu cozinhei. É bem simples, mas 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
fonte
12
@ Anderson Green: Adicionei um exemplo a este jsfiddle: jsfiddle.net/KooiInc/W4BHD
KooiInc
4
A prova de que isso funciona (em cromo): +1 com document.querySelector('[value="2706236"]').nextSibling.nextSibling.dispatchEvent(ev);:)
PointedEars
58
Bem, eu tentei seu java-script no voto até botão :) (trabalhou de curso)
0fnt
1
Para simular o comportamento do usuário exato, você deve envolver o dispatchEventou clickinvocações com setTimeout, como parece que dispatchEventé síncrona .
Lev Kazakov 29/11
16
Event.initEventagora está obsoleta developer.mozilla.org/en/docs/Web/API/Event/initEvent
artnikpro
392

Que tal algo simples como:

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

Suportado até pelo IE.

Darren Sweeney
fonte
@HermannIngjaldsson Sim, ele funciona perfeitamente no IE - msdn.microsoft.com/en-us/library/ie/ms536363%28v=vs.85%29.aspx
Darren Sweeney
6
A questão era "isso também funciona?" - a resposta é sim - AFAIK pelo menos até 8, não conferiu 7
Darren Sweeney
24
Isso não existia antes? Por que as respostas de 2010 não mencionaram essa solução simples? Apenas curioso ...
Parth
3
@ NinoŠkopac Atualmente, funciona muito bem em computadores, mas não há garantia de trabalhar com navegadores móveis. Mesmo o site do desenvolvedor do mozilla não mostra suporte para dispositivos móveis.
Le0diaz
8
@Parth Talvez ele fez, ele simplesmente não clique para eles.
28419 Andrew
78

Você já pensou em usar o jQuery para evitar toda a detecção do navegador? Com o jQuery, seria tão simples quanto:

$("#mytest1").click();
BradBrening
fonte
21
Isso só manipuladores de eventos jQuery fogo, não o comportamento padrão (navegador vai para href nesse caso)
Romuald Brunet
12
Não sei o que é triste, mas com certeza pode ser conveniente não precisar repetir as mesmas rotinas de detecção de navegador repetidas vezes.
BradBrening
9
@ ErikAigner: Eu estava pensando o mesmo, mas feliz que a resposta aceita neste caso seja JavaScript simples e não jQuery. Visto isso muitas vezes no SO. Mais uma vez: jQuery é JavaScript, mas JavaScript não é jQuery. Embora eu goste de usar o jQuery, estou vendo cada vez mais que desenvolvedores não entendem o que é realmente simples. Meus 2 centavos, não pude resistir a comentar. ;)
Sander
58
Também existem muitos seres humanos que não saberiam por onde começar se tivessem que lavar suas roupas à mão, já que a maioria das famílias possui uma lavadora e quase a mesma possui um secador de roupas. O jQuery, como os aparelhos modernos, tornou uma tarefa muito mais fácil e menos propensa a erros. Não é a solução para todos, no entanto, reduzir a votação de uma resposta que responda com precisão à pergunta usando uma sintaxe mais concisa e compreensível enquanto compatível com vários navegadores, parece invertida. +1.
FreeAsInBeer
2
@FreeAsInBeer Então você também não deve andar em lugar nenhum, pois dirigir é muito mais fácil. Mas sabemos que isso é bobagem. Você anda se não precisar ir muito longe. Você usa JavaScript simples se precisar fazer algo simples e não quiser carregar uma biblioteca inteira para fazê-lo. Não há necessidade de desperdiçar gás / largura de banda para algo simples.
24675 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.
}

Referência

mnishiguchi
fonte
Eu acredito que esta deve ser a melhor resposta nos dias de hoje
DavidTaubmann
15

Você pode economizar muito espaço usando o jQuery. Você só precisa usar:

$('#myElement').trigger("click")
Adam Salma
fonte
10
O OP pediu JavaScript. Embora isso seja compacto e funcional, algumas pessoas preferem o JS sem biblioteca do que o jQuery.
Carcass
43
Economize espaço baixando jquery?
MH
9
Algumas pessoas preferem montagem também.
Dan Nissenbaum 3/09/16
@MH Acho que um argumento mais válido seria "para simplificar". Seu perfil padrão aqui no SO é aproximadamente do mesmo tamanho do jQuery.
adelriosantiago 14/12/19
7

A melhor resposta é a melhor! No entanto, quando não estava acionando eventos de mouse para mim no Firefox etype = 'click'.

Então, mudei o document.createEventpara 'MouseEvents'e resolvi o problema. O código extra é para testar se outro código está interferindo ou não no evento, e se ele fosse cancelado, eu o registraria no console.

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
fonte