Google Chrome にはいくつか開発者ツール内で限定的に使える機能があります。例えば $$(‘セレクター’) でセレクターに合う要素を配列で取得できたりします。他にもそのような関数や変数がいくつかあり、これらの一覧は次リンクのページで見ることができます。
Console Utilities API reference – Chrome Developers
getEventListeners はそういった Google Chrom のコンソール限定機能の一つであり、与えられた要素のイベントリスナーを取得する関数です。この関数を利用することでイベントリスナーの検索ができます。これの実装が次です。
/** * 指定されたセレクタまたは要素の子孫にアタッチされたイベントリスナーを検索します。 * @param {string|HTMLElement} selectorOrEl - セレクタ文字列またはHTMLElement。 * @returns {Array} elementsWithListeners - 要素、イベントタイプ、リスナーに関する情報を含むオブジェクトの配列。 */ function findEventListeners(selectorOrEl) { // 入力がセレクタ文字列かHTMLElementかを判断 const element = typeof selectorOrEl === 'string' ? document.querySelector(selectorOrEl) : selectorOrEl; // 指定された要素のすべての子孫要素を検索 const allElements = element.querySelectorAll(`*`); // イベントリスナー付きの要素を格納する配列を初期化 const elementsWithListeners = []; // すべての要素を反復処理 allElements.forEach(element => { // 現在の要素にアタッチされているイベントリスナーを取得 // @see https://developer.chrome.com/docs/devtools/console/utilities/#getEventListeners-function const eventListeners = getEventListeners(element); // 現在の要素にアタッチされているイベントリスナーがない場合はスキップ if (Object.keys(eventListeners).length === 0) { return; } // 現在の要素にアタッチされているすべてのイベントタイプを反復処理 for (const eventType in eventListeners) { // 現在のイベントタイプのすべてのイベントリスナーを反復処理 eventListeners[eventType].forEach(listener => { // 要素、イベントタイプ、リスナーに関する情報を含むオブジェクトを配列に追加 elementsWithListeners.push({ element, eventType, listener }); }); } }); // イベントリスナー付きの要素の配列を返す return elementsWithListeners; } /*** 使用例 ***/ // 要素を渡して実行。ここでは body 以下を検索 const bodyListeners = findEventListeners(document.body); console.table(bodyListeners); // セレクタを渡して実行。ここでは id="search-user-page" な要素以下を検索 const searchUserPageListeners = findEventListeners('#search-user-page'); console.table(searchUserPageListeners);
getEventListeners に要素を渡すと要素に設定されているイベントの種類とリスナーを返してくれます。上記の findEventListeners 関数では引数から得られる要素の子孫要素を一通り取得し、取得した要素の getEventListeners の返り値をまとめる処理をしています。これによりページ中のある部分に絞ってイベントリスナーを探すなどして、イベントリスナーの動作をより調査しやすくなります。もしこれを拡張するのであればイベントの種類やリスナー関数によるフィルターをつけるあたりが便利そうです。