スタッフブログ Staff Blog

PDFファイルの閲覧数などを計測するJavaScriptの汎用化

約2週間前、「gtag.jsでPDFファイルの閲覧数やバナーのクリック数の計測」の記事で、Google アナリティクスのgtag.jsを使用し、PDFファイルの閲覧数などを計測する方法についてご紹介しました。その際はまだコードを汎用化しておらずサイト全体で読み込むJavaScriptファイルにjQueryで記述をしていたのですが、今後も積極的に計測をしていきたいと考えており、簡単に計測が始められるようにコードを汎用化しました。

コードの汎用化に当たって、以下の方針で記述してみました。

  • IE11をサポートしなくてもよい時代が来た後もメンテナンスしやすいこと...ES2015を使ってみること
  • 誰でも簡単に使用できること
  • jQuery非依存(もしかするとjQueryを使用しないプロジェクトへの対応)

jQueryに非依存については、今はもうjQueryを使わないのが良い等とは思ってはなく、シングルページアプリケーションではないごく一般的な企業様のサイトではこれからもjQueryを使い続けるのかな、という気がしております。

コードと使い方

コードと使い方(README.md)はGitHubの「hideki-a/autotrack」に置いています。

簡単に述べると、autotrack.min.jsを読み込みconst autotrack = new Autotrack(GA_TRACKING_ID);でAutotrackインスタンスを生成、autotrack.fileTracker();でPDFファイル等の閲覧数を計測したり、autotrack.bannerTracker({設定を書く});でバナーのクリック数計測をしたりするようにしました。

ES2015(ES6)を使ってみて

ES2015(ES6)については以前から勉強していましたが、本格的に使ったのは久しぶりかもしれないという印象がしました。

一番大きいのはクラス定義を使用したこと、アロー関数を使用したことでしょうか。クラスはJavaScriptにすでにあるプロトタイプベース継承の糖衣構文とは言え、コードが直感的に書きやすくなる、直感的に分かりやすくなることは間違いないでしょう。アロー関数はaddEventListener()を使う前にvar self = this;などと書かなくて良いのが助かります。

Array.from()を使いたいけれど...

querySelectorAll()で取得した要素をループで回してイベントを付ける、という処理はよく書くのではないでしょうか。この時、querySelectorAll()の返値はNodeListなのでforEach()が使用できません。そこでArray.from()を使いたくなるのですが、IE11が現状対応していません。ではポリフィルを使おうかとなるのですが、コードが結構長くてサイズが増えそう...。結論として、[].forEach.call(elems)と書きました。

[].forEach.call()は少々分かりづらさがある(.call().apply()は昔理解するのに時間がかかりました)、Array.from()は分かりやすいけれどIE11が足を引っぱる、という点はもやもやする所です。

イベントを登録するからには削除できるようにもしたい

addEventListener()で登録したイベントを任意のタイミングで削除したいと考えremoveEventListener()を使おうとしました。その際、第2引数にはaddEventListener()の第2引数と同じ関数を渡す必要があるのですが、上手く書けませんでした。というのも下記コードのように第2引数の外で定義している定数を第2引数内の関数で使用しているためです。

const links = document.querySelectorAll(trackerOptions.bannerSelector);
const eventAction = trackerOptions.eventAction;
const eventCategory = trackerOptions.eventCategory;
[].forEach.call(links, link => {
  link.addEventListener('click', (e) => {
    const images = link.getElementsByTagName('img');
    const eventLabel = images[0].getAttribute('alt');
    this._sendEvent(eventAction, eventCategory, eventLabel);
  });
});

このような場合はどうしたものかと考えたのですが答えを見つけられずヒントを検索したのですが、Stack OverflowのHow to removeEventListener that is addEventListener with anonymous function?に対する返答に要件を満たす回答があり助かりました。

お問い合わせ Contact

制作のご依頼、ご相談などは下記のフォームからご連絡ください。