javascript - 如何动态更改悬停和按下的 extjs 按钮的背景

标签 javascript jquery css extjs extjs4

你好,

我需要能够动态更改按钮不同状态(正常、悬停、按下)的背景颜色。

到目前为止,我想到的内容如下: http://jsfiddle.net/suamikim/c3eHh/

Ext.onReady(function() {
    function updateBackground() {
        var theWin = win || this, // neccessary because of the call from the afterrender-event
            btn = theWin.down('#btnTest'),
            bckgr = theWin.down('#btnBckgr').getValue(),
            bckgrHover = theWin.down('#btnBckgrHover').getValue(),
            bckgrPressed = theWin.down('#btnBckgrPressed').getValue();

        // Set normal background as button-style
        // Should be ok
        $('#' + btn.id).css('background', bckgr);

        // Toggle background when hover-state changes
        // Are there any downsides if this function gets called everytime the updateBackground-method is called? Do i have to dispose anything before binding the functions again?
        $('#' + btn.id).hover(function() {
                $('#' + btn.id).css('background', bckgrHover);
            }, function() {
                $('#' + btn.id).css('background', bckgr);
            }
        );

        // Set the background for pressed button as document style
        // Problems:
        //     - Pollutes the document-header if called multiple times...
        //     - Background does not change anymore on hover for pressed button because of the !important, but without important it wouldn't show the pressed background at all...
        $('<style type="text/css"> #' + btn.id + '.x-btn-pressed { background: ' + bckgrPressed + ' !important } </style>').appendTo('head');
    };

    // Create a window with the propertygrid
    var win = Ext.create('Ext.window.Window', {
        width: 800,
        height: 200,
        layout: 'fit',

        tbar: {
            defaultType: 'textfield',
            defaults: {
                listeners: {
                    blur: updateBackground
                }
            },
            items: [
                'Background (CSS):', { itemId: 'btnBckgr', value: '#77ABD8' },
                'Background hover (CSS):', { itemId: 'btnBckgrHover', value: '#CC1C1C' },
                'Background pressed (CSS):', { itemId: 'btnBckgrPressed', value: '#7D4FC6' }
            ]
        },

        items: [{
            xtype: 'button',
            itemId: 'btnTest',
            text: 'test button',
            enableToggle: true
        }],

        listeners: {
            'afterrender': updateBackground
        }
    }).show();
});

这基本上有效,但我还有一些问题:

1)

每次调用updateBackground方法时都调用jquery的hover函数可以吗?

根据 jquery-doc ( http://api.jquery.com/hover/ ),此函数将 2 个给定函数绑定(bind)到给定元素的 mouse-enter- 和 mouse-leave-events。

这是否意味着每次我调用它时它都会绑定(bind)新函数,或者它是否更新已经绑定(bind)的函数,或者它是否在绑定(bind)新函数之前自动处理已经绑定(bind)的函数...

简而言之:在将新函数与 $.hover 绑定(bind)之前我是否必须处理任何内容?

2)

我将按下状态的样式设置为文档样式,这意味着如果经常调用 updateBackground 函数(每当其中一个文本字段在我的测试用例中触发模糊事件时,文档标题就会被污染) ).

有没有更好的方法来实现相同的目标,或者我可以在添加新样式之前删除已经设置的样式吗?

3)

由于按下样式中的 !important-flag,如果按下按钮,悬停状态的背景不会出现。我不能只是删除这个标志,因为如果没有它,按下状态的背景将无法正确显示...... 有什么解决办法吗?

总的来说,我愿意接受关于如何以完全不同的方式解决这个问题的每一个建议。

谢谢

米克


编辑:

上面的代码只是一个例子。实际上,我也需要能够更改除按钮之外的其他外部控件的背景属性(面板、复选框等),但我认为我可以自己为其他控件采用按钮的工作解决方案。

请记住这一点,不要在按钮上过多指定答案。它应该尽可能通用......

最佳答案

使用一些更具体的CSS选择器,您可以利用Ext的pressedCls和overCls配置。 http://docs.sencha.com/ext-js/4-1/#!/api/Ext.button.Button-cfg-pressedCls http://docs.sencha.com/ext-js/4-1/source/Button2.html#Ext-button-Button-cfg-overCls

.x-btn.my-over {
    background: blue;
}
/*Ext is not consistent */
.x-btn.x-btn-my-pressed {
    background: red;
}


new Ext.button.Button({
    overCls : 'my-over',
    pressedCls : 'my-pressed',
    //needs to be true to have the pressed cls show
    enableToggle : true,
    text : 'My button',
    renderTo : Ext.getBody(),
})
<小时/>

编辑以获得更加动态、通用的解决方案

    Ext.define('DynamicStyleState', {
    alias : 'plugin.dynamicStyleState',
    extend : Ext.AbstractPlugin,
    /**
     * @cfg
     */
    elementProperty : 'el',

    /**
     * @property
     */
    pressed : false,

    init : function(component) {
        this.component = component;
        this.component.on('afterrender', this._onAfterrender, this);
    },

    /**
     * @protected
     */
    clearStyle : function() {
        this.el.setStyle({
            background : ''
        });
    },
    /**
     * @protected
     * meant to be overriden
     */
    getHoverStyle : function() {
        return {
            background : 'blue'
        };
    },
    /**
     * @protected
     * meant to be overriden
     */
    getPressedStyle : function() {
        return {
            background : 'red'
        };
    },

    _onAfterrender : function() {
        this.el = this.component[this.elementProperty];
        this.el.hover(this._onElementMouseIn, this._onElementMouseOut, this);
        this.el.on('click', this._onElementClick, this);
    },

    _onElementMouseIn : function() {
        if(!this.pressed) {
            this.el.setStyle(this.getHoverStyle());
        }
    },

    _onElementMouseOut : function() {
        if(!this.pressed) {
            this.clearStyle();
        }
    },

    _onElementClick : function(e) {
        this.pressed = !this.pressed;
        if(this.pressed) {
            this.el.setStyle(this.getPressedStyle());
        } else {
            //mimic mouse in
            if(e.within(this.el)) {
                this.el.setStyle(this.getHoverStyle());
            }
        }
    }
});

由于您想要的东西不仅仅适用于按钮,因此它应该适用于任何组件。

这是一个示例用法:

    var headerHoverColor = new Ext.form.field.Text({
    fieldLabel : 'Header hover color',
    value : 'orange',
    renderTo : Ext.getBody()
});

var headerPressedColor = new Ext.form.field.Text({
    fieldLabel : 'Header pressed color',
    value : 'black',
    renderTo : Ext.getBody()
})

new Ext.panel.Panel({
    plugins : {
        ptype : 'dynamicStyleState',
        elementProperty : 'body'
    },
    header : {
        plugins : {
            ptype : 'dynamicStyleState',
            getHoverStyle : function() {
                return {
                    background : headerHoverColor.getValue()
                }
            },
            getPressedStyle : function() {
                return {
                    background : headerPressedColor.getValue()
                }
            }
        }
    },
    height : 300,
    width : 300,
    renderTo : Ext.getBody(),
    title : 'Panel'
});

关于javascript - 如何动态更改悬停和按下的 extjs 按钮的背景,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12106952/

相关文章:

javascript - RhoMobile Javascript 应用程序 - 如何在页面之间进行更改

html - 在 div 中垂直居中内容

CSS背景图片旋转

javascript - 在运行时将变量更改为文字?

javascript - 调整大小时 Skrollr 视差中断

javascript - 如何在复选框选中时启用 Onclick <Button> PHP

javascript - 服务器端数据表以 json 形式发送 POST 数据

javascript - 禁用 URL JavaScript 中的哈希链接

javascript - 混合使用 Javascript 和 jQuery?

css - 在 jquery mobile 中显示平面按钮