@acm1980

Как уточнить работу меток в Яндекс карте?

В песочнице Яндекс карт нашел "Вывод списка объектов карты" https://yandex.ru/dev/maps/jsbox/2.1/object_list/ - там при нажатии на ссылку из списка открывается и закрывается балун метки.
А как сделать в обе стороны? Так, чтобы при нажатии на метку, не только балун открывался, а еще ссылка из списка "реагировала"? В идеале при большом количестве меток (и ссылок в списке) - при нажатии на метку соответствующая ссылка выделялась, а список "перелистывался" до соответствующей ссылки (как с якорями).

ymaps.ready(init);

function init() {

    // Создание экземпляра карты.
    var myMap = new ymaps.Map('map', {
            center: [50.443705, 30.530946],
            zoom: 14
        }, {
            searchControlProvider: 'yandex#search'
        }),
        // Контейнер для меню.
        menu = $('<ul class="menu"/>');
        
    for (var i = 0, l = groups.length; i < l; i++) {
        createMenuGroup(groups[i]);
    }

    function createMenuGroup (group) {
        // Пункт меню.
        var menuItem = $('<li><a href="#">' + group.name + '</a></li>'),
        // Коллекция для геообъектов группы.
            collection = new ymaps.GeoObjectCollection(null, { preset: group.style }),
        // Контейнер для подменю.
            submenu = $('<ul class="submenu"/>');

        // Добавляем коллекцию на карту.
        myMap.geoObjects.add(collection);
        // Добавляем подменю.
        menuItem
            .append(submenu)
            // Добавляем пункт в меню.
            .appendTo(menu)
            // По клику удаляем/добавляем коллекцию на карту и скрываем/отображаем подменю.
            .find('a')
            .bind('click', function () {
                if (collection.getParent()) {
                    myMap.geoObjects.remove(collection);
                    submenu.hide();
                } else {
                    myMap.geoObjects.add(collection);
                    submenu.show();
                }
            });
        for (var j = 0, m = group.items.length; j < m; j++) {
            createSubMenu(group.items[j], collection, submenu);
        }
    }

    function createSubMenu (item, collection, submenu) {
        // Пункт подменю.
        var submenuItem = $('<li><a href="#">' + item.name + '</a></li>'),
        // Создаем метку.
            placemark = new ymaps.Placemark(item.center, { balloonContent: item.name });

        // Добавляем метку в коллекцию.
        collection.add(placemark);
        // Добавляем пункт в подменю.
        submenuItem
            .appendTo(submenu)
            // При клике по пункту подменю открываем/закрываем баллун у метки.
            .find('a')
            .bind('click', function () {
                if (!placemark.balloon.isOpen()) {
                    placemark.balloon.open();
                } else {
                    placemark.balloon.close();
                }
                return false;
            });
    }

    // Добавляем меню в тэг BODY.
    menu.appendTo($('body'));
    // Выставляем масштаб карты чтобы были видны все группы.
    myMap.setBounds(myMap.geoObjects.getBounds());
}
  • Вопрос задан
  • 121 просмотр
Решения вопроса 1
0xD34F
@0xD34F Куратор тега Яндекс.Карты
Добавить ссылкам и меткам индексы - использовать для этого data-атрибуты и properties соответственно.

Дальше при клике по ссылке просто открываете балун метки с тем же индексом, что и у ссылки:

контейнерСсылок.addEventListener('click', e => {
  const index = e.target.dataset.index;
  if (index) {
    массивМеток[index].balloon.open();
  }
});

Меткам добавляете обработчики событий открытия и закрытия балуна, где добавляете/снимаете выделение ссылке с тем же индексом, что и у метки:

массивМеток.forEach(n => {
  n.events.add('balloonopen', onBalloonOpen);
  n.events.add('balloonclose', onBalloonClose);
});

function onBalloonOpen(e) {
  const index = e.get('target').properties.get('index');
  const link = контейнерСсылок.children[index]; /* или, если структура списка ссылок более сложная,
                                                 * как в примере из документации, можно искать нужную
                                                 * через .querySelector(`[data-index="${index}"]`)
                                                 */
  link.scrollIntoView({
    behavior: 'smooth',
  });
  link.classList.add('active');
}

function onBalloonClose(e) {
  const index = e.get('target').properties.get('index');
  контейнерСсылок.children[index].classList.remove('active');
}

https://jsfiddle.net/19sbtk0d/1/
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы