2016-08-06 18 views
7

Próbuję zrobić Proxy object z Image, aby przechwycić właściwości, ale nawet przy pustym module obsługi pojawia się komunikat o błędzie.Obiekt proxy nie może zostać dodany do DOM (pułapki też się nie uruchamiają)

TypeError: Argument 1 of Node.appendChild does not implement interface Node.

Obiekt proxy ma działać jako obiekt docelowy, więc trochę mnie to zaskakuje. O ile rozumiem, powinieneś być w stanie to zrobić również z DOM nodes (?).

także: Nie mogę rozpocząć ładowanie obrazu i mieć program obsługi onload wyzwalane, gdy ustawienie właściwości src.

Jak powinienem używać proxy, aby móc "przejąć" na przykład właściwość "src", a poza tym działać jak zwykły obiekt obrazu?

Mój kod

'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

Aktualizacja: Dzięki @Harangue! używając "new" (bah ..) z pewnością uczyniłem obiekt proxy, ale teraz nie jestem w stanie przechwycić ustawienia właściwości. Wydaje się, aby ignorować pułapki całkowicie - przykład:

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

Jak mogę pułapka ustawienie nieruchomość przy pomocy ważnego pełnomocnictwa?

Aktualizacja 2 Z drugiej strony - z wykorzystaniem new z nowego proxy tylko wydają się używać oryginalnego konstruktora . Wszystkie przykłady mogę znaleźć robi nie używać nowego:

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

Korzystanie następnie na szczycie tej new myProxy() tylko wydają się używać oryginalnego konstruktora, który nie jest to, co chcę, ponieważ ignoruje pułapek.

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

Pułapki wydają się działać w moich pierwszych prób, ale pełnomocnik nie zachowuje się zgodnie z oczekiwaniami. To jest takie mylące i takie nowe. Zadowoleni za wszelkie informacje, jak można je rozwiązać (pułapki i zachowanie).

Odpowiedz

3

Nigdy nie lekceważ znaczenia słowa kluczowego 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 

Dzięki pełnomocnikowi skutecznie rozszerzasz obiekt Image. Ale wysłanie samego konstruktora obrazu, a nie zwróconego przez niego węzła DOM, rzeczywiście zabrakłoby potrzebnego appendChild.

+0

Ach tak, ja rzeczywiście zapomnieć nowego słowa kluczowego. ALE, teraz jest nowy problem, ponieważ nie mogę pułapki ustawienia. Czy przeoczyłem tu inną rzecz? zaktualizowałem odpowiedź, podając nowy przykład dla tej sprawy. Dzięki! – bjanes

+0

OTOH .. po przestudiowaniu przykładów nie wydaje się, że jest to powszechny sposób używania proxy. Mam na myśli, wydaje się, że nowy Proxy (...) powinien wystarczyć. Czy jesteś pewny co do potrzeby "nowego"? Wydaje się, że używa on konstruktora obrazu bez przechodzenia przez serwer proxy. ale mogłem źle zrozumieć. :/ – bjanes

+0

@ bjanes Kiedy używam tego kodu, otrzymuję komunikat konsoli, gdy ustawione jest 'src'. Szukasz innego zachowania? – Harangue

1

Jako alternatywę dla pełnomocnika można również zastąpić właściwość na obiekcie siebie, a zatem kontrolować to zachowanie:

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 

A ponieważ ta właściwość jest określona na Image.prototype *, można po prostu rozszerzyć tę klasę oraz zmodyfikować działanie na prototyp dziedziczone klasy

* przynajmniej w FF, trzeba sprawdzić inne przeglądarki

+0

Dzięki! Jest to zdecydowanie alternatywa, którą będę miał na myśli. Nie byłem w stanie przesłonić właściwości, dlatego spojrzałem na proxy. Nie wiedziałem, że możesz to zrobić w ten sposób. miły! – bjanes