代理对象不能添加到DOM(陷阱不会触发)

我试图让一个Proxy对象的Image陷阱属性,但即使与一个空的处理程序,我收到一条错误消息。

TypeError:Node.appendChild的参数1没有实现接口节点。

代理对象被认为是目标对象,所以这让我很困惑。 据我所知,你应该可以做到这一点与DOM节点(?)。

另外 :我无法开始加载图像,并在设置src属性时触发onload处理程序。

我应该如何使用代理服务器,以便“接管”例如“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

永远不要低估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 *上定义的,因此您可以简单地扩展此类并修改继承类的原型上的行为

*至少在FF中,必须检查其他浏览器

链接地址: http://www.djcxy.com/p/92791.html

上一篇: Proxy object cannot be added to DOM (traps doesn't trigger either)

下一篇: Converting image X,Y coordinates to longitude and latitude?