ゆうなんとかさんの雑記帳的な。

Twitterで踊ったり音ゲーしたりしてるあの名前がよくわからない人が書いてるらしいよ。

JavaScriptのクリックイベントを発火させる方法

最近噂のCookieClickerというゲームがあります。
Cookie Clicker
ゲーム内容はクッキーをクリックしたりクッキーを消費して様々なユニットやアップグレードアイテムを購入したりして、ひたすらクッキーを生産し続けるというゲームなのかもはやよくわからないゲームです。
ここ数日急用があったので放置気味でしたが、今のところ始めて3日で、1秒間につき地球上のすべての人にあまねく10枚ずつ以上クッキーを渡せる程度の生産量になりました。通な言い方をすれば約82GCpS*1です。やりこんでいる人は数PCpSを軽く超える生産量だそうです。桁の吹っ飛び具合が人気の秘訣なのでしょうか。
でこのゲーム、実はHTML5でできてるんですよね。しかも、「自動クリック程度はチートじゃないからやってもいいらしい*2」とのこと。ということなので、プログラマーの端くれとしては自動クリックくらいはやってみたいものです。
ということで、JavaScriptのクリックイベントを発火させてみましょう。
もちろん、これはUIテストでクリックイベントを発火させたいときなどに応用することもできます。

お手軽な方法

HTMLElementにはclickというclickイベントを発生させるメソッドがあります。これが使えるものであれば使うのが一番お手軽です。

var clickMe = document.getElementById("click_me");
clickMe.click();

ちなみにこれ、一部のエレメントではうまく動いてくれないらしいです。そこで、以下の2通りの方法も試してみましょう。
HTMLElementにはonclickというクリックイベントのハンドラがあります。これに関数を代入する形でイベントリスナーをハンドルさせている場合、その関数を呼び出してあげるとよいでしょう。

var clickMe = document.getElementById("click_me");
clickMe.onclick = function() { alert("I was clicked!"); }; //こういうふうにイベントリスナーを設定してあると
clickMe.onclick(); //これでイベントが発火する

ただし、この方法ではaddEventListenerを使って登録されたイベントリスナーを呼び出すことはできません。

イベントオブジェクトを使う方法

少々手間はかかりますが、こちらは確実です。

var clickMe = document.getElementById("click_me");
if( /*@cc_on ! @*/ false )
{
  // IEの場合
  clickMe.fireEvent("onclick"); //これでclickイベントが発火する
}
else
{
  // それ以外の場合
  var event = document.createEvent( "MouseEvents" ); // イベントオブジェクトを作成
  event.initEvent("click", false, true); // イベントの内容を設定
  clickMe.dispatchEvent(event); // イベントを発火させる
}

ちなみに…

CookieClickerでは2つ目のonclickを呼び出す方法でイベントリスナーを呼び出すことができます。これとsetIntervalを組み合わせれば、いとも簡単に人間離れしたインターバルでクッキーを連打しつつ、金のクッキーももれなく回収することができます。この程度だと作者にとってはチートというよりはTASの範疇らしいですよ!
…とここまで書きましたが、実はこの他にも、クリックしたときに呼び出されるメソッドを直接叩いても同じことができます。こちらの方法ではたまにしか現れない金のクッキーをたくさん出したりと、本格的にチートすることもできます。

*1:CpS(Cookies per Second、クッキー毎秒)

*2:生産数よりもなぜか多い所持数にする、なぜか出てくるはずのない金のクッキーが出てくるようにするなどがチートになるとこのと。実際にやると不名誉な実績を解除してしまうとか