2012-08-07 62 views
2

我需要一個自定義的面板,它總是在指定位置(例如總是右下角)保持一個按鈕。ExtJS中的浮動元件

該位置需要儘可能靈活(但靜態定義)。從理論上講,它可能在面板中的任何地方(左中心,中心,左+ 10px &底部 - 50px,...),它需要「免費」。所以它不能被任何其他元素包圍,比如工具欄(浮動...)。

我已經實現了這一點,但還是有它的錯誤,我不知道如果沒有沒有更好的辦法來做到這一點:

http://jsfiddle.net/suamikim/uQDDu/1/

Ext.onReady(function() { 
    var floatBtn, toolbar, win; 

    Ext.define('PanelWithFloatButton', { 
     extend: 'Ext.panel.Panel', 

     items: [], 

     constructor: function(config) { 
      // region private variables (no getter & setter available) 
      this._floatingBtn = undefined; 
      // endregion private variables 

      // region private events 
      this._afterRender = function() { 
       this._floatingBtn.show(); 
      }; 
      // endregion private events 

      // region private functions 
      this._updateFloatBtnPos = function() { 
       var bodySize = this.body.getSize(), 
        btnSize = this._floatingBtn.getSize(); 

       if (this._floatingBtn && this._floatingBtn.el) { 
        this._floatingBtn.setPosition(bodySize.width - btnSize.width - 10, bodySize.height - btnSize.height - 10); 
       } 
      }; 
      // endregion private functions 

      return this.callParent(arguments); 
     }, 

     initComponent: function() { 
      // Create floating button 
      this._floatingBtn = Ext.create('Ext.button.Button', { 
       text: 'Floating button, always bottom-right...', 
       floating: true, 
       style: { 
        'z-index': 1 
       } 
      }); 

      // Add items 
      this.add(this._floatingBtn); 

      // Add listeners 
      this.addListener('afterrender', this._afterRender, this); 
      this.addListener('resize', this._updateFloatBtnPos, this); 

      this.addListener('beforedestroy', function() { 
       this._floatingBtn.destroy(); 
      }, this); 

      this.addListener('beforehide', function() { 
       this._floatingBtn.hide(); 
      }, this); 

      this.addListener('show', function() { 
       this._floatingBtn.show(); 
      }, this); 

      return this.callParent(arguments); 
     } 
    }); 

    btnParent = Ext.create('PanelWithFloatButton', { 
     title: 'Button-Parent', 
     layout: { 
      type: 'vbox', 
      align: 'stretch' 
     } 
    }); 

    toolbar = Ext.create('Ext.toolbar.Toolbar', { 
     region: 'north', 
     defaultType: 'button', 
     items: [{ 
       text: 'Toggle visibility of Button-Parent', 
       handler: function() { 
        try { 
         btnParent.setVisible(!btnParent.isVisible()); 
        } catch (e) { 
         // btnParent is already destroyed 
        } 
       } 
      }, '|', { 
       text: 'Destroy Button-Parent', 
       handler: function() { 
        try { 
         btnParent.up().remove(btnParent); 
        } catch (e) { 
         // btnParent is already destroyed 
        } 
       } 
      }, '|', { 
       text: 'Add subpanel', 
       handler: function() { 
        btnParent.add(Ext.create('Ext.panel.Panel', { 
         title: 'Sub-Panel', 
         height: 200, 
         style: { 
          'z-index': 2 
         } 
        })); 
       } 
     }] 
    }); 

    win = Ext.create('Ext.window.Window', { 
     width: 500, 
     height: 500, 
     layout: 'border', 
     items: [ 
      toolbar, 
      { 
       xtype: 'panel', 
       region: 'center', 
       layout: 'fit', 
       items: btnParent 
     }] 
    }).show(); 
}); 

一些具體問題:

1.) 爲什麼只有在窗口第一次手動移動而不是從頭開始移動之後,按鈕纔會正確定位?

2.) 有沒有更好的方法讓按鈕始終保持在它的位置比捕獲調整大小事件和手動重新計算?

3.) 有沒有辦法讓按鈕自動顯示/隱藏/銷燬它的父面板像正常的子項目(不浮動)呢?

4.) 有沒有辦法自動隱藏按鈕父項的其他子項下的浮動按鈕?通過按「添加子面板」添加2個子面板後,它應該在第二個面板下自動隱藏。 我認爲這可以通過設置z-index輕鬆實現,但是這似乎被Ext-Framework覆蓋,因爲當我查看DOM時,會在元素級設置一個真正的大型z-index(> 19000)這不能用css輕鬆覆蓋。

5.) 我的方法(擴展面板,創建按鈕並在initComponent中添加偵聽器,...)基本上正確我要達到的目標還是在我的代碼中存在任何主要缺陷?

感謝&問候,

邁克

+0

不知道我理解完全你的問題,但沒有任何特別的理由作出這樣的按鈕浮動?我可能會在面板上使用絕對佈局,並將按鈕放在我需要的座標上。 – 2012-08-07 16:53:32

+1

你有沒有考慮過使用CSS類擴展?包括定位在內的佈局通常最好由Stylesheets處理。也許在CSS3上發佈一些提示? – Eric 2012-08-08 18:13:23

+0

@AlexanderTokarev:我需要添加除按鈕之外的其他項目的可能性(參見jsfiddle-example並按下工具欄中的「添加子面板」按鈕)。而且這些項目的佈局也需要改變。在這個例子中,它是一個hbox佈局,但它也可以是任何其他的佈局... – suamikim 2012-08-09 05:22:26

回答

0

這是否對你的工作? http://jsfiddle.net/dbrin/XuQg4/21/

+0

對不起,但這不適合我。如上所述,按鈕需要在面板內「自由」(不包圍任何東西),並且該位置可以在任何地方(同時也水平和垂直居中)。 無論如何感謝您的輸入! – suamikim 2012-08-09 05:29:42

1

試試這個http://jsfiddle.net/uQDDu/13/

的Javascript

... 
    Line 48 this.addListener('afterrender', this._afterRender, this); 
    Line 49 this.addListener('afterlayout', this._updateFloatBtnPos, this); //added 
    ...