要素の中身やデータが変更された時はMutationObserver

Webマーケティング

onChangeはformでしか使えない


「トップのメイン画像がスライドして表示されたときに拡張eコマースの商品のインプレッションを計測するように」と言われたとき、どうしますか?

「画像がスライドされるならGoogle Tag Managerの『要素の表示』トリガーが使えるのでは?」と思ったのですが、この画像たちはすでに表示されているようになっていて使えないという事実が判明。

画像の横の位置が動的に変わる事でスライドされるように表示されていたので、「javascriptのonChange関数やjQueryのchange関数を使えばできるなぁ」と思ったのですが、onChange関数はselectなどのformでしか使えないという事なのでこれまた却下。
(参考:HTML onchange Event Attribute(w3schools.com)

要素の属性値などを監視するMutationObserver

今回、この画像を含むdivではいくつかの要素の属性値が変わっていました。そこで今回は、MutationObserverクラスを使います。

MutationObserverクラスで指定の要素を監視

// 1.監視する対象のIDを指定
var targetNode = document.getElementById('XXXXX');

// 2.MutationObserverのオプションを実行前に指定
var config = { attributes: true, childList: true, subtree: true };
// 3. 変更があった時に実行したい処理をここに記述
var callback = function(mutationsList, observer) {
    for(var mutation of mutationsList) {
         if (mutation.type == 'attributes') {
            // 属性が変わった時に実行したい場合はここに書く 
            console.log(mutation.attributeName + ' が変わりました');
        }else if (mutation.type == 'characterData') {
            // データが変わった時に実行したい場合はここに書く 
        }else if (mutation.type == 'childList') {
            // 対象ノードの子ノード(テキストノードも含む)が変わった時に実行したい場合はここに書く 
        }
    }
};

// 4. MutationObserverインスタンスの作成
var observer = new MutationObserver(callback);
// 5. 対象ノードの監視開始
observer.observe(targetNode, config);

// 6. 監視を終了するときにはdisconnect()を実行
// observer.disconnect();

MutationObserverオプションはできるだけ設定すべき

2のMutationObserverのオプションのうち、attribute、characterData、childListは必ず設定しておくことをお勧めします。特にchildListをfalseにしないと、子ノードに変更があった場合にもイベントが発生するため、注意しましょう。

MutationObserverのオプション一覧

childList対象ノードの子ノード(テキストノードも含む)に対する追加・削除を監視する場合は true にします。
attributes対象ノードの属性に対する変更を監視する場合は true にします。
characterData対象ノードのデータに対する変更を監視する場合は true にします。
subtree対象ノードとその子孫ノードに対する変更を監視する場合は true にします。
attributeOldValue対象ノードの変更前の属性値を記録する場合は true にします(attributes が true の時に有効)。
characterDataOldValue対象ノードの変更前のデータを記録する場合は true にします(characterData が true の時に有効)。
attributeFilterすべての属性の変更を監視する必要がない場合は、(名前空間を除いた)属性ローカル名の配列を指定します。

3のif句内で実行したいことを記述します。今回は分けていますが、属性の変更時のみだけで良い場合は、最初のif部分だけで構いません。上にも書いていますが、子ノードの変更を監視したくない場合はわざと if (mutation.type == ‘childList’) 句を用意して中身を空欄にしておくなどしておいた方が安全です。

4と5はお決まりの書き方なので、そのまま使ってください。

6については終了させたいときに呼び出してください。

コメント

タイトルとURLをコピーしました