События

В API Яндекс.Карт реализован собственный механизм работы с событиями, расширяющий стандартные средства управления событиями JavaScript. Это означает, что для работы с событиями браузера, окна браузера и DOM-дерева применимы стандартные подходы, использующиеся в JavaScript, для работы с объектами API — событийная модель API Яндекс.Карт.

В API реализована традиционная модель работы с событиями. Некоторые объекты могут генерировать события, на которые можно подписываться и передавать в функцию-обработчик.

Все объекты API, которые могут генерировать события, реализуют интерфейс IEventEmitter и имеют поле events. Это поле содержит ссылку на менеджер событий, с помощью которого можно подписаться на нужные события или удалить подписку.

myPlacemark.events.add('click', function () {
    alert('О, событие!');
});

Возникшее событие распространяется вверх по всей иерархии родительских объектов вплоть до родительской коллекции объекта карты (т. н. «всплывание»). До самого объекта карты события дочерних элементов не доходят.

myPlacemark.events.add('click', function () {
    alert('О, событие!');
});
myMap.geoObjects.events.add('click', function (e) {
    alert('Дошло до коллекции объектов карты');
    // Получение ссылки на дочерний объект, на котором произошло событие.
    var object = e.get('target');
});
myMap.events.add('click', function () {
    alert('Событие на карте'); // Возникнет при щелчке на карте, но не на маркере.
});

Для остановки распространения события предназначен метод stopPropagation.

myPlacemark.events.add('click', function (e) {
    alert('О, событие!');
    e.stopPropagation();
});
myMap.geoObjects.events.add('click', function () {
    alert('Граница на замке');
});

Для большинства событий определены стандартные действия, которые будут произведены после возникновения события. Эти действия могут быть отменены с помощью метода preventDefault.

myMap.events.add('dblclick', function (e) {
    e.preventDefault(); // При двойном щелчке зума не будет.
});

Структура объекта-события

События, генерируемые API Яндекс.Карт представляют собой объекты класса Event. Исключение составляют события карты, описываемые классом MapEvent, расширяющим Event.

Объект, описывающий событие, содержит в себе информацию как о самом событии, так и об объекте, который его сгенерировал. Извлечение данных из объектов Event и MapEvent производится с помощью метода get, в который передается имя поля внутреннего объекта этого класса, описывающего событие.

Для любого события может быть получена ссылка на объект, который его сгенерировал. Эта ссылка содержится в поле target.

myMap.events.add('click', function (e) {
    var eMap = e.get('target');// Получение ссылки на объект, сгенерировавший событие (карта).
    eMap.setType('yandex#hybrid');
});

Тип любого события может быть получен путем обращения к полю type.

myMap.events.add(['click', 'contextmenu'], function (e) {
    var eType = e.get('type');
    eType == 'click' ? alert('left button') : alert('right button');
});

Событие API, возникновение которого инициируется событием DOM, в поле domEvent внутреннего объекта содержит ссылку на объект API, описывающий DOM-событие (класс DomEvent). Этот объект содержит ссылку на оригинальное событие DOM в поле originalEvent.

myPlacemark.events.add('mousedown', function (e) {
    // 0, 1 или 2 в зависимости от того, какая кнопка мыши нажата (В IE значение может быть от 0 до 7).
    alert(e.get('domEvent').originalEvent.button);
});

Класс DomEvent предоставляет прокси-доступ к полям и методам оригинального DOM-события и адаптирован с учетом особенностей различных браузеров. Поэтому удобнее не обращаться к оригинальному DOM-событию, а использовать класс DomEvent: метод get для получения свойства события и метод callMethod для обращения к его методу.

myPlacemark.events.add('click', function (e) {
    // Вместо alert(e.get('domEvent').originalEvent.pageX);
   alert(e.get('domEvent').get('pageX'));
});

Кроме того, DomEvent позволяет получить координаты курсора сразу в виде массива — get('position').

Архитектура API спроектирована таким образом, что большую часть информации, содержащейся в объекте, описывающем событие, можно узнать из свойств объекта, который сгенерировал это событие.

Контекст обработки события

При назначении обработчика события с помощью менеджера событий, можно указать не только функцию-обработчик, но и контекст, в котором она будет выполняться. Чаще всего в качестве контекста передается ссылка на объект, внутренние данные которого необходимы функции-обработчику.

function myCounter(start) {
    this.counter = start;
}
myCounter.prototype.go = function () {
    var myMap = new ymaps.Map("map", {
        center: [59.93, 30.31],
        zoom: 12
    });
    myMap.events.add('click', this.up, this);
}
myCounter.prototype.up = function () {
    this.counter++;
    alert(this.counter)
};
var c = new myCounter(2012);
c.go();