JavaScriptでのイベントリスニングのハンドルを取得する
-
05-07-2019 - |
質問
先週、Omnitureの分析コードを、先週程度の調整とテストの後、大量のWebサイトにリリースしました。
ほとんどすべてのサイトテンプレートで、問題なく機能します。散発的で予測不可能ないくつかの状況では、一部のユーザーを追い払う可能性のある、ひどいブラウザクラッシュエクスペリエンスがあります。
現時点では、クラッシュしているテンプレート間の関係を確認することはできません。また、トラブルシューティングする方法は ありますが、私たちを困惑させているのはイベントリスナーに関連しています。
これらのテンプレートのアンカーをクリックすると、サイトがクラッシュします。インラインJSはありません。また、HTMLの属性を調べてバグを修正しましたが、これを引き起こす識別可能なループや問題は見つかりませんでした。 (トラブルシューティング中に、こちら [警告!ページ内のリンクをクリックすると、ブラウザがクラッシュします!]
オブジェクトにリスナーがあるかどうかをどのように判断しますか?イベントがトリガーされたときに起動するものをどのように決定しますか?
FYI、ブレークポイントを設定したいのですが、 Omnituresが悲惨なほど難読化されたコードと繰り返されるブラウザの間 クラッシュ、さらに調査したい 徹底的にこれにアプローチする方法。
解決
「要素の検査」を行いましたそのページのfirebugのあるリンク、およびDOMタブには、onclick関数(匿名)と" s_onclick_0"と呼ばれる他の関数があります。
Firebugが時計を置くように誘導しました
alert(document.links[0].onclick)
omniture(私が推測する)がリンクに付加するonclick関数を通知するには:
function anonymous(e) {
var s = s_c_il[0], b = s.eh(this, "onclick");
s.lnk = s.co(this);
s.t();
s.lnk = 0;
if (b) {
return this[b](e);
}
return true;
}
たぶん同じ方法で、その難読化の後に実際に実行されているものを見ることができます。
他のヒント
DOMは、ノードに関連付けられたイベントリスナーのコレクションを参照する手段を提供しません。
リスナーを特定できる唯一の状況は、要素にプロパティまたは属性を設定することでリスナーが追加されたときです-onxxxのプロパティまたは属性を確認します。
この機能を追加するかどうかについて、最近W3のWebAPIグループで講演がありました。専門家はそれに反対しているようです。私は彼らの議論を共有します。
オンページ分析の実装者への一連の推奨事項:
-
ドキュメントレベルのイベントキャプチャのみを使用します。これはほとんどすべての場合(変更/送信イベントを除く)で十分です
-
ハンドラーで計算集中型のコード(およびIO操作)を実行せず、タイムアウトで実行を延期します
この2つの単純なルールを考慮に入れると、ブラウザは存続するはずです
Omnitureの使用経験があり、s_code.jsを見ると、「リンクトラッキング」でいくつかのことが行われています。エリア、例:
/* Link Tracking Config */
s.trackDownloadLinks=true
s.trackExternalLinks=true
s.trackInlineStats=true
s.linkDownloadFileTypes="exe,zip,wav,mp3,mov,mpg,avi,wmv,pdf,doc,docx,xls,xlsx,ppt,pptx"
s.linkInternalFilters="javascript:,gatehousemedia.com"
s.linkLeaveQueryString=false
s.linkTrackVars="None"
s.linkTrackEvents="None"
Omnitureの人々と相談し、リンクトラッキング設定が正しく設定されていることを確認します。
具体的には、このテンプレートと内部のリンクはmorningsun.netに属しているようですが、morningsun.netはs.linkInternalFilters設定に含まれていません。複数のドメインに同じs_code.jsファイルを使用している場合、javascriptを使用して、このような設定値を設定できます(たとえばdocument.location.hostnameに基づいて)。
私は個人的にリンクトラッキング設定の経験がありません。または、設定方法の詳細をお知らせします:)
帰宅中に、AddEventListenerで追加された要素のイベントハンドラーを内観できるソリューションに行きました。分析コードを含める前にコードを実行します。コードが機能するかどうかは検証されませんでしたが、アイデアは明らかです。 IEでは動作しませんが、同様の手法(APIメンバーの書き換え)を適用することもできます。
(function(){
var fAddEventListener = HTMLElement.prototype.addEventListener;
HTMLElement.prototype.addEventListener = function() {
if (!this._listeners)
this._listeners = [];
this._listeners.push(arguments);
fAddEventListener.apply(this, arguments);
}
})();