Введение
Пожалуйста, имейте в виду, я знаю, почему мое решение не работает, и мой вопрос заключается в том, как заставить его работать, с текущим кодом или совершенно другим способом, если возможно.
Также имейте в виду, что это , а не дубликат В обработчике 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).