Hiển thị kết quả từ 1 đến 6 / 6
  1. #1
    Tham gia
    29-11-2005
    Location
    Ho Chi Minh
    Bài viết
    629
    Like
    0
    Thanked 3 Times in 2 Posts

    Tệ thật ! __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 :

    PHP Code:
    function Window(idwidthheightcontenturltitleicon){
      
    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(){
        ...
      }
            ..........

    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 :

    PHP Code:
    function Dialog(idwidthheightcontenttitle){
      
    this.__proto__ = new Window(idwidthheightcontent''title'');
      
    this.modal=true;

    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

    PHP Code:
    function Dialog(idwidthheightcontenttitle){
        if(
    this.__proto__this.__proto__ = new Window(idwidthheightcontent''title'');
        else{
           var 
    k=new Window(idwidthheightcontent''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ỉ
    Quote Quote

  2. #2
    Tham gia
    19-05-2009
    Location
    San Jose
    Bài viết
    85
    Like
    0
    Thanked 0 Times in 0 Posts
    Ha ha, bác pro quá, nhìn chóng mặt. Nhưng chắc phải chịu vậy thôi chứ bít sao giờ

  3. #3
    Tham gia
    22-06-2007
    Bài viết
    328
    Like
    0
    Thanked 4 Times in 4 Posts
    bạn có thể tường minh hơn một chút xíu là được.
    <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>
    Được sửa bởi trinhdiep lúc 20:17 ngày 01-06-2009 Reason: Bổ sung bài viết

  4. #4
    Tham gia
    29-11-2005
    Location
    Ho Chi Minh
    Bài viết
    629
    Like
    0
    Thanked 3 Times in 2 Posts
    @ V.O.S : bác quá lời, em chỉ là amateur tập code chơi thôi. Không qua trường lớp nào đâu.

    @ 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 :

    PHP Code:
    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 :

    PHP Code:
    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(); 
    Lúc này cả Tom và Jerry sẽ đều nói ra được tên mình.

    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

    PHP Code:
    function Dialog(idwidthheightcontenttitle){
      
    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.
    Được sửa bởi sacroyant lúc 21:05 ngày 01-06-2009

  5. #5
    Tham gia
    22-06-2007
    Bài viết
    328
    Like
    0
    Thanked 4 Times in 4 Posts
    nói cung thì bạn vẫn sai
    >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;
    }

  6. #6
    Tham gia
    29-11-2005
    Location
    Ho Chi Minh
    Bài viết
    629
    Like
    0
    Thanked 3 Times in 2 Posts
    Quote Được gửi bởi trinhdiep View Post
    nói cung thì bạn vẫn sai
    >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;
    }
    Sử dụng call như kiểu của bạn cũng đã được nhắc đến ở đây.

    Đúng là cách viết

    PHP Code:
    this.prototype=new Window(); 
    sẽ sinh lỗi. Phải viết bên ngoài hàm khởi tạo Dialog như trong trường hợp Tom & Jerry mới chính xác.
    PHP Code:
    function Dialog(idwidthheightcontenttitle){
    ...
    }
    Dialog.prototype=new Window(); 
    Cảm ơn bạn

Bookmarks

Quy định

  • Bạn không thể tạo chủ đề mới
  • Bạn không thể trả lời bài viết
  • Bạn không thể gửi file đính kèm
  • Bạn không thể sửa bài viết của mình
  •