суббота, 12 марта 2011 г.

YUI3 Event utility

Подключать можно вот так:
YUI().use('node-base', function(Y) {
    var handleClick = function(e) {
        // pass the event facade to the logger or console for inspection:
        Y.log(e);
    }; 

    //elements can be targeted using selector syntax:
    Y.on("click", handleClick, "#foo p"); //targets all p elements that are descendants
                                          //of #foo
 
    //elements can be targeted by Node references:
    var foo = Y.one("#foo");
    Y.on("click", handleClick, foo);
    foo.on("click", handleClick); //same as above
 
    //elements can be passed in as direct references:
    var foo = document.getElementById("foo");
    Y.on("click", handleClick, foo);
 
    //In all cases, you can pass in an array instead of a
    //single item:
    Y.on("click", handleClick, ["#foo p", "#bar"]);
});



Метод ".on" принимает следующие параметры:
1. Event name: "click", "blur" and etc.
2. Handler: колбек обработчик, первый аргумент это евент фасад(е), а все остальные - аргументы переданные в привязки (5)
3. Element(s): элемент/элементы на которые вешается обработчик, они будут воспроизводить события
4. Context object: контекст, чему будет равен this
5. Argument 1 ... n: аргументы, которые будут переданы в обрабтчик.

.addListener -- этот метод сохранился для оборатной совместимости с юай2, лучше пользоваться ".on", делают они одно и тоже.


Отвязка обработчиков:
//Get a YUI instance:
YUI().use('node-base', function(Y) {
 
    //an event handler:
    function handleClick(e) {
        Y.log(e);
    }
 
    // attach a click event handler to element foo.  The 'eventcategory|'
    // part of this is an optional string that can be used to detach
    // the listener
    var fooHandle = Y.on("eventcatgory|click", handleClick, "#foo");
 
    // detach by event category prefix
    Y.detach('eventcategory|click');
 
    // detach the handler using the handle:
    fooHandle.detach();
 
    // detach all listeners filed under the 'eventcategory' category
    Y.detach('eventcategory|*');
 
    // detach the handler via detach:
    Y.detach("click", handleClick, "#foo");
 
    // or pass the event handle to detach:
    Y.detach(fooHandle);
});

Можно также чистить сами дом-элементы от того, что на них нацеплено:
//get a YUI instance:
YUI().use('node-base', function(Y) {
    // purge all listeners:
    Y.Event.purgeElement("#foo");
    // all listeners and recurse children:
    Y.Event.purgeElement("#foo", true);
    // only click listeners, and don't recurse:
    Y.Event.purgeElement("#foo", false, "click");
});

Симуляция событий
В jQuery это называется тригерами:)
Бывают следующие виды событий, которые можно симулировать и в которых есть своя специфика симуляции:
1.Mouse Events
* click
* dblclick
* mousedown
* mouseup
* mouseover
* mouseout
* mousemove

При этом мы можем добавлять екстрасвойства, которые более точно характеризируют событие:

  • detail - Indicates the number of times a button was clicked (DOM-compliant browsers only).
  • screenX/screenY - coordinates of the mouse event in relation to the entire screen (DOM-compliant browsers only).
  • clientX/clientY - coordinates of the mouse event in relation to the browser client area.
  • ctrlKey/altKey/shiftKey/metaKey - the state of the Ctrl, Alt, Shift, and Meta keys, respectively (true for down, false for up).
  • button - the button being used for the event, 0 for left (default), 1 for right, 2 for center.
  • relatedTarget - the element the mouse moved from (during a mouseover event) or to (during a mouseout event). 

YUI().use('node-event-simulate', function(Y) {
 
    var node = Y.one("#myDiv");
 
    //simulate a click Alt key down
    node.simulate("click", { altKey: true});
 
    //simulate a double click with Ctrl key down
    node.simulate("dblclick", { ctrlKey: true });
 
    //simulate a mouse over
    node.simulate("mouseover", { relatedTarget: document.body });
 
    //simulate a mouse out
    node.simulate("mouseout", { relatedTarget: document.body });
 
    //simulate a mouse down at point (100,100) in the client area
    node.simulate("mousedown", { clientX: 100, clientY: 100 });
 
    //simulate a mouse up at point (100,100) in the client area
    node.simulate("mouseup", { clientX: 100, clientY: 100 });
 
    //simulate a mouse move at point (200, 200) in the client area
    node.simulate("mousemove", { clientX: 200, clientY: 200 });
});

Key Events
* keyup
* keydown
* keypress

YUI().use('node-event-simulate', function(Y) {
 
    var node = Y.one("#myDiv");
 
    //simulate a keydown on the A key
    node.simulate("keydown", { keyCode: 97 });
 
    //simulate a keyup on the A key
    node.simulate("keyup", { keyCode: 97 });
 
    //simulate typing "a"
    node.simulate("keypress", { charCode: 97 });
});

UI Events
* blur
* change
* focus
* resize
* scroll
* select

YUI().use('node-event-simulate', function(Y) {
 
    var node = Y.one("#myInput");
 
    //simulate a change event
    node.simulate("change");
 
    //simulate a select event
    node.simulate("select");
}); 

available - можно нацепить на дом елемент и событие произойдет, когда он будет уже доступен, но при этом его дети могут еще быть не догружены
contentready - а этот запустится, когда следующий сиблинг будет доступный, тоесть когда дети нацепленного элемента будут тоже зугружены
domready - это альтернатива window.load, при этом событие произойдет раньше, потому что оно не будет дожидаться когда догрузятся картинки.

Реакция на нажатие кнопок
  1. The key event type followed by a colon ('up:', 'down:, or 'press:')
  2. zero or more keyCodes to listen for, separated by commas. If more than one keyCode is specified, the listener will fire if any of the codes are detected. ('up:12,13,14')
  3. zero or more modifiers keys to listen for, separated by the plus symbol. If modifiers are specified, all must be detected in order for the listener to fire ('+shift+ctrl+alt+meta').
So, the following specification will fire only if keyCode 65 or 66 is detected during a keypress event while shift and control are held down: 'press:65,66+shift+ctrl'
YUI().use('event-key', function(Y) {
 
    // store the return value from Y.on to remove the listener later
    var handle = Y.on('key', function(e, arg1, arg2, etc) {
        Y.log(e.type + ": " + e.keyCode + ' -- ' + arg1);
 
        // stopPropagation() and preventDefault()
        e.halt();
 
        // unsubscribe so this only happens once
        handle.detach();
 
    // Attach to 'text1', specify keydown, keyCode 13, make Y the context, add arguments
    }, '#text1', 'down:13', Y, "arg1", "arg2", "etc");
 
});

Делегирование
Если однотипных элементов достаточно много, то отдельный слушатель на каждом серьйозно снизит произодительность. Проще нацепить на родителя один слушаетль, который балгодаря пузырению вверх отловит событие, и по параметру e.target -- можно понять кто был автором события.
YUI().use("event-delegate", function(Y) {
 
    Y.delegate("click", function(e) {
 
        //  The list item that matched the provided selector is the
        //  default 'this' object
        Y.log("Default scope: " + this.get("id"));
 
        //  The list item that matched the provided selector is
        //  also available via the event's currentTarget property
        //  in case the 'this' object is overridden in the subscription.
        Y.log("Clicked list item: " + e.currentTarget.get("id"));
 
        //  The actual click target, which could be the matched item or a
        //  descendant of it.
        Y.log("Event target: " + e.target);
 
        //  The delegation container is added to the event facade
        Y.log("Delegation container: " + e.container.get("id"));
 
 
    }, "#container", "li");
 
});


YUI().use("node", function(Y) {
 
    var container = Y.one("#container");
 
    container.delegate("click", function (e) {
        // Same as above
    }, "li");
 
});

mouseenter и mouseleave -- эти два события были переняты из ie. Их главное преимущество по сравнению с w3c-ными mouseover/mouseout в том, что они не пузытятся - если у нашего контейнера много детей, то все они будут позырить эти событие, если слушатель висит на нашем родетеле. Хотя нас интересует только вход-выход в сам контейнр-родитель, а не в его детей. В этом случае нам и нужны эти иешные события.
  • Item Type One
  • Item Type Two
  • Item Type Three

Ховер
YUI().use("event-hover", function(Y) {
 
    function over(e) {
        this.addClass("hover");
    }
 
    function out(e) {
        this.removeClass("hover");
    }
 
    var button = Y.one("#myButton");
 
    // Subscribe to individual events
    button.on({
        mouseenter: over,
        mouseleave: out
    });
 
    // Or subscribe using the hover event
    button.on("hover", over, out);
 
    // Also supports delegation.  Note the signature.
    Y.one("#menu").delegate("hover", over, out, ".menuItem");
});


Touch Events
* touchstart
* touchmove
* touchend
* touchcancel
Это события, которые возникают на такскринных устройствах (айфоны, планшеты). По необходимости можно вернуться более подробнее к этой теме.

Custom Events
Можно создавать кастомные события и реакции на них.

Кастомные события еще также используются для общения между разными песочницами:
var publisher = new Y.EventTarget();
publisher.name = 'broadcast publisher';
 
publisher.publish('instance_notification:foo', {
    broadcast:  1,   // instance level notification
    emitFacade: true // emit a facade so we get the event target
});
 
// this event is available by using the YUI instance to subscribe to it
Y.on('instance_notification:foo', function(e) {
    Y.log(e.target.name); // broadcast publisher
});
 
var publisher2 = new Y.EventTarget();
publisher2.name = 'global publisher';
 
publisher.publish('global_notification:foo', {
    broadcast:  2,   // global notification
    emitFacade: true // emit a facade so we get the event target
});
 
// external code, this new sandbox has access to the global event
YUI().use('event-custom', function(Y2) {
    // the global event can be listened to on a special event
    // target referenced on your YUI instance called 'Global'
    Y2.Global.on('global_notification:foo', function() {
        Y.log(e.target.name); // global publisher
    });
 
    Y2.on('instance_notification:foo', function(e) {
        // will NOT receive notification
    });
};

А вот быстрое создание кастомного события, а также реакция на него:
//Create a YUI instance:
YUI().use('event-custom', function(Y) {
    Y.on('customapp:started', function(arg1, arg2, arg3) {
        Y.log('Custom App Started, now I can do a a few things);
        // the arguments 1, 2, and 3 were provided by fire()
    });

    Y.fire('customapp:started', 1, 2, 3);
});

Итак метод класса Y.TargetEvent.publish принимает два параметра: первый "имя события", по которому, мы сможем его запускать; второй - обьект с настройками:
  • 'broadcast': whether or not the YUI instance and YUI global are notified when the event is fired (false)
  • 'bubbles': whether or not this event bubbles (true) Events can only bubble if emitFacade is true.
  • 'context': the default execution context for the listeners (this)
  • 'defaultFn': the default function to execute when this event fires if preventDefault was not called
  • 'emitFacade': whether or not this event emits a facade (false)
  • 'prefix': the prefix for this targets events, e.g., 'menu' in 'menu:click'
  • 'fireOnce': if an event is configured to fire once, new subscribers after the fire will be notified immediately.
  • 'async': fireOnce event listeners will fire synchronously if the event has already fired unless async is true.
  • 'preventable': whether or not preventDefault() has an effect (true)
  • 'preventedFn': a function that is executed when preventDefault is called
  • 'queuable': whether or not this event can be queued during bubbling (false)
  • 'silent': if silent is true, debug messages are not provided for this event.
  • 'stoppedFn': a function that is executed when stopPropagation is called
  • 'monitored': specifies whether or not this event should send notifications about when the event has been attached, detached, or published.
  • 'type': the event type (valid option if not provided as the first parameter to publish)

Комментариев нет:

Отправить комментарий