Jak symulować kliknięcie za pomocą JavaScript?

292

Zastanawiam się, jak mogę użyć JavaScript do symulacji kliknięcia elementu.

Obecnie mam:

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

Ale to nie działa :(

Jakieś pomysły?

Belgin Fish
źródło
9
„Pięć najczęstszych błędów kodowania”: javascript.about.com/od/hintsandtips/a/worst_4.htm - Prawie nikt już nie uruchamia IE4, więc obsługa DOM document.all nie jest już wymagana. To naprawdę zaskakujące, jak wiele osób nadal używa go w kodowaniu. Gorsze jest to, że obsługa dokumentu.all DOM jest często testowany w celu określenia używanej przeglądarki, a jeśli jest obsługiwany, kod zakłada, że ​​przeglądarka to Internet Explorer (co jest całkowicie niewłaściwe, ponieważ Opera rozpoznaje również DOM) .
zaf
1
Zobacz stackoverflow.com/questions/1421584/...
Crescent Fresh

Odpowiedzi:

418

Oto co ugotowałem. To dość proste, ale działa:

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);
  }
}

Stosowanie:

eventFire(document.getElementById('mytest1'), 'click');
KooiInc
źródło
12
@Anderson Green: Dodałem przykład do tego jsfiddle: jsfiddle.net/KooiInc/W4BHD
KooiInc
4
Dowód, że to działa (w Chromium): +1 z document.querySelector('[value="2706236"]').nextSibling.nextSibling.dispatchEvent(ev);:)
PointedEars
58
Cóż, próbowałem skryptu java na przycisku głosowania w górę :) (działało oczywiście)
0fnt
1
Aby symulować dokładne zachowanie użytkownika, powinieneś owinąć dispatchEventlub clickwywołania setTimeout, ponieważ wydaje się, że dispatchEventjest synchroniczne .
Lew Kazakow
16
Event.initEventjest teraz przestarzały developer.mozilla.org/en/docs/Web/API/Event/initEvent
artnikpro
393

Co z czymś prostym, takim jak:

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

Obsługiwany nawet przez IE.

Darren Sweeney
źródło
@HermannIngjaldsson Tak, działa idealnie w IE - msdn.microsoft.com/en-us/library/ie/ms536363%28v=vs.85%29.aspx
Darren Sweeney
6
Pytanie brzmiało: „czy to działa np. Również?” - odpowiedź brzmi tak - AFAIK co najmniej do 8, nie sprawdziłem 7
Darren Sweeney
24
Czy to wcześniej nie istniało? Dlaczego w odpowiedziach z 2010 r. Nie wspomniano o tym prostym rozwiązaniu? Po prostu ciekawy ...
Parth
3
@ NinoŠkopac Działa świetnie obecnie na komputery stacjonarne, ale nie ma gwarancji współpracy z przeglądarkami mobilnymi. Nawet witryna programisty mozilla nie wyświetla wsparcia mobilnego.
le0diaz
8
@Parth Może tak było, to po prostu nie kliknij na nich.
Andrew
78

Czy rozważałeś użycie jQuery, aby uniknąć wykrycia wszystkich przeglądarek? Z jQuery byłoby to tak proste, jak:

$("#mytest1").click();
BradBrening
źródło
21
To tylko uruchamianie programów obsługi zdarzeń jQuery, a nie zachowanie domyślne (w tym przypadku przeglądarka przechodzi do href)
Romuald Brunet
12
Nie wiem o smutku, ale na pewno może być wygodne, aby nie musieć ciągle przekodowywać tych samych procedur wykrywania przeglądarki.
BradBrening
9
@ErikAigner: Zastanawiałem się nad tym samym, ale cieszę się, że przyjęta odpowiedź w tym przypadku to zwykły JavaScript, a nie jQuery. Widziałem to zbyt wiele razy na SO. Jeszcze raz: jQuery jest JavaScript, ale JavaScript nie jest jQuery. Chociaż lubię używać jQuery, coraz częściej widzę, że deweloperzy nie rozumieją prawdziwej rzeczy. Moje 2 centy, nie mogłem się oprzeć komentowaniu. ;)
Sander
58
Jest też wielu ludzi, którzy nie wiedzieliby, od czego zacząć, gdyby musieli prać ręcznie, ponieważ większość gospodarstw domowych ma pralkę, a prawie tyle samo ma suszarkę do ubrań. jQuery, podobnie jak nowoczesne urządzenia, sprawił, że stare obowiązki stały się łatwiejsze i mniej podatne na błędy. Nie jest to jednak rozwiązanie dla wszystkich, oddawanie głosu w dół odpowiedzi, która dokładnie odpowiada na pytanie przy użyciu bardziej zwięzłej, zrozumiałej składni, a jednocześnie kompatybilność z różnymi przeglądarkami wydaje się być wstecz. +1.
FreeAsInBeer
2
@FreeAsInBeer Następnie nie powinieneś nigdzie chodzić, ponieważ jazda samochodem jest o wiele łatwiejsza. Ale wiemy, że to głupie. Idziesz, jeśli nie musisz iść daleko. Używasz zwykłego JavaScript, jeśli chcesz zrobić coś prostego i nie chcesz w tym celu załadować całej biblioteki. Nie trzeba marnować gazu / przepustowości na coś prostego.
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.
}

Odniesienie

mnishiguchi
źródło
Uważam, że obecnie powinna to być najlepsza odpowiedź
DavidTaubmann
15

Możesz zaoszczędzić sporo miejsca za pomocą jQuery. Musisz tylko użyć:

$('#myElement').trigger("click")
Adam Salma
źródło
10
OP poprosił o JavaScript. Chociaż jest to kompaktowe i funkcjonalne, niektórzy ludzie wolą JS bez biblioteki niż rzeczy takie jak jQuery.
Tusza
43
Zaoszczędź miejsce, pobierając jquery?
MH,
9
Niektórzy wolą też montaż.
Dan Nissenbaum,
@ MH Myślę, że bardziej uzasadnionym argumentem byłoby „upraszczanie”. Twój domyślny profil tutaj w SO ma mniej więcej ten sam rozmiar jQuery.
adelriosantiago,
7

Najlepsza odpowiedź jest najlepsza! Jednak w Firefoksie nie powodowało to zdarzeń myszyetype = 'click' .

Więc zmienił document.createEventsię 'MouseEvents'i że problem został rozwiązany. Dodatkowym kodem jest sprawdzenie, czy inny fragment kodu zakłóca zdarzenie, a jeśli zostanie anulowany, zaloguję to na konsolę.

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
źródło