Прокси HTMLElement - PullRequest
       8

Прокси HTMLElement

0 голосов
/ 29 августа 2018

Я хотел проверить, что библиотека делает с элементом видео, который я передаю ей, поэтому я наивно сделал это:

cosnt videoElement = new Proxy(document.querySelector('video'), {
    get(target, key) {
        const name = typeof key === 'symbol'? key.toString() : key;
        console.info(`Accessing video.${ name }`)
        return target[key];
    }
});

Но я получил ошибку:

TypeError: Не удалось выполнить «contains» на «Node»: параметр 1 не относится к типу «Node».

Есть ли способ заставить эту работу?


РЕДАКТИРОВАТЬ: я получил некоторые знания, с его помощью я обновил мой прокси как пара:

cosnt videoElement = document.querySelector('video');
cosnt proxyElement = new Proxy(videoElement , {
    get(target, key) {
        if (key == '___element___') {
            return video;
        }

        const name = typeof key === 'symbol'? key.toString() : key;
        console.info(`Accessing video.${ name }`);
        const value = video[key];
        if (value instanceof Function) {
            return video[key].bind(video);
        } else {
            return video[key];
        }
    },
    set(target, key, value) {
        const name = typeof key === 'symbol'? key.toString() : key;
        console.info(`Writing video.${ name } = ${ value }`);
        video[key] = value;
        return true;
    }
});

Он предназначен для отладки, поэтому я отредактировал скомпилированный код и заменил все ссылки на манипуляции с DOM на element.___element___.

Затем я обнаружил, что, похоже, существуют проблемы с вызовом функций через прокси, поэтому я добавил часть .bind(video).

И, наконец, установка значений была выброшена. Поэтому мне пришлось заменить цель на прямую ссылку на видео (фактически, я заменил все ссылки на цель на видео, чтобы быть уверенным), что заставило его работать ... Я не уверен, почему или как, но это произошло.

Вопросы:

  • Это действительно так, как должно быть? (document.body.contains(myProxyElement) часть)
  • Установка значений для выброса видеоэлемента при настройке внутри прокси казалась странной, это ошибка? (3-й пункт, вроде второй тоже, я полагаю, он подключен)

Бонус: детская площадка

const video = document.querySelector('video');
const proxy = new Proxy(video, {
  get(target, key) {
    console.log(`Getting video.${typeof key === 'symbol'? key.toString() : key}`);
    const value = video[key];
    if (value instanceof Function) {
      return value.bind(video);
    } else {
      return value;
    }
  },
  set(target, key, value) {
    console.log(`Setting video.${typeof key === 'symbol'? key.toString() : key} =`, value);
    video[key] = value;
    return true;
  }
});

proxy.muted = true;
proxy.play();
proxy.controls = true;
try {
  console.log(document.body.contains(proxy));
} catch (e) {
  console.error('DOM operation failed', e);
}
video { max-width: 100%; }
<video src="//vjs.zencdn.net/v/oceans.mp4">

1 Ответ

0 голосов
/ 10 сентября 2018

Как уже упоминалось в комментариях, объект Proxy не будет автоматически приведен к Node при вызове document.body.contains(proxy).

Следовательно, вы можете установить конкретный ключ, который будет возвращать цель прокси:

const video = document.querySelector('video');
const proxy = new Proxy(video, {
  get(target, key) {
        const value = video[key];
        if (value instanceof Function) {
        return value.bind(video);
        } else if (key == 'target') {
        return target;
      } else {
        return value;
        }
  },
  set(target, key, value) {
    target[key] = value;
    return true;
  }
});

И тогда вы можете сделать:

console.log(document.body.contains(proxy.target));

Редактировать

Это действительно так, как и должно быть? ( document.body.contains (myProxyElement) часть):

Да, я не вижу другого способа, как это сделать.

Установка значений для броска видеоэлемента при настройке внутри прокси казалось странным, это ошибка? (3-й пункт, вроде как второй, я полагаю, подключен):

Поскольку я не могу воспроизвести эту проблему, трудно сказать. Может быть, попробуйте заменить new Proxy(video, ... на new Proxy({}, ..., а затем установить видео как proxy.video = video (вам также придется обновить логику в get и set) и посмотреть, как это ведет себя?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...