Обработка property.subproperty в обработчике прокси - PullRequest
0 голосов
/ 30 апреля 2018

Введение

Пожалуйста, имейте в виду, я знаю, почему мое решение не работает, и мой вопрос заключается в том, как заставить его работать, с текущим кодом или совершенно другим способом, если возможно.

Также имейте в виду, что это , а не дубликат В обработчике Proxy как отличить получение свойства (var) от вызова метода? или Как чтобы получить аргументы функции в обработчике прокси , хотя это может звучать похоже.

После всех этих мер предосторожности:

Я пытаюсь создать «селектор», похожий на тот, который известен из jquery, но использую es6 'querySelectorAll и объект Proxy.

Я хочу использовать Proxy, потому что я хочу затем вызвать mySelector ('div'). Style = 'color: red' - таким образом, что я не хочу добавлять свойство 'style' - я не надеваю даже не хочу знать заранее, что такая вещь существует - я хочу использовать свойство стиля существующий (в HTMLElement)

Я также хочу перехватывать вызовы методов, например mySelector ('div'). SetAttribute (...);

Ток Почти Рабочий раствор:

Здесь функция yes возвращает объект Proxied Yes. Там я ловлю "получить" и "установить". Это прекрасно работает с:

yes('.allDivs').setAttribute('style','color:red');

yes('.allDivs').style = 'color:blue';

Но это не работает:

yes('.allDivs').style.color = 'green';

Код:

Пример HTML:

<div class = 'allDivs'>
 blah1 
</div>

<div class = 'allDivs'>
 blah2
</div>

Javascript:

(function(window) {

  class Yes {

      constructor(selector){
        this.length = 0;
        this.nodes  = [];
        if(typeof selector === 'string' && selector !== '') {
          this.nodes = Array.from(document.querySelectorAll(selector));
        }

        //This is we can access the object with [index]:
        if (this.nodes.length) {
          this.length = this.nodes.length;
          for (var i = 0; i < this.nodes.length; i++) {
            this[i] = this.nodes[i];
          }
        }
      }

      //methods:
      forEach (elem) {this.nodes.forEach (elem);return this;}

      //traps:  

      //target here is *we* - the Yes instance (this), and prop is (string) property being called, a property or method
      get (target, prop) {
        console.log('::get called, for prop: ', prop);
        return function(...args) {
            target.forEach((elem) => {
                if(typeof elem[prop] === 'function'){
                    elem[prop](...args);
                }
            });        

        }        
     }

    set (target, prop, value) {
        console.log('::set called, for prop, val:: ', prop, value);
        target.forEach((elem) => {
            if(typeof elem[prop] !== 'function'){
                elem[prop] = value;
            }
        });            

     }
  }

  /////////
  //End of class Yes definition

  function yes (selector){
    let yInstance = new Yes(selector);
    return new Proxy(yInstance, yInstance);
  }

  //
  Yes.fn = Yes.prototype;
  window.yes = yes;

  //E.fn.forEach = function (elem) {this.nodes.forEach (elem);return this;}



})(window);

//tests:

//These work fine:

//yes('.allDivs').setAttribute('style','color:red');//OK
//yes('.allDivs').style = 'color:blue';//OK

//This does not:
yes('.allDivs').style.color = 'green';//NOT OK

Рабочий код: https://jsfiddle.net/kpion/5wy9uaqL/

Теперь я знаю, почему это не работает, JS вызывает 'get', потому что хочет прочитать свойство .style. Я хотел бы знать, как делать то, что я хочу достичь.

Обратите внимание, что я не могу просто вернуть один div-элемент HTMLElement, потому что я хочу внести изменения во весь массив элементов (отсюда и цикл в обработчиках get / set).

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