无法将代理对象添加到 DOM(陷阱也不会触发)
Proxy object cannot be added to DOM (traps doesn't trigger either)
我正在尝试制作 Image
的 Proxy
object 来捕获属性,但即使使用空处理程序,我也会收到错误消息。
TypeError: Argument 1 of Node.appendChild does not implement interface Node.
假设代理对象充当目标对象,所以这让我有点困惑。据我了解,您也应该能够使用 DOM nodes (?).
来做到这一点
也:设置src
属性.[=25 时,我无法开始加载图像并触发onload
处理程序=]
我应该如何使用 Proxy 以便我可以 "take over" 例如 "src" 属性 并且让它像普通图像对象一样工作?
我的代码
'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
更新:感谢@Harangue! 使用“new
”(呸..)确实使代理对象活跃起来,但是现在我无法捕获属性设置。它似乎完全忽略了陷阱-示例:
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';
如何使用有效的代理设置 属性 设置?
更新 2 另一方面 - 使用 new
和 new 代理似乎只使用 原始构造函数。我能找到的所有示例都 not 使用 new:
var myProxy = new Proxy(.., ..); // should suffer
在此基础上使用 then new myProxy()
似乎只使用了原始构造函数,这不是我想要的,因为它忽略了陷阱。
var proxy = new Proxy(Image, {}); //should be sufficent??
var proxy2 = new proxy();
console.log(proxy2); //-> says Image (not proxy..)
这些陷阱似乎在我的第一次尝试中起作用,但代理的行为并不像预期的那样。这太令人困惑了,太新了。对于如何解决这两个问题(陷阱和行为)的任何输入都很高兴。
永远不要低估 new
关键字的重要性。 ;)
//--- 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
使用代理,您可以有效地扩展 Image 对象。但是发送 Image 构造函数本身,而不是它返回的 DOM 节点,确实会缺少所需的 appendChild
.
作为代理的替代方法,您还可以覆盖对象本身的 属性,从而控制它的行为:
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
并且由于此 属性 是在 Image.prototype
* 上定义的,您可以简单地扩展此 class 并修改继承 Class[ 原型的行为=12=]
*至少在FF中,要检查其他浏览器
我正在尝试制作 Image
的 Proxy
object 来捕获属性,但即使使用空处理程序,我也会收到错误消息。
TypeError: Argument 1 of Node.appendChild does not implement interface Node.
假设代理对象充当目标对象,所以这让我有点困惑。据我了解,您也应该能够使用 DOM nodes (?).
来做到这一点也:设置src
属性.[=25 时,我无法开始加载图像并触发onload
处理程序=]
我应该如何使用 Proxy 以便我可以 "take over" 例如 "src" 属性 并且让它像普通图像对象一样工作?
我的代码
'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
更新:感谢@Harangue! 使用“现在我无法捕获属性设置。它似乎完全忽略了陷阱-示例:new
”(呸..)确实使代理对象活跃起来,但是
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';
如何使用有效的代理设置 属性 设置?
更新 2 另一方面 - 使用 new
和 new 代理似乎只使用 原始构造函数。我能找到的所有示例都 not 使用 new:
var myProxy = new Proxy(.., ..); // should suffer
在此基础上使用 then new myProxy()
似乎只使用了原始构造函数,这不是我想要的,因为它忽略了陷阱。
var proxy = new Proxy(Image, {}); //should be sufficent??
var proxy2 = new proxy();
console.log(proxy2); //-> says Image (not proxy..)
这些陷阱似乎在我的第一次尝试中起作用,但代理的行为并不像预期的那样。这太令人困惑了,太新了。对于如何解决这两个问题(陷阱和行为)的任何输入都很高兴。
永远不要低估 new
关键字的重要性。 ;)
//--- 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
使用代理,您可以有效地扩展 Image 对象。但是发送 Image 构造函数本身,而不是它返回的 DOM 节点,确实会缺少所需的 appendChild
.
作为代理的替代方法,您还可以覆盖对象本身的 属性,从而控制它的行为:
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
并且由于此 属性 是在 Image.prototype
* 上定义的,您可以简单地扩展此 class 并修改继承 Class[ 原型的行为=12=]
*至少在FF中,要检查其他浏览器