Как создать прокси для HTMLELement - PullRequest
0 голосов
/ 06 мая 2019

Как создать прокси для родного объекта dom браузера?

Я хочу перехватить настройки стиля элемента. Поэтому я создаю прокси для объекта dom. Однако это вызывает ошибку, когда я использую какую-то функцию, такую ​​как getComputedStyle.

  const setHandler = (target: any, prop: PropertyKey, value: any, _receiver?: any) => {
    if (/*some condition*/) {
      target[prop] = value
    }
    return true
  }

  const getHandler = (target: any, prop: PropertyKey, _receiver?: any) => {
    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) => {
      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)

el - это нативный объект dom браузера. В моем коде есть много методов, параметры которых - el, и эти методы могут изменять el. Я хочу, чтобы некоторые из этих методов не модифицировали el, поэтому я пытаюсь прокси-объект el. Но после прокси некоторые методы для объектов dom нельзя использовать на объектах прокси, например, getComputedStyler.

Я создаю демо ниже.

(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)
})()
<div id='demo'>demo</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...