Клуб API Карт

Html метки

Пост в архиве.

Здравствуйте!

Переносим проект на Яндекс.Карты 2.1. И зашли в тупик. Чтение документации не помагает. Понимаем что ответ где-то на поверности, но найти его не можем. Поэтому просим помощи.

создаем обрботчик событий метки

  

 

                // Контекстное меню, позволяющее изменить параметры метки.

                // Вызывается при нажатии правой кнопкой мыши на метке.

                placemarkNew.events.add('contextmenu', function (e) 

                {

                    // Получение ссылки на объект 

                   thisPlacemark = e.get('target');

                  

                  //и вот тут самое интересное

                  // в 2.0 можно было сделать

                  var thisPlacemarkDom = jQuery(thisPlacemark.getOverlay().getElement());

                  // это позволяло "достучаться" до ДОМ метки и творить с ним что угодно 

                  .......

                 // в 2.1 это сделать не получается даже если через промисы достучаться до getOverlay() то вот getElement() получить не удается

                 подскажите как быть? как получить текущий html метки?

                }

 

13 комментариев
Всеволод Шмыров
28 января 2016, 00:12
Вы реализуете собственные HTML-метки?

В версии 2.1 был изменен стандартный оверлей метки. Раньше использовался 'html#placemark', а теперь используется 'default#placemark'. Новые оверлей не предоставляет метод getLayout, так как макета может не быть - метка может нарисована не только средствами DOM, но и SVG или на canvas в зависимости от возможностей браузера.

'default#placemark'
http://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/overlay.Placemark.xml

'html#placemark'
http://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/overlay.html.Placemark.xml

Если вы реализуете собственную HTML-метку, то вы, чтобы сильно не менять код, можете просто выставить опцию pointOverlay
http://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/Placemark.xml#param-options.pointOverlay равной 'html#placemark'.

А в обработчике события вызывать getOverlaySync().getLayoutSync().getElement(). В обоих случаях синхронный метод, так как на момент срабатывания события оверлей уже будет загружен.

Спасибо за ваш ответ.

 

Да, мы реализуем собственный макет для метки ymaps.templateLayoutFactory.createClass. Макет - это картинка в диве.

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

Спасибо за ваше предложение, сегодня же попробуем, на первый взляд оно должно нам помочь.

 

А еще Вы написали, что "чтобы сильно не менять код" можно сделать так, но это можно трактовать еще и  так, что это же можно сделать более правильно, но с большими изменениями кода. Есть где-либо пример, или если вас не затруднит можете привести пример сами, как можно сделать то что нам нужно, но более правильно?

Всеволод Шмыров
28 января 2016, 00:12
А какую задачу вы решаете? Вполне может быть, что для вашей задачи другого решения и нет.

Задача следующая. Как я уже сказал ранее, есть метка создананя через макет. Макет состоит из картинки находящейся в диве. Когда на карте происходит клик по метке, выскакивает меню. Меню состоит из скрола прогарудированногго в радусах от 0 до 360. В момент перемещения скрола получается значение градуса. и хочется в реальном времени производтиь поворот картинки метки на карте. для этого требуется получить ДОМ метки и выставить ему css свойство transform:rotate

 

Ваш первый способ подходит, но честно говоря хотелось бы реализовать эту задачу правильно и корректно и не бояться, что когда Яндекс.Карты откажутся от html#placemark хватануть новых проблем в будущем.

Всеволод Шмыров
28 января 2016, 00:12
от html#placemark в версии 2.* мы точно не будем избавляться. "Мажорные" версии выходят не очень часто. И мы стараемся в них без нужды не ломать обратную совместимость. Но периодически это необходимо.

Вообще логику макета правильней реализовать в самом макете.
Пример
http://jsfiddle.net/VTLJ2/1/
В примере создается собственный макет, в котором на верхний элемент навешивается событие 'contextmenu'. Это происходит в переопределении метода build. Чтобы сам макет ловил события, в примере он был поставлен над слоем событий (iconPane: 'overlaps'). Обычно меткам не нужны сложные HTML макеты с каким-то поведением. Метки по умолчанию в 2.1 стали находится под слоем событий. Это значит поступающие события "перехватываются" выше и программно определяется какому объекту под слоем событий соответствовало это событие. Это было сделано в целях производительности. При большом кол-ве меток кол-во подписок не увеличивается.

спасибо. все получилось

Появился еще один вопрос. А если использовасть способ предложенны вами в последнем варианте http://jsfiddle.net/VTLJ2/1/, то как получить доступ к координатам метки?

 

если          

this._events.add('contextmenu', function ()

{

      alert('1'); 

 });

 

переписать на 

this._events.add('contextmenu', function (e)

{

     то в "е" координат метки уже нет. как быть?

});

Всеволод Шмыров
28 января 2016, 00:12
Макет получает информацию о геообъекте при создании. Координаты можно получить через метод getData().

this._events.add('contextmenu', function () {
    alert(this.getData().geometry.getCoordinates());
}, this);

http://jsfiddle.net/VTLJ2/2/
Всеволод Шмыров
28 января 2016, 00:12
или

this.getData().geoObject.geometry

В метод add был добавлен третий аргумент - это контекст исполнения функции обратного вызова.
http://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/IEventManager.xml#add

спасибо

Добрый день! У меня схожая проблема. Сделал как вы указали через getOverlaySync, но вызов этого метода в первый раз не срабатывает, последующие вызовы работают. С чем это может быть связано?
Илья Рудь
25 июля 2022, 19:43
pyreee,
ну жа поавилигно !!
Илья Рудь
25 июля 2022, 19:42
оу ее