使用事件

Ext JS 的组件和类在它们的生命周期的各个点上触发很宽泛的事件.应用中的事件允许你编写代码来响应.事件是Ext JS 中的一个关键概念.

什么是事件?

事件每当一个你的类发生一些有趣的事时触发.例如, 当 Ext.Component 渲染到屏幕时, Ext JS 在完成渲染后触发一个事件.我们能通过配置一个简单listeners对象来监听:

编辑 预览 在 Fiddle 中打开
Ext.create('Ext.Panel', {
    html: 'My Panel',
    renderTo: Ext.getBody(),
    listeners: {
        afterrender: function() {
            Ext.Msg.alert('We have been rendered');
        }
    }
});

在这个例子中,当你点击 预览 按钮, 这个面板渲染到屏幕上,紧接接弹出一个定义好的消息.一个类触发的所有事件都在类的API页中列出来了. - 例如, Ext.panel.Panel 现在有 45 个事件.

监听事件

虽然在某些情况下 Ext.Component-event-afterrender 事件很有用,但你可能使用其它事件更为频繁. 例如, Ext.button.Button 按钮当点击时触发 click 事件:

编辑 预览 在 Fiddle 中打开
Ext.create('Ext.Button', {
    text: 'Click Me',
    renderTo: Ext.getBody(),
    listeners: {
        click: function() {
            Ext.Msg.alert('I was clicked!');
        }
    }
});

一个组件可以包含按照需要足够多的事件监听器. 下面的例子中,我们配置用户在鼠标离开监听器中调用 this.hide() 方法来隐藏一个按钮. 然后我们在1秒后又显示这个按钮. 当 this.hide() 调用后,这个按钮隐藏并且 hide 事件触发. 这个 hide 事件触发我们的 hide 监听器,这个监听器将会等待1秒然后再显示这个按钮:

编辑 预览 在 Fiddle 中打开
Ext.create('Ext.Button', {
    renderTo: Ext.getBody(),
    text: 'My Button',
    listeners: {
        mouseover: function() {
            this.hide();
        },
        hide: function() {
            // Waits 1 second (1000ms), then shows the button again
            Ext.defer(function() {
                this.show();
            }, 1000, this);
        }
    }
 });

事件监听器每调用一次事件触发一次,因此你可以随意的连续的隐藏和显示这个按钮.

后续添加监听

在上面的例子中,当类实例化后我们将监听器传给组件.然而,如果我们已经有了一个实例,我们能通过使用这个 on 函数来增加监听器:

编辑 预览 在 Fiddle 中打开
var button = Ext.create('Ext.Button', {
    renderTo: Ext.getBody(),
    text: 'My Button'
});

button.on('click', function() {
    Ext.Msg.alert('Event listener attached by .on');
});

你可以通过使用这个 .on 方法指定多个监听器,类似于使用监听器配置,下面重写上面这个设置鼠标离开时事件按钮的可见性的例子:

编辑 预览 在 Fiddle 中打开
var button = Ext.create('Ext.Button', {
    renderTo: Ext.getBody(),
    text: 'My Button'
});

button.on({
    mouseover: function() {
        this.hide();
    },
    hide: function() {
        Ext.defer(function() {
            this.show();
        }, 1000, this);
    }
});

删除监听

和我们可以在任意时候添加监听器一样,我们也能删除监听器.这回我们使用这个 un 函数. 删除一个监听器,我们需要这个函数的引用.在上面的例了中,我们一个函数到监听器的对象或这个 on 调用. 这次,我们先创建这个函数然后将它设置为一个叫做 doSomething 的变量, 这个函数包含了我们定制的函数. 因我们初始化时传递这个新的 doSomething 函数给我们的监听器对象,这段代码和前面的开始一样.在最后有一个 Ext-method-defer 函数, 按这个按钮的前3秒弹出一个提示信息.3秒后这个监听器被删除了,这个再按就没有反应了:

编辑 预览 在 Fiddle 中打开
var doSomething = function() {
    Ext.Msg.alert('listener called');
};

var button = Ext.create('Ext.Button', {
    renderTo: Ext.getBody(),
    text: 'My Button',
    listeners: {
        click: doSomething,
    }
});

Ext.defer(function() {
    button.un('click', doSomething);
}, 3000);

确听监听范围选项

监听范围设置处理器函数里面的值.默认的情况下,这是对触发事件的实例的设置.经常来说是这样,但并不是全部,你要的功能.这个功能允许我们调用 this.hide() 方法来隐藏按钮就象我们这个向导早前的第二个例子一样.在下面的这个例子中,我们创建一个按钮和一个面板.我们然后在面板范围内来监听这个按钮的点击事件.为了这么做,我们需要传递一个对象而不是一个处理器函数.这个对象包含忱个处理器函数范围:

编辑 预览 在 Fiddle 中打开
var panel = Ext.create('Ext.Panel', {
    html: 'Panel HTML'
})

var button = Ext.create('Ext.Button', {
    renderTo: Ext.getBody(),
    text: 'Click Me'
});

button.on({
    click: {
        scope: panel,
        fn: function() {
            Ext.Msg.alert(this.getXType());
        }
    }
});

当你运行这个示例时,点击处理器中 this 的值是这个Panel面板的引用. 为看到这个说明,我们弹出这个范围组件的 xtype . 当这个按钮被点击,我们可以看到这个Panel(面板) xtype 在消息中弹出来了.

一次性监听事件

你可能只需要监听一次某一个事件. 这个事件本身可以触发任意次数,但我们只需要监听一次.下面的代码演示了这种情形:

编辑 预览 在 Fiddle 中打开
var button = Ext.create('Ext.Button', {
    renderTo: Ext.getBody(),
    text: 'Click Me',
    listeners: {
        click: {
            single: true,
            fn: function() {
                Ext.Msg.alert('I will say this only once');
            }
        }
    }
});

使用缓冲配置

在短时间内接连角发多次事件时,我们减少监听器的次数叫做使用缓冲配置. 在这个例子中我们的按钮点击事件监听器在2秒内只调用一次,而不管你点了多少次:

编辑 预览 在 Fiddle 中打开
var button = Ext.create('Ext.Button', {
    renderTo: Ext.getBody(),
    text: 'Click Me',
    listeners: {
        click: {
            buffer: 2000,
            fn: function() {
                Ext.Msg.alert('I say this only once every 2 seconds');
            }
        }
    }
});

触发定制事件

通过调用包含事件名称的 fireEvent 来角发你自己的事件. 下面的例子中我们触发一个传递2个参数的叫做 myEvent 的事件 -2个参数是按钮本身和一个1至100的随机数:

编辑 预览 在 Fiddle 中打开
var button = Ext.create('Ext.Button', {
    renderTo: Ext.getBody(),
    text: "Just wait 2 seconds",
    listeners: {
        myEvent: function(button, points) {
            Ext.Msg.alert('myEvent fired! You score ' + points + ' points');
        }
    }
});

Ext.defer(function() {
    var number = Math.ceil(Math.random() * 100);

    button.fireEvent('myEvent', button, number);
}, 2000);

我们再次使用了 Ext.defer 来延迟加载我们触发定制事件的函数, 这次是2秒钟. 当事件被触发时, myEvent 监听器获得监听并且显示我们传过去的参数.

监听DOM事件

不是每一个 ExtJS 组件触发每一个事件. 然而,通过确定容器的元素,我们可以附加很多组件可以监听的原生事件. 这个例子中,我们确定为 Ext.container.Container. 容器没有点击事件.那我们给它一个!

编辑 预览 在 Fiddle 中打开
var container = Ext.create('Ext.Container', 
    renderTo: Ext.getBody(),
    html: 'Click Me!',
    listeners: {
        click: function(){
            Ext.Msg.alert('I have been clicked!')  
        }
    }
});

container.getEl().on('click', function(){ 
    this.fireEvent('click', container); 
}, container);

没有第二块代码,容器的点击事件处理器不会被触发.因此我们确定了容器元素为目标并且附加了单击的监听器,我们继承了容器的事件能力.

事件标准化

事件标准化是允许 Ext JS 5+ 应用运行在触屏设备上的关键. 标准化发生在这个背景下并且是一个从标准鼠标事件到它们相等的触点事件的转换.

触点击事件是一个处理在屏幕上定位目标指定的一套动作的 w3c 标准,与输入设备无关(鼠标,触摸,触笔等等)

当你代码需要一个鼠标事件的监听器时,框架按需要附加一个相似的触点事件.例如,如果一个应用尝试附加一个 mousedown 监听器:

myElement.on('mousedown', someFunction);

事件处理系统将这个点击转换为一个支持触点事件设备上的 touchstart 事件:

myElement.on('touchstart', someFunction);

或者, pointerdown 如果是在支持点事件的设备上:

myElement.on('pointerdown', someFunction);

这种转换准备好了,这样你可以不需要额外的代码就可以支持平板和触屏设备.

大多数情况下框架可以在鼠标、触屏和触点输入中做无缝转换.但是,有少数的交互(如鼠标离开mouseover)事件不能在触屏类交互中转换.这些事件需要区别对待的基础方法,下面的章节会说明.

手势

与标准 DOM 事件不同, 元素可以触发人工 “gesture”(手势) 事件. 尽管 Sencha Touch 事件系统形成了事件系统的基础, Sencha Touch 用户可能已经对这些概念已经熟悉.

从浏览器的方面来看, 有3种主要的点、触 和鼠标事件 - start,(开始),move(移动), 和 end(结束):

Event Touch Pointer Mouse
Start touchstart pointerdown mousedown
Move touchmove pointermove mousemove
Stop touchend pointerup

理解这些事件的顺序和时机,框架可以无缝的转换更为复杂的事件诸如 drag(拖), swipe(滑动), longpress(长按), pinch(捏), rotate(旋转), 和 tap(轻触). Ext JS 应用能够就象其它事件一样监听这些手势事件,例如:

Ext.get('myElement').on('longpress', handlerFunction);

原始的l Sencha Touch 手势系统内心来讲是为主要处理触屏事件而设计的. 通过增加对点击类和鼠标事件到手势系统, Ext JS 5 允许任意手势来响应任意类型的输入. 这意味着不管是使用触碰所有手势能被触发,而且所有单点手势 (如tap(轻触), swipe(滑动)等.) 也能象鼠标一样被触发.手势处理系统的这一结果可以在输入类型无关的设备间无缝工作.

Last updated