javascript
  • node.js
  • ecmascript-6
  • jsdom
  • es6-proxy
  • 2016-10-14 101 views 0 likes 
    0

    我需要拦截对某些DOM API函数的调用并将其参数存储为副作用。例如,假设我对函数getElementsByTagNamegetElementById感兴趣。见下面的例子:拦截调用DOM API函数

    "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"]} 
    

    一个重要的注意的是,我使用Node.js的对象documentjsdom库实现。到目前为止,我试图利用ES6代理修改上述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"] 
    
    +0

    我不知道为什么,但它听起来就像你做了坏事... – evolutionxbox

    +0

    @evolutionxbox什么叫'坏thing'是什么意思? –

    +0

    你试图通过拦截这些调用来解决什么是你的[实际问题](http://meta.stackexchange.com/q/66377)? – Bergi

    回答

    0

    如果您只想拦截对这两个函数的调用,则不需要使用代理服务器。您只需存储原始函数的副本,然后使用保存参数的函数覆盖要拦截调用的函数,然后调用原始函数。

    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)

    +0

    它只跟踪文档对象上的调用,而不是_Element_。例如这里'console.log(document.getElementById('test')。getElementsByTagName('span'));'_span_不存储在标签中。 –

    +0

    @AlexElyasov看我的编辑。 –

    +0

    似乎不太可能覆盖每个单独的方法;只是说。 – naomik

    相关问题