События

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

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

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

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

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

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

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

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

myMap.events.add('click', function (e) {
    // Получение координат щелчка
    var coords = e.get('coords');
    alert(coords.join(', '));
});

Для любого события может быть получена ссылка на объект, который его сгенерировал. Эта ссылка содержится в поле 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 спроектирована таким образом, что большую часть информации, содержащейся в объекте, описывающем событие, можно узнать из свойств объекта, который сгенерировал это событие.

Распространение событий

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

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(); // При двойном щелчке зума не будет.
});

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

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

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();
Предыдущая
Следующая