如何动态更改悬停和压缩的extjs-button的背景 [英] How to change background of hovered and pressed extjs-button dynamically

查看:117
本文介绍了如何动态更改悬停和压缩的extjs-button的背景的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在那里,



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

我到目前为止已经提出如下:
http://jsfiddle.net/suamikim/c3eHh/

  Ext.onReady (function(){
function updateBackground(){
var theWin = win || this,//因为afterrender事件的调用
btn = theWin.down('# btnTest'),
bckgr = theWin.down('#btnBckgr')。getValue(),
bckgrHover = theWin.down('#btnBckgrHover')。getValue(),
bckgrPressed = theWin.down('#btnBckgrPressed')。getValue();

//将普通背景设置为按钮样式
//应该可以
$('#'+ btn.id).css('background',bckgr);

//当ho时切换背景ver-state changes
//每次调用updateBackground方法时,如果这个函数被调用,是否有任何缺点?在绑定功能之前,我必须处理任何东西吗?
$('#'+ btn.id).hover(function(){
$('#'+ btn.id).css('background',bckgrHover);
} ,function(){
$('#'+ btn.id).css('background',bckgr);
}
);

//将按钮的背景设置为文档样式
//问题:
// - 如果多次调用,则会污染文档标题...
// - 由于!重要,背景不再变化,因为按下了按钮,但重要的是不会显示所有的压缩背景...
$('< style type =text / css>#'+ btn.id +'.x-btn -ressed {background:'+ bckgrPressed +'!important}< / style>')appendTo('head');
};

//使用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'},
'背景悬停(CSS):',{itemId:'btnBckgrHover',value:'#CC1C1C'},
'后台按下(CSS):',{itemId:'btnBckgrPressed',value: #7D4FC6'}
]
},

项目:[{
xtype:'button',
itemId:'btnTest',
文本:'test button',
enableToggle:true
}],

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

这基本上可以工作,但有一些问题给我:



1)



每次调用updateBackground方法时都可以调用jquery的悬浮功能吗?


根据jquery-doc( http://api.jquery.com/hover/ )这个功能将2个给定的功能绑定到鼠标进入&给定元素的鼠标离开事件。


这是否意味着它每次调用它时会绑定新的函数,或者是更新已经绑定的函数,还是自动处理已经绑定的函数绑定新的...


简而言之:在使用$ .hover绑定新函数之前,是否必须处理任何东西?



2)



我将压缩状态的样式设置为文档样式,这意味着如果经常调用updateBackground函数,则文档头会被污染(每次的文本字段触发了我的测试用例中的模糊事件)。



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



3)



悬停状态的背景如果按下按钮是因为按压样式中的!重要标志,则不会出现。我不能只是删除这个标志,因为压缩状态的背景不会显示正确没有它...
任何解决方案?


$ b $一般来说,对于如何以完全不同的方式解决这个问题的一切建议,我都会公开。



谢谢,



mik






编辑:



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



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

解决方案

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

  .x-btn.my-over {
background:blue;
}
/ * Ext不一致* /
.x-btn.x-btn-my -ressed {
background:red;
}


new Ext.button.Button({
overCls:'my-over',
compressCls:'my -ressed',
//需要是真的有按下的cls显示
enableToggle:true,
文本:'我的按钮',
renderTo:Ext.getBody(),
})






编辑更加动态的通用解决方案

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

/ **
* @property
* /
按:false,

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

/ **
* @protected
* /
clearStyle:function (){
this.el.setStyle({
背景:''
});
},
/ **
* @protected
*意图被覆盖
* /
getHoverStyle:function(){
return {
background:'blue'
};
},
/ **
* @protected
*意图被覆盖
* /
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 {
//模仿鼠标在
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:'身体'
},
标题:{
plugins:{
ptype:'dynamicStyleState',
getHoverStyle:function(){
return {
background:headerHoverColor.getValue()
}
},
getPressedStyle:function(){
return {
background:headerPressedColor.getValue()
}
}
}
},
height:300,
width:300,
renderTo:Ext.getBody(),
标题:'Panel'
});


Hy there,

i need the ability to change the background-color for the different states (normal, hover, pressed) of a button dynamically.

What i've came up with so far is the following: 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();
});

This works basically but there are some questions left to me:

1)

Is it ok to call the hover-function of jquery everytime the updateBackground-method is called?

According to the jquery-doc (http://api.jquery.com/hover/) this functions binds the 2 given functions to the mouse-enter- & mouse-leave-events of the given element.

Does this mean that it binds new functions everytime i call it or does it update the already bound ones or does it dispose the already bound ones automatically before binding the new ones...

In short: do i have to dispose anything before binding the new functions with $.hover?

2)

I set the style for the pressed state as document-style which means that the document-header gets polluted if the updateBackground-function is called often (everytime one of the text-fields fires the blur-event in my test-case).

Is there any better way to achieve the same goal or can i remove the already set styles before adding new ones?

3)

The background for hover-state doesn't appear if the button is pressed because of the !important-flag in the pressed-style. I can't just remove this flag because the background of the pressed-state wouldn't show correctely without it... Any solutions?

In general i'd be open for every suggestion on how to solve this problem in a completely different way.

Thanks,

mik


Edit:

The code above is just an example. Actually i need to be able to change the background-attribute for other ext-controls than buttons too (panels, checkboxes, ...) but i think that i can adopt a working solution for buttons to those other controls myself.

Please keep this in mind and don't specify the answer too much on buttons. It should be as generic as possible...

解决方案

Using some more specific css selectors you can take advantage of Ext's pressedCls and overCls configs. 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(),
})


Edit for a more dynamic, generic solution

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

Since you want something that works on more than just button this should work on any component.

Here is an example usage:

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

这篇关于如何动态更改悬停和压缩的extjs-button的背景的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆