javascript ExtJS 中的浮动组件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11840417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 14:30:37  来源:igfitidea点击:

Floating components in ExtJS

javascriptextjsextjs4

提问by suamikim

i need a custom panel which always holds a button at a specified position (e.g. always bottom-right).

我需要一个自定义面板,它始终在指定位置(例如,始终在右下角)保持一个按钮。

The position needs to be as flexible as possible (but statically defined). Theoretically it could be everywhere within the panel (left-centered, center-center, left + 10px & bottom - 50px, ...) and it needs to be "free". So it must not be surrounded by any other element like a toolbar (floating...).

位置需要尽可能灵活(但静态定义)。理论上它可以在面板内的任何地方(左居中,居中,左 + 10 像素和底部 - 50 像素,...)并且它需要是“自由的”。所以它不能被任何其他元素包围,比如工具栏(浮动...)。

I've already achieved this but there's still a bug in it and i'm not sure if there ain't no better way to do it:

我已经实现了这一点,但它仍然存在一个错误,我不确定是否没有更好的方法来做到这一点:

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

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();
});  

Some specific questions:

一些具体问题:

1.) Why is the button positioned correctely only after the window has been moved manualy for the first time and not right from the start?

1.) 为什么第一次手动移动窗口后按钮才正确定位,而不是从一开始就定位正确?

2.) Is there a better way to make the button always stay at it's position than by catching the resize-event and recalculating manually?

2.) 有没有比捕捉调整大小事件并手动重新计算更好的方法让按钮始终保持在它的位置?

3.) Is there a way to make the button automatically show/hide/destroy with it's parent-panel like normal sub-items (not floating) do?

3.) 有没有办法让按钮像普通子项(不浮动)一样自动显示/隐藏/销毁它的父面板?

4.) Is there a way to automatically hide the floating button under other child-items of the buttons parent? After adding 2 more subpanels by pressing "Add subpanel" it should hide automatically under the second panel. I thought that this could be easily achieved by setting the z-index but this seems to be overwritten by the Ext-Framework because when i look at the DOM there is a realy big z-index (> 19000) set at element-level which can't be overwritten that easy with css.

4.) 有没有办法自动隐藏按钮父项的其他子项下的浮动按钮?通过按“添加子面板”添加另外两个子面板后,它应该会自动隐藏在第二个面板下。我认为这可以通过设置 z-index 轻松实现,但这似乎被 Ext-Framework 覆盖,因为当我查看 DOM 时,在元素级别设置了一个非常大的 z-index (> 19000)不能用 css 轻易覆盖。

5.) Is my approach (Extending the panel, creating the button and adding listeners in initComponent, ...) basically correct for what i want to achieve or are there any major flaws in my code?

5.) 我的方法(扩展面板,创建按钮并在 initComponent 中添加侦听器,...)对于我想要实现的目标是否基本正确,或者我的代码是否有任何重大缺陷?

Thanks & best regards,

谢谢和最好的问候,

Mike

麦克风

回答by Dart

Try this http://jsfiddle.net/uQDDu/13/

试试这个http://jsfiddle.net/uQDDu/13/

Javascript

Javascript

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

回答by dbrin