Боковая панель на карте

Open in CodeSandbox

В примере показано, как добавить боковую панель на карту. Боковая панель не зависит от меток и в неё можно добавлять любой контент с помощью метода setContent().

Боковая панель создаётся на основе собственного элемента управления. Для ускорения разработки, можно отнаследовать класс элемента управления от класса collection.Item.

В данном примере мы слушаем событие клика на метках, добавленных на карту. При клике по метке мы добавляем в боковую панель информацию, которая содержится в балуне этой метки.

<!DOCTYPE html>
<html>
    <head>
        <title>Боковая панель на карте</title>
        <meta
            http-equiv="Content-Type"
            content="text/html; charset=utf-8"
        />
        <!--
        Укажите свой API-ключ. Тестовый ключ НЕ БУДЕТ работать на других сайтах.
        Получить ключ можно в Кабинете разработчика: https://developer.tech.yandex.ru/keys/
    -->
        <script
            src="https://api-maps.yandex.ru/2.1/?lang=ru_RU&amp;apikey=<ваш API-ключ>"
            type="text/javascript"
        ></script>
        <script
            src="https://yandex.st/jquery/2.2.3/jquery.min.js"
            type="text/javascript"
        ></script>
        <script src="panel.js" type="text/javascript"></script>
        <script src="sidebar.js" type="text/javascript"></script>
        <style type="text/css">
            html,
            body,
            #map {
                width: 100%;
                height: 100%;
                padding: 0;
                margin: 0;
            }

            .customControl {
                display: none;
                background-color: #fff;
                padding: 5px;
                border-radius: 3px;
                max-width: 250px;
                box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            }

            .closeButton {
                flex-basis: 15px;
                flex-grow: 0;
                flex-shrink: 0;
                padding: 3px;
                height: 15px;
                cursor: pointer;
                background: url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNCIgaGVpZ2h0PSIxNCI+PHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBkPSJNMTQgLjdsLS43LS43TDcgNi4zLjcgMCAwIC43IDYuMyA3IDAgMTMuM2wuNy43TDcgNy43bDYuMyA2LjMuNy0uN0w3LjcgN3oiIGNsaXAtcnVsZT0iZXZlbm9kZCIvPjwvc3ZnPg==")
                    50% no-repeat;
                opacity: 0.3;
            }

            .content {
                padding: 5px;
                max-height: 250px;
                overflow: auto;
            }

            a,
            a:visited {
                color: #04b;
                text-decoration: none !important;
            }
        </style>
    </head>
    <body>
        <div id="map"></div>
    </body>
</html>
// Пример реализации боковой панели на основе наследования от collection.Item.
// Боковая панель отображает информацию, которую мы ей передали.
ymaps.modules.define(
    "Panel",
    ["util.augment", "collection.Item"],
    function (provide, augment, item) {
        // Создаем собственный класс.
        var Panel = function (options) {
            Panel.superclass.constructor.call(this, options);
        };

        // И наследуем его от collection.Item.
        augment(Panel, item, {
            onAddToMap: function (map) {
                Panel.superclass.onAddToMap.call(this, map);
                this.getParent()
                    .getChildElement(this)
                    .then(this._onGetChildElement, this);
                // Добавим отступы на карту.
                // Отступы могут учитываться при установке текущей видимой области карты,
                // чтобы добиться наилучшего отображения данных на карте.
                map.margin.addArea({
                    top: 0,
                    left: 0,
                    width: "250px",
                    height: "100%",
                });
            },

            onRemoveFromMap: function (oldMap) {
                if (this._$control) {
                    this._$control.remove();
                }
                Panel.superclass.onRemoveFromMap.call(this, oldMap);
            },

            _onGetChildElement: function (parentDomContainer) {
                // Создаем HTML-элемент с текстом.
                // По-умолчанию HTML-элемент скрыт.
                this._$control = $(
                    '<div class="customControl"><div class="content"></div><div class="closeButton"></div></div>'
                ).appendTo(parentDomContainer);
                this._$content = $(".content");
                // При клике по крестику будем скрывать панель.
                $(".closeButton").on("click", this._onClose);
            },
            _onClose: function () {
                $(".customControl").css("display", "none");
            },
            // Метод задания контента панели.
            setContent: function (text) {
                // При задании контента будем показывать панель.
                this._$control.css("display", "flex");
                this._$content.html(text);
            },
        });

        provide(Panel);
    }
);
ymaps.ready(["Panel"]).then(function () {
    var map = new ymaps.Map("map", {
        center: [55.733, 37.588],
        zoom: 10,
        controls: [],
    });
    // Создадим контент для меток.
    var firstOffice =
        "Первый полноценный офис Яндекса появился в Москве в 2001 году. " +
        "Тогда компания занимала небольшой корпус Вычислительного центра РАН на улице Вавилова, там работало 60 человек.";
    var secondOffice = "Второй офис Яндекса на Самокатной улице.";
    var thirdOffice =
        '<a href="https://yandex.ru/company/contacts/moscow/">Главный офис Яндекса</a>' +
        "<p>В офисе на улице Льва Толстого находится штаб-квартира Яндекса, он самый большой и по размерам, " +
        "и по численности сотрудников. Сейчас он занимает почти целый квартал между улицами Льва Толстого " +
        "и Тимура Фрунзе. Общая площадь всех зданий — более 50 тысяч квадратных метров.</p>";
    // Создадим и добавим панель на карту.
    var panel = new ymaps.Panel();
    map.controls.add(panel, {
        float: "left",
    });
    // Создадим коллекцию геообъектов.
    var collection = new ymaps.GeoObjectCollection(null, {
        // Запретим появление балуна.
        hasBalloon: false,
        iconColor: "#3b5998",
    });
    // Добавим геообъекты в коллекцию.
    collection
        .add(
            new ymaps.Placemark([55.733838, 37.5881], {
                balloonContent: thirdOffice,
            })
        )
        .add(
            new ymaps.Placemark([55.75824, 37.678523], {
                balloonContent: secondOffice,
            })
        )
        .add(
            new ymaps.Placemark([55.693784, 37.564942], {
                balloonContent: firstOffice,
            })
        );
    // Добавим коллекцию на карту.
    map.geoObjects.add(collection);
    // Подпишемся на событие клика по коллекции.
    collection.events.add("click", function (e) {
        // Получим ссылку на геообъект, по которому кликнул пользователь.
        var target = e.get("target");
        // Зададим контент боковой панели.
        panel.setContent(target.properties.get("balloonContent"));
        // Переместим центр карты по координатам метки с учётом заданных отступов.
        map.panTo(target.geometry.getCoordinates(), { useMapMargin: true });
    });
});