title: How to create a proxy for HTMLELement
body: <h1>Question</h1>
  
  <p>How to create a proxy for browser native DOM object?</p>
  
  <hr>
  
  <h2>Background</h2>
  
  <p>I want to intercept the settings for the element style. So I create a proxy for the DOM object. However, it causes error when I use some function like <code>getComputedStyle()</code>.</p>
  
  <pre class="lang-js prettyprint-override"><code>  const setHandler = (target: any, prop: PropertyKey, value: any, _receiver?: any) =&gt; {
      if (/*some condition*/) {
        target[prop] = value
      }
      return true
    }
  
    const getHandler = (target: any, prop: PropertyKey, _receiver?: any) =&gt; {
      return target[prop]
    }
  
    const style = new Proxy(el.style, {
      get: getHandler,
      set: setHandler
    })
    const classList = new Proxy(el.classList,{
      get: getHandler,
      set: setHandler
    })
  
    const proxy = new Proxy(el/*HTMLElement*/, {
      get: (target, prop, _receiver) =&gt; {
        if (prop === 'target') {
          return target
        }
        if (prop === 'style') {
          return style
        }
        if (prop === 'classList') {
          return classList
        }
        return getHandler(target, prop, target)
      },
      set: setHandler
    })
  
    const style = getComputedStyle(el)
  
  </code></pre>
  
  <p><code>el</code> is the native browser DOM object. In my code, there are many methods whose parameters are <code>el</code>, and these methods may modify el. </p>
  
  <p>I want to prevent <em>some</em> of these methods from modifying <code>el</code>, so I am trying to proxy the <code>el</code> object. </p>
  
  <p>But after the proxy, some methods for DOM objects can't be used on proxy objects (like <code>getComputedStyle()</code>).</p>
  
  <hr>
  
  <h2>Demo</h2>
  
  <p>I create a demo below.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>(function() {
    const node = document.querySelector('#demo')
    const proxy = new Proxy(node, {
      getPrototypeOf(target){
        return Object.getPrototypeOf(target)
      },
      get(target, prop, receiver){
        let value = target[prop]
        if (typeof value === 'function') {
          value = Function.prototype.bind.call(value, target)
        }
        return value
      },
      set(target, prop,value, receiver){
        target[prop] = value
      },
      apply(target, args, newTarget) {
        return Object.apply(target,args)
      },
    })
    console.log(proxy)
    console.log(Object.getPrototypeOf(proxy))         
   
    console.log(proxy.style)
  
    // error: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.
    const style = getComputedStyle(proxy)
    console.log(style)
  })()</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;div id='demo'&gt;demo&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>