10/10/2018, 09:38
__proto__ : IE củ chuối quá !
Mấy hôm trước rảnh rỗi ngồi code lại trang chủ, tình cờ phát hiện thêm 1 điểm đáng chán của IE.
Chả là tớ gom các đối tượng cửa sổ giả lập vào 1 class để dễ quản lý theo tầng. Class ấy có dạng thế này :
Sau đó tớ nghĩ đến 1 số hộp thoại nhận dữ liệu đơn giản, nó hiển thị ở tầng trên như 1 cửa sổ, nhưng không phải là cửa sổ, nó cũng di chuyển được nhưng không thể thu nhỏ, không chiếm chỗ trong stack phân tầng, không thể chứa 1 inline frame... Túm lại nó khá giống các cửa sổ nhưng không phải là cửa sổ. Nếu đặt ra các thuộc tính để phân biệt thì rườm rà code, nếu viết riêng 1 class khác thì không lợi dụng được những điểm tương đồng giữa 2 lớp. Thế nên tớ chọn giải pháp viết 1 class Dialog sao chép toàn bộ các methods và properties của class Window sang, như sau :
Rất tuyệt, việc gán mọi thuộc tính và phương thức từ lớp này sang lớp kia với __proto__ khiến cho code gọn không thể hơn được. Chrome, FireFox, Opera đều chạy ngon lành.
Ấy thế mà thằng IE đếch hiểu ! Nó bắt mình phải tạo 1 đối tượng trung gian rồi gán từng Method, từng Property qua Dialog, khiến cho class trở nên như vầy
Nhìn chuối không thể tả ! Các bác có giải pháp nào hay hơn để xử lý tình huống trên cho MSIE không nhỉ
Chả là tớ gom các đối tượng cửa sổ giả lập vào 1 class để dễ quản lý theo tầng. Class ấy có dạng thế này :
PHP Code:
function Window(id, width, height, content, url, title, icon){
this.id=id;
this.width=width||200;
this.height=height||100;
this.title=title;
this.content=content||';
this.icon=icon||';
this.url=url||';
this.state=0;
this.zIndex=0;
this.top=0;
this.left=0;
this.cursorX=0;
this.cursorY=0;
this.topToPoint=0;
this.leftToPoint=0;
this.iconPath=';
this.modal=false;
this.draggable=false;
this.minimizable=false;
this.getState=function(){return this.state}
this.setOrder=function(z){
...
}
this.init=function(){
...
}
this.display=function(){
...
}
this.focus=function(){
...
}
..........
}
PHP Code:
function Dialog(id, width, height, content, title){
this.__proto__ = new Window(id, width, height, content, ', title, ');
this.modal=true;
}
Ấy thế mà thằng IE đếch hiểu ! Nó bắt mình phải tạo 1 đối tượng trung gian rồi gán từng Method, từng Property qua Dialog, khiến cho class trở nên như vầy
PHP Code:
function Dialog(id, width, height, content, title){
if(this.__proto__) this.__proto__ = new Window(id, width, height, content, ', title, ');
else{
var k=new Window(id, width, height, content, ', title, ');
this.drop=k.drop;
this.setPosition=k.setPosition;
this.moving=k.moving;
this.startMove=k.startMove;
this.makeDraggable=k.makeDraggable;
this.getCursorPos=k.getCursorPos;
this.getWinsize=k.getWinsize;
this.setState=k.setState;
this.getState=k.getState;
this.setOrder=k.setOrder;
this.getOrder=k.getOrder;
this.close=k.close;
this.focus=k.focus;
this.display=k.display;
this.init=k.init;
this.draggable=k.draggable;
this.minimizable=k.minimizable;
this.id=id;
this.width=width;
this.height=height;
...
}
this.modal=true;
}
Nhìn chuối không thể tả ! Các bác có giải pháp nào hay hơn để xử lý tình huống trên cho MSIE không nhỉ
Bài liên quan
<code>
=======
function Dialog(id, width, height, content, title){
this.modal=true;
}
Dialog.prototype= new Window(id, width, height, content, '', title, '');
=======
</code>
mình nghĩ __proto__ chỉ là một shortcut
[=========> Bổ sung bài viết <=========]
oh. nhầm nhầm. nè không ổn lắm
<code>
=======
function Dialog(id, width, height, content, title){
var proto = new Window(id, width, height, content, '', title, '');
proto.modal=true;
return proto;
}
=======
</code>
@ trinhdiep :
Cảm ơn bạn có gợi ý hay. Bạn chỉ gần đúng rồi. Mình sửa lại một chút là được.
Theo cách nghĩ ban đầu của mình, Dialog không phải là lớp con của Window, tuy chúng gần giống nhau. Tương tự mèo và chuột chứ không phải mèo và động vật. Viết theo cách bạn nêu sẽ sinh lỗi, cụ thể như ví dụ sau :
function Mouse(name){
this.name=name;
this.talk=function(){
alert('My name is '+this.name);
}
}
function Cat(name){}
Cat.prototype=new Mouse(name);
var Jerry=new Mouse('Jerry');
Jerry.talk();
var Tom=new Cat('Tom');
Tom.talk();
Vì ở dòng Cat.prototype=new Mouse(name);, tham số name là undefined. Cho nên Jerry sẽ nói được tên nó còn Tom thì không.
Nhưng code sẽ chính xác khi được sửa thành :
function Mouse(name){
this.name=name;
this.talk=function(){
alert('My name is '+this.name);
}
}
function Cat(name){this.name=name;} // định nghĩa lớp Cat
Cat.prototype=new Mouse(); // gán prototype từ Mouse sang Cat
var Jerry=new Mouse('Jerry');
Jerry.talk();
var Tom=new Cat('Tom');
Tom.talk();
Vậy là tớ đã biết cách viết lại class Dialog, sao cho nó là một class khác biệt mà lại có được những methods và properties như class Window. Một cách viết chung cho cả trình duyệt chuẩn lẫn trình duyệt củ chuối
function Dialog(id, width, height, content, title){
this.id=id;
this.width=width;
this.height=height;
this.title=title;
this.content=content;
this.icon='';
this.url='';
this.modal=true;
this.prototype=new Window();
}
Bổ sung :
__proto__ là một thuộc tính liên quan đến hiện thể, khác biệt với prototype là thuộc tính liên quan đến lớp đối tượng. Khi tạo ra một hiện thể, chẳng hạn Jerry=new Mouse, thì thuộc tính prototype của class Mouse sẽ được sao chép sang thuộc tính __proto__ của Jerry, giúp cho Jerry có được mọi khả năng của lớp Mouse.
>Vì ở dòng Cat.prototype=new Mouse(name);, tham số name là undefined. Cho nên Jerry sẽ nói được tên nó còn Tom thì không.
cái nè mình đã nói là nhầm mà.
>this.prototype=new Window();
cái nè nó sẽ không hiểu là prototype. prototype không sử dụng như vầy.
nghĩ linh tinh lại ra cũng khá hay.
function Dialog(id, width, height, content, title){
Window.call(this,[id, width, height, content, '', title, '']);
this.modal=true;
}
Đúng là cách viết
this.prototype=new Window();
function Dialog(id, width, height, content, title){
...
}
Dialog.prototype=new Window();