1

一部の DOM API 関数の呼び出しをインターセプトし、それらの引数を副作用として保存する必要があります。たとえば、関数getElementsByTagNameとに興味があるとしgetElementByIdます。以下の例を参照してください。

"use strict";
const jsdom = require("jsdom");
let document = jsdom.jsdom("<html><head></head><body><div id='foo'><div></div></div></body></html>");
let cpool = {ids: [], tags: []};
let obj = document.getElementById("foo");
// --> cpool = {ids: ["foo"], tags: []}
obj.getElementsByTagName("div"); 
// --> cpool = {ids: ["foo"], tags: ["div"]}

1 つの重要な注意点は、私はnode.jsを使用しており、documentオブジェクトはjsdomライブラリによって実装されているということです。これまでのところ、ES6 Proxies を利用して、前述の DOM 関数の動作を変更しようとしました。

これが、すべてのメソッド呼び出しをトラップするためにドキュメントオブジェクトをプロキシしようとした方法です。この手法または他の手法を使用して、問題を解決できるかどうか、またどのように使用できるか疑問に思います。

let documentProxy = new Proxy(document, {
    get(target, propKey, receiver) {
        return function (...args) {
            Reflect.apply(target, propKey, args);
            console.log(propKey + JSON.stringify(args));
            return result;
        };
    }
});    
documentProxy.getElementById("foo");
// --> getElementById["foo"]
4

1 に答える 1

0

これら 2 つの関数の呼び出しのみをインターセプトする場合は、プロキシを使用する必要はありません。元の関数のコピーを保存し、引数を保存してから元の関数を呼び出す関数で呼び出しをインターセプトする関数をオーバーライドすることができます。

const cpool = {ids: [], tags: []}

;(getElementsByTagNameCopy => {
  document.getElementsByTagName = tag => {
    cpool.tags.push(tag)
    return Reflect.apply(getElementsByTagNameCopy, document, [tag])
  }
})(document.getElementsByTagName)

;(getElementsByTagNameCopy => {
  Element.prototype.getElementsByTagName = function(tag) {
    cpool.tags.push(tag)
    return Reflect.apply(getElementsByTagNameCopy, this, [tag])
  }
})(Element.prototype.getElementsByTagName)

;(getElementByIdCopy => {
  document.getElementById = id => {
    cpool.ids.push(id)
    return Reflect.apply(getElementByIdCopy, document, [id])
  }
})(document.getElementById)

console.log(document.getElementsByTagName('body'))
console.log(document.getElementById('whatever'))
console.log(document.body.getElementsByTagName('div'))
console.log(cpool)

于 2016-10-14T10:01:53.290 に答える