A proxy object cannot be added to the DOM (traps also do not start)

I am trying to make a Proxy object Image to catch properties, but even with an empty handler I get an error message.

TypeError: argument 1 of Node.appendChild does not implement the Node interface.

The proxy object should act as the target, so this puzzles me a bit. As far as I understand, you should do this using DOM nodes (?).

Also : I cannot start loading the image and start the onload handler when setting the src property.

How to use a proxy server so that I can "take over", for example, the "src" property, and otherwise it will act like a regular image object?

My code

 'use strict'; //--- normal image use --- var imgNormal = new Image(); imgNormal.onload = function(){ console.log('Normal loaded OK'); document.body.appendChild(imgNormal); }; imgNormal.src = 'https://i.imgur.com/zn7O7QWb.jpg'; //--- proxy image --- var imgProxy = new Proxy(Image, { // I also tried with 'new Image()' and HTMLImageElement set: function(a,b,c,d){ console.log('set '+b); return Reflect.set(a,b,c,d); } }); imgProxy.onload = function(){ console.log('Proxy loaded OK'); document.body.appendChild(imgProxy); }; imgProxy.src = 'https://i.imgur.com/zn7O7QWb.jpg'; document.body.appendChild(imgProxy); // double-up to demo error 

Update : thanks @Harangue! using " new " (bang ..) certainly launched a proxy object, but Now I can not capture the property setting. It seems to completely ignore the trap - example:

 var proxy = new Proxy(Image, { set: function(a,b,c,d){ console.log('set '+b); // doesn't show return Reflect.set(a,b,c,d); } }); var imgProxy = new proxy(); imgProxy.onload = function(){ console.log('Proxy loaded OK'); document.body.appendChild(imgProxy); }; imgProxy.src = 'https://i.imgur.com/zn7O7QWb.jpg'; 

How can I catch a property parameter using a valid proxy?

Update 2 On the other hand, using new with a new proxy seems to use the original constructor. All the examples I can find do not use new:

 var myProxy = new Proxy(.., ..); // should suffer 

Using then on top of this new myProxy() seems only to use the original constructor, which is not what I want, as it ignores traps.

 var proxy = new Proxy(Image, {}); //should be sufficent?? var proxy2 = new proxy(); console.log(proxy2); //-> says Image (not proxy..) 

The traps seem to work in my first attempts, but the proxy does not behave as expected. It is so confusing and so new. Rejoice over any contribution, how both can be resolved (traps and behavior).

+7
javascript javascript-objects ecmascript-6 es6-proxy
source share
2 answers

Never underestimate the importance of the new keyword.;)

 //--- proxy image --- var imgProxy = new Proxy(Image, { // I also tried with 'new Image()' set: function(a,b,c,d){ console.log('set '+b); return Reflect.set(a,b,c,d); } }); imgProxy.src = 'https://i.imgur.com/zn7O7QWb.jpg'; document.body.appendChild(new imgProxy); // double-up to demo error 

With a proxy server, you effectively extend the Image object. But sending the Image constructor itself, and not the DOM Node returned by it, will indeed lack the necessary appendChild .

+3
source share

As an alternative to the proxy server, you can also overwrite the property of the object itself and, therefore, control its behavior:

 function findDescriptor(obj, prop){ if(obj != null){ return Object.hasOwnProperty.call(obj, prop)? Object.getOwnPropertyDescriptor(obj, prop): findDescriptor(Object.getPrototypeOf(obj), prop); } } var img = new Image(); var {get, set} = findDescriptor(img, "src"); Object.defineProperty(img, "src", { configurable: true, enumerable: true, //get: get, //keep behaviour get(){ //overwrite getter var v = get.call(this); //call the original getter console.log("get src:", v, this); return v; }, //same for setter set(v){ console.log("set src:", v, this); //modify value before applying it to the default setter v = v.toLowerCase(); set.call(this, v); } }); img.src = "FileWithUppercaseLetters.jpg"; //setter img.src; //trigger getter 

And since this property is defined in Image.prototype *, you can simply extend this class and change the behavior on the prototype of the inherited class

* at least in FF, you need to check other browsers

+1
source share

All Articles