2016-12-04 115 views
0

我试图拦截HTMLImageElement的图像()构造函数:拦截的Javascript HTMLImageElement构造

https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/Image

var origImgConstr = HTMLImageElement.prototype.constructor;             
Image = function(width, height) {                    
    console.log('image constructor!');                   
    return new origImgConstr(arguments);                   
}; 

,但我得到

Uncaught TypeError: Illegal constructor(…) 

同样的结果,如果我有HTMLImageElement取代Image

我错过了什么?

+0

这是专门'Image'要截距? –

+0

是的。它是否特别? – rlib

+1

'HTMLImageElement'是一个接口,而不是一个类。 –

回答

3

ImageHTMLImageElement的构造函数功能不一样。您无法跨越可靠的跨浏览器的后者。

前言:重写Image不会拦截由HTML解析器img元素或document.createElement调用的创建。据我所知,这是不可能的跨浏览器。你可以做的是捕获所有图像,因为它们通过mutation observer添加到文档中。但是这只是在被添加而不是创建的时候捕捉到它们。

但是:你说这是Image,具体而言,要覆盖,因此替换它之前采取的Image原始值,并使用它。

例子:

var originalImage = Image; 
 
Image = function(width, height) { 
 
    var result; 
 
    console.log("Intercepted"); 
 
    switch (arguments.length) { 
 
     case 0: 
 
     result = new originalImage(); 
 
     break; 
 
     case 1: 
 
     result = new originalImage(width); 
 
     break; 
 
     default: 
 
     result = new originalImage(width, height); 
 
     break; 
 
    } 
 
    return result; 
 
}; 
 

 
var img = new Image(); 
 
img.src = "https://i.stack.imgur.com/rQIK0.jpg?s=64&g=1"; 
 
document.body.appendChild(img); 
 
img = new Image(32, 20); 
 
img.src = "https://i.stack.imgur.com/rQIK0.jpg?s=64&g=1"; 
 
document.body.appendChild(img);

在ES2015,如果这是一个选择:

const originalImage = Image; 
 
Image = function(...args) { 
 
    console.log("Intercepted"); 
 
    return new originalImage(...args); 
 
}; 
 

 
let img = new Image(); 
 
img.src = "https://i.stack.imgur.com/rQIK0.jpg?s=64&g=1"; 
 
document.body.appendChild(img); 
 
img = new Image(32, 20); 
 
img.src = "https://i.stack.imgur.com/rQIK0.jpg?s=64&g=1"; 
 
document.body.appendChild(img);

+0

'new originalImage(width,height)'不能可靠地工作吗?我想他们会认为'undefined'是一个非数字。 – 2016-12-04 19:03:19

+1

@squint:这就是我的防守。 :-)我不知道*实现不会看到实际收到的参数的数量,所以......(并且感谢天堂ES2015的传播符号,在ES2015中这将是一个很好的清晰的图像= ...(function)(... args){console.log(“Intercepted”); return new originalImage(... args);};') –

+0

*“...感谢ES2015传播符号的天堂......”以及许多其他增加的内容开始使本机语法实际上令人愉快地使用。 – 2016-12-04 19:06:53