javascript - es6 - El objeto proxy no se puede agregar al DOM(las trampas tampoco se activan)
es6 proxy apply (2)
Estoy tratando de hacer que un objeto Proxy
de la Image
atrape propiedades, pero incluso con un controlador vacío recibo un mensaje de error.
TypeError: el argumento 1 de Node.appendChild no implementa el Nodo de interfaz.
Se supone que el objeto proxy actuará como el objeto objetivo, así que esto me desconcierta un poco. Por lo que yo entiendo, también deberías poder hacer esto con los nodos DOM (?).
Además : no puedo comenzar a cargar la imagen y tener el controlador de carga activado al configurar la propiedad src
.
¿Cómo debo usar el Proxy para poder "tomar el control", por ejemplo, la propiedad "src" y hacer que actúe como un objeto de imagen normal?
Mi código
''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
Actualización : ¡Gracias a @Harangue! usar " ahora no puedo atrapar la configuración de las propiedades. Parece ignorar la trampa por completo, por ejemplo: new
" (bah ...) ciertamente hizo que el objeto proxy cobrara vida, pero
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'';
¿Cómo puedo atrapar la configuración de propiedad usando un proxy válido?
Actualización 2 Por otro lado, el uso de new
con el nuevo proxy solo parece usar el constructor original . Todos los ejemplos que puedo encontrar no usan nuevos:
var myProxy = new Proxy(.., ..); // should suffer
Usando entonces encima de eso, new myProxy()
solo parece usar el constructor original, que no es lo que yo quiero, ya que ignora las trampas.
var proxy = new Proxy(Image, {}); //should be sufficent??
var proxy2 = new proxy();
console.log(proxy2); //-> says Image (not proxy..)
Las trampas parecen funcionar en mis primeros intentos, pero el proxy no se comporta como se esperaba. Esto es tan confuso y tan nuevo. Feliz por cualquier entrada, cómo ambos pueden ser resueltos (trampas y comportamiento).
Como alternativa a un proxy, también puede sobrescribir la propiedad en el objeto mismo y, por lo tanto, controlar su comportamiento:
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
Y dado que esta propiedad se define en Image.prototype
*, simplemente puede extender esta clase y modificar el comportamiento en el prototipo de la clase heredada.
* al menos en FF, tiene que comprobar los otros navegadores
Nunca subestimes la importancia de la new
palabra clave. ;)
//--- 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
Con el proxy, extiendes efectivamente el objeto Imagen. Pero al enviar el constructor Image en sí mismo, en lugar del nodo DOM devuelto por él, de hecho le faltaría el appendChild
necesario.