2016-08-06 2 views
7

Ich versuche, eine von Image zum Trap-Eigenschaften, aber auch mit einem leeren Handler bekomme ich eine Fehlermeldung.Proxy-Objekt kann nicht zu DOM hinzugefügt werden (Traps triggert auch nicht)

Das Proxy-Objekt soll als das Zielobjekt fungieren, so dass dies mich ein wenig verwirrt. Soweit ich weiß, sollten Sie dies auch mit DOM nodes (?) Tun können.

Auch: Ich kann nicht gestartet werden, das Bild zu laden und haben die onload Handler ausgelöst, wenn die src Eigenschaft festlegen.

Wie sollte ich den Proxy verwenden, damit ich zum Beispiel die "src" -Eigenschaft übernehmen kann und sie sich sonst wie ein normales Bildobjekt verhält?

Mein 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

aktualisieren: Dank @Harangue! mit "new" (bah ..) sicherlich das Proxy-Objekt zum Leben erweckt, aber jetzt kann ich nicht die Einstellung von Eigenschaften abfangen. Es scheinen die Falle vollständig zu ignorieren - Beispiel:

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';

Wie kann ich Falle der Einstellung der Eigenschaft einen gültigen Proxy verwenden?

Update 2 Auf der anderen Seite - new mit den neuen Proxy nur das ursprüngliche Konstruktor zu verwenden scheinen. Alle Beispiele, die ich finden kann, tut nicht neue Verwendung:

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

Mit dann oben auf dieser new myProxy() scheinen nur den ursprünglichen Konstruktor zu verwenden, das ist nicht, was ich will, wie es die Fallen ignoriert.

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

Die Fallen scheint in meinen ersten Versuchen zu arbeiten, aber der Proxy nicht wie erwartet verhalten. Das ist so verwirrend und so neu. Ich freue mich über jede Eingabe, wie beides gelöst werden kann (Fallen und Verhalten).

Antwort

3

Unterschätzen Sie niemals die Wichtigkeit des Schlüsselworts 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 

Mit dem Proxy erweitern Sie das Image-Objekt effektiv. Wenn der Image-Konstruktor selbst und nicht der von ihm zurückgegebene DOM-Knoten gesendet wird, fehlt in der Tat die erforderliche appendChild.

+0

Ah ja zu überprüfen, ich habe in der Tat vergessen, das neue Schlüsselwort. ABER, es gibt jetzt ein neues Problem, da ich die Einstellung nicht abfangen kann. Habe ich hier noch etwas übersehen? Ich aktualisierte die Antwort mit einem neuen Beispiel für diesen Fall. Vielen Dank! – bjanes

+0

OTOH .. nach dem Studium der Beispiele scheint es nicht, dass dies der übliche Weg ist, einen Proxy zu verwenden. Ich meine, es scheint, dass ein neuer Proxy (...) ausreichen sollte. Sind Sie sicher, dass Sie "neu" brauchen? Es scheint nur den Konstruktor des Bildes zu verwenden, ohne den Proxy zu durchlaufen. aber ich könnte es falsch verstehen. :/ – bjanes

+0

@bjanes Wenn ich diesen Code verwende, erhalte ich immer eine Konsolenmeldung, wenn 'src' gesetzt ist. Suchst du nach einem anderen Verhalten? – Harangue

1

Als Alternative zu einem Proxy Sie auch die Eigenschaft auf dem Objekt selbst überschreiben können und es somit das Verhalten steuern:

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 

Und da diese Eigenschaft auf den Image.prototype * definiert ist, können Sie einfach diese Klasse erweitern und ändern Sie das Verhalten auf dem Prototyp die geerbte Klasse

* zumindest in FF, haben die anderen Browsern

+0

Danke! Dies ist definitiv eine Alternative, die ich mir vorstellen werde. Ich konnte Eigenschaften nicht überschreiben, weshalb ich Proxies betrachtete. Ich wusste nicht, dass du es so machen kannst. nett! – bjanes

Verwandte Themen