jQuery的"特別事件"擴展

特別事件

翻譯自http://brandonaaron.net/blog/2009/03/26/special-eventsjquery

原做者:Brandon Aarongit

jQuery自1.2.2版開始引入稱爲"特別事件"的擴展API。These events are special because they have the ability to do some extra work for specific events and even the option to bypass some of the internal jQuery event system. 有了這些特別事件你能夠建立須要一些setup work的自定義事件,甚至你能夠徹底重載標準jQuery事件的行爲。github

We use special events in jQuery to create the 「mouseenter」 and 「mouseleave」 events. In addition to those two events we used it to make the 「ready」 event and I use it to normalize the 「mousewheel」 event in the mouse wheel plugin.app

一個例子: 「tripleclick」三次點擊

咱們打算創建一個新事件,該事件當用戶對某個元素點擊三次之後觸發。傳統上咱們應該創建相似jQuery.fn.tripleclick這樣的jQuery插件. 但在這裏咱們不這麼作, 咱們想要利用標準jQuery事件系統的bind語法及其它好處好比event normalization, data, and namespaces.ui

首先咱們要創建這個特殊事件。每一個特殊事件須要定義setupteardown方法。方法setup在事件被bind時調用而方法teardown則在解除bind時調用。注意:這兩個方法對每一個元素只會被調用一次,由於jQuery事件系統會管理屢次bind的事件處理器等全部繁瑣的事情。this

In jQuery 1.3 there is a new special event type called 「Special All」 that operates for all handlers but has a slightly different behavior. However, that is for another article.(這個特性已經被取消,不該該再使用Special All了,能夠改用add/remove鉤子,參見最後的延伸閱讀部分)spa

咱們的「tripleclick」插件大概骨架以下:.net

jQuery.event.special.tripleclick = {
    setup: function(data, namespaces) {
        var elem = this;
    },

    teardown: function(namespaces) {
        var elem = this;
    }
};

Notice that the setup event gets passed the data and namespaces that were used when binding the event. Also that the teardown event gets passed the namespaces that were used when unbinding the event. Although, they are only marginally useful here since this is the data and namespaces associated with the very first event handler bound to a particular element. But you could use the data to configure the event for all the handlers of that type for an element. The scope, or the value of this, for these two methods is the element the event is being bound to.插件

Behind the scenes we are actually going to utilize the native 「click」 event to keep track of the number of clicks on an element. We’ll also need a handler that actually does the heavy work of keeping track. I’m going to add a third method called handler to the tripleclick special event. To make the code a little more simple I’m going to track the number of clicks on an element by using the jQuery data API.翻譯

The updated tripleclick special event looks like this.

jQuery.event.special.tripleclick = {
    setup: function(data, namespaces) {
        var elem = this, $elem = jQuery(elem);
        $elem.bind('click', jQuery.event.special.tripleclick.handler);
    },

    teardown: function(namespaces) {
        var elem = this, $elem = jQuery(elem);
        $elem.unbind('click', jQuery.event.special.tripleclick.handler);
    },

    handler: function(event) {
        var elem = this, $elem = jQuery(elem), clicks = $elem.data('clicks') || 0;
        clicks += 1;
        if ( clicks === 3 ) {
            clicks = 0;
            // set event type to "tripleclick"
            event.type = "tripleclick";
            // let jQuery handle the triggering of "tripleclick" event handlers
            jQuery.event.handle.apply(this, arguments)
        }
        $elem.data('clicks', clicks);
    }
};

To quickly break down the handler code. First we get the number of clicks via the data API and increment the number by 1. Then we check to see if it has been clicked 3 times. If so, we then need to reset the number of clicks and trigger the other event handlers as the comment indicates. Finally, we store the new value for the number clicks on the element via the data API.

The handler has to set the event type to 「tripleclick」 because behind the scenes we actually use a click event. jQuery uses the event type to know which handlers it should call and we want it to call the event handlers for our 「tripleclick」 event.

The Example

We can now use our special event just like we’d use any other event via the bind method. For example to bind a 「tripleclick」 event to all divs we’d write the following code.

jQuery('div').bind('tripleclick', function(event) {
    alert('triple clicked');
});

You can see an example of this new special event in action here.

You could enhance this event by requiring all three clicks to be within a certain timeframe. You could achieve this by also storing the event.timeStamp property of the previous click and comparing the distance between it and the latest click.

返回值

前面我說過特別事件可以bypass到內部的jQuery事件系統。The functionality that can be skipped is the actual binding of the event to the element using the addEventListener or attachEvent methods. This functionality is skipped based on the return value. 返回任何非false的值會阻止jQuery將該事件經過DOM實際bind到元素上。換句話說,若是從方法setupteardown中return false的話,jQuery將調用DOM API將事件bind到元素上。在咱們的tripleclick插件中,咱們不但願在元素上bind這個"tripleclick"事件(並不存在這樣的DOM事件),因此咱們沒有返回任何值(就是說,返回了undefined)

 

延伸閱讀

jQuery 1.4爲特別事件新增的add和remove鉤子: http://brandonaaron.net/blog/2009/06/4/jquery-edge-new-special-event-hooks

Automating with Special Events: http://brandonaaron.net/blog/2009/06/17/automating-with-special-events

Special Events: The changes in jQuery 1.4.2: http://brandonaaron.net/blog/2010/02/25/special-events-the-changes-in-1-4-2

相關文章
相關標籤/搜索