Вывести стандартный балун яндекс карт по клику

Существует ли простой способ, например в конфигурации карт, добавить по клику на любое место карты стандартный балун, который появляется по клику на Яндекс.Картах с описанием места? Или для этого нужно обязательно писать свой кастомный балун?
Отслеживать
2,326 2 2 золотых знака 11 11 серебряных знаков 39 39 бронзовых знаков
задан 13 июн 2019 в 15:58
Константин Константин
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
В JS API Яндекс.Карт есть стандартный балун, но вот, какой именно контент в нём выводить, придётся определить самому. Из коробки балун как на самих Яндекс.Картах получить не удастся.
Как сделать балун с адресом по клику на карте
У карты есть событие click , которое вам нужно слушать, и метод карты balloon.open() , который позволяет открыть на ней стандартный балун. Вот тут есть интерактивный пример
Чтобы вывести адрес в точке клика нужно добавить обратное геокодирование:
myMap.events.add('click', function (e) < if (!myMap.balloon.isOpen()) < var coords = e.get('coords'); ymaps.geocode(coords).then(function (res) < var firstGeoObject = res.geoObjects.get(0); myMap.balloon.open(coords, < contentHeader: firstGeoObject.getAddressLine(), contentBody: 'Координаты щелчка: ' + [ coords[0].toPrecision(6), coords[1].toPrecision(6) ].join(', ') + '
' >) >); > else < myMap.balloon.close(); >>);
Как добавить свои кнопки в балун
Чтобы в балуне появились кнопки, например, «маршрут» и «искать рядом», нужно создать свой макет балуна. В песочнице Яндекса есть подробный пример.
В целом, кастомный макет позволяет полностью видоизменить стандартный балун — настроить его под свой дизайн или повторить дизайн Яндекс.Карт.
Кроме того, потребуется провязать кнопки с контролами на карте. То есть отдельно добавить интерфейс построения маршрутов и строку поиска.
Как задать смещение балуна относительно метки?
Пытаюсь сместить балун относительно метки в Yandex map API, но не получается:
myMap.setCenter(coordinates, 16); var placemark = new ymaps.Placemark(coordinates,< balloonContentHeader: 'qwefgh', balloonOffset: [0,40], >); myMap.geoObjects.add(placemark); placemark.balloon.open();
Как можно сместить балун относительно метки?
Отслеживать
задан 18 окт 2022 в 9:44
75 6 6 бронзовых знаков
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
Как я понял balloonOffset находится в options, и его надо было вывести в отдельные фигурные скобки.
var placemark = new ymaps.Placemark(coordinates,< balloonContentHeader: 'qwefgh', >, );
Отслеживать
ответ дан 18 окт 2022 в 9:51
75 6 6 бронзовых знаков
это не вынести в отдельные фигурные скобки, а третий параметр конструктора. Если вы документацию прочиатете, то первый — коордианиы, потом properties, потом options. Вот доп.опции баллуна написано надо укзазывать в третьем параметре с префиксом. yandex.ru/dev/maps/jsapi/doc/2.1/ref/reference/…
18 окт 2022 в 9:54
Спасибо, уже разобрался
Yandex Maps. Карта с кастомным балуном центрируется только при втором клике, если текст в балуне ограничен по ширине. Почему?

При клике на кнопку «На карте», всегда открывается кастомный балун и карта центрируется на нём, в стилях кастомному балуну ymaps[class$=»-balloon__content»] задал max-width 250, балун должен быть именно такой ширины. При этом дочерний элемент ymaps получает ширину в зависимости от текста, и если длина текста больше, он выходит за балун, а не переносится.
Если к тексту или к любым его родительским классам ymaps добавлять width/max-width и т.д, или же как предлагается документацией yaMap https://yandex.ru/dev/maps/jsapi/doc/2.1/ref/refer. , ограничивать размер балуна через minWidth MaxWidth и т.п., это работает и текст корректно переносится.
Но здесь появляется баг, при первом клике по кнопке «На карте», всё ок, если нажать на любую другую, балун открывается, но карта на нём не центрируется, а остаётся в предыдущем положении, при повторном клике или дабл-клике, всё открывается корректно. Как сделать без костылей так, чтобы текст переносился нормально, и можно было переключаться по разным адресам с первого клика?
function yaMapInit() < const yaMapContainer = document.getElementById('yaMapStorages'); // Инициализируем Яндекс карты const myMap = new ymaps.Map('yaMapStorages', < center: [34.76, 37.64], zoom: 10, // Опции скролла при взаимодействии с картой: двигаем карту, зум +/- по дабл-клику мышкой, масштабирование мультисенсорным касанием behaviors: [ "drag", "dblClickZoom", "multiTouch" ], // Элементы управления: зум, геолокация controls: [ 'zoomControl', 'geolocationControl' ], >, < // Отрубаем все не нужное на карте suppressMapOpenBlock: true, // Отключаем дефолтное позиционирование кнопки геолокации на экране geolocationControlFloat: 'none', // Отключаем все метки карты, кроме собственных yandexMapDisablePoiInteractivity: true, // Задаём позиционирование геолокации position: < top: '10px', right: '10px', >, // Задаём позиционирование Скролл-зума карты zoomControlPosition: < right: '20px', bottom: '40px' >>); // ObjectManager - Инструмент для добавления большого числа объектов на карту const objectManager = new ymaps.ObjectManager( // Опции < // Чтобы метки начали кластеризоваться (объединяться), выставляем опцию. clusterize: true, // При каком зуме объединять метки в группу maxZoom: 18, // Отступы от края карты zoomMargin: 100, >); // Отключаем scrollZoom myMap.behaviors.disable(['scrollZoom']); // Дополняем опции objectManager const markIconMap = < iconLayout: 'default#image', // Своё изображение иконки метки. iconImageHref: '', // Размеры метки. iconImageSize: [24, 33], //iconImageOffset: [-20, -53], >; objectManager.objects.options.set(markIconMap); myMap.geoObjects.add(objectManager); myMap.geoObjects.add(placemark); // Объект меток, с координатами, кастомными балунами const pointsObjMsk = JSON.parse(document.getElementById('pointsObj').textContent); if (pointsObjMsk.features.length >= 1) < // Добавляем данные с метками в коллекцию objectManager objectManager.add(pointsObjMsk); if (pointsObjMsk.features.length === 1) < // Если на карте всего 1 метка, устанавливаем корректный зум для этой метки myMap.setCenter(pointsObjMsk.features[0].geometry.coordinates, 12); >else < // Центрируем карту по всем меткам, устанавливаем в опциях минимальные отступы для точек от границ карты. myMap.setBounds(myMap.geoObjects.getBounds(), < // Отступы от края карты zoomMargin: 100, checkZoomRange: true, >); > // Контейнер с хранилищами и картой const mapAndStorages = yaMapContainer.closest('.map-and-storages'); if (mapAndStorages) < // Скрываем карту на экранах < 768px if (window.innerWidth < 768) < const tabMapTarget = mapAndStorages.querySelector('#tab-map-target'); if (tabMapTarget) tabMapTarget.classList.remove('active', 'show'); >// Ищем объект на карте по клику на контейнер const buttons = mapAndStorages.querySelectorAll('.show-container-in-map'); // Кнопка, которая открывает таб с картой if (buttons && buttons.length > 0) < const buttonTabMap = mapAndStorages.querySelector('button[data-bs-target="#tab-map-target"]'); buttons.forEach(el => < el.addEventListener('click', () =>< if (window.innerWidth < 768) buttonTabMap.click(); const cardContainer = el.closest('.card-container'); if (cardContainer) < const idContainer = cardContainer.getAttribute('data-id-container'), coords = < x: cardContainer.getAttribute('data-x'), y: cardContainer.getAttribute('data-y') >, balloonInfo = pointsObjMsk.features[idContainer].properties; // показываем точку, меняем зум при необходимости myMap.setCenter([coords.x, coords.y], 13); const markIconMapContainer = < contentHeader: balloonInfo.balloonContentHeader, contentBody: balloonInfo.balloonContentBody, contentFooter: balloonInfo.balloonContentFooter, clusterCaption: balloonInfo.clusterCaption, hintContent: balloonInfo.hintContent, >// Показываем конкретный объект на карте Object.assign(markIconMapContainer, markIconMap); // При экране < 768px врубаем задержку для качественного рендеринга if (window.innerWidth < 768) < setTimeout(() =>< myMap.balloon.open( myMap.getCenter(), markIconMapContainer ); >, 100); > else < myMap.balloon.open( myMap.getCenter(), markIconMapContainer, < /* minWidth: '250px', minHeight: '1px',*/ >); > > >); >); > > // Скрываем лоадер const yaMapLoader = yaMapContainer.querySelector('img.map-loader'); if (yaMapLoader) < yaMapLoader.remove(); >> >
#yaMapStorages < position: absolute; top: 0; bottom: 0; left: 0; width: 100%; height: 100%; @include max_768 < position: relative; height: 600px; >img.map-loader < position: absolute; right: 0; left: 0; top: 0; bottom: 0; max-width: 150px; margin: auto; >>ymaps < //width: 100% !important; >ymaps[class$="-balloon-content__header"] < margin: 0; >ymaps[class$="-balloon-content__footer"] < margin: 0; >ymaps[class$="-balloon__content"] < ymaps <>width: 100%; max-width: 250px; padding: 0; margin-right: 0; .baloon__link < text-decoration: underline; &:hover < text-decoration: none; color: black; >> .baloon__image < width: 250px; height: 140px; object-fit: cover; object-position: center; >strong < @include rg-font-style('bold'); >p < @include px-to-rem(16); //width: 250px; >h3 < background-color: #f3f3f3; @include px-to-rem(20); text-align: left; padding: 10px; +p < margin-bottom: 0; padding: 10px; >> > ymaps[class$="-balloon__close"] < background-color: white; width: 20px; height: 20px; border-radius: 25px; border: 1px solid black; top: 5px; right: 5px; >ymaps < width: 20px; height: 20px; background-size: 10px; >> >
- Вопрос задан более года назад
- 424 просмотра
Размещение балуна от метки справа, яндекс карты?
Всем доброго времени суток!
Суть проблемы такова: имеется карта, на ней есть метки и собственно балуны у них.
Не могу найти и понять вообще как сдвинуть балун вот таким образом: joxi.ru/krDk3L0t07zR9A
Подскажите пожалуйста, буду очень признателен:)
- Вопрос задан более трёх лет назад
- 4780 просмотров
Комментировать
Решения вопроса 1

Big_person @Big_person
Замените
на
и поправьте позиционирование:
applyElementOffset: function () < this._$element.css(< top: -(this._$element[0].offsetHeight/2) >); >,
ymaps.ready(function () < // Создание экземпляра карты и его привязка к созданному контейнеру. var myMap = new ymaps.Map('map', < center: [55.751574, 37.573856], zoom: 9, behaviors: ['default', 'scrollZoom'] >, < searchControlProvider: 'yandex#search' >), // Создание макета балуна на основе Twitter Bootstrap. MyBalloonLayout = ymaps.templateLayoutFactory.createClass( '' + '×' + ' ' + '' + '$[[options.contentLayout observeSize minWidth=235 maxWidth=235 maxHeight=350]]' + '' + '', < /** * Строит экземпляр макета на основе шаблона и добавляет его в родительский HTML-элемент. * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/layout.templateBased.Base.xml#build * @function * @name build */ build: function () < this.constructor.superclass.build.call(this); this._$element = $('.popover', this.getParentElement()); this.applyElementOffset(); this._$element.find('.close') .on('click', $.proxy(this.onCloseClick, this)); >, /** * Удаляет содержимое макета из DOM. * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/layout.templateBased.Base.xml#clear * @function * @name clear */ clear: function () < this._$element.find('.close') .off('click'); this.constructor.superclass.clear.call(this); >, /** * Метод будет вызван системой шаблонов АПИ при изменении размеров вложенного макета. * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/IBalloonLayout.xml#event-userclose * @function * @name onSublayoutSizeChange */ onSublayoutSizeChange: function () < MyBalloonLayout.superclass.onSublayoutSizeChange.apply(this, arguments); if(!this._isElement(this._$element)) < return; >this.applyElementOffset(); this.events.fire('shapechange'); >, /** * Сдвигаем балун, чтобы "хвостик" указывал на точку привязки. * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/IBalloonLayout.xml#event-userclose * @function * @name applyElementOffset */ applyElementOffset: function () < this._$element.css(< top: -(this._$element[0].offsetHeight/2) >); >, /** * Закрывает балун при клике на крестик, кидая событие "userclose" на макете. * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/IBalloonLayout.xml#event-userclose * @function * @name onCloseClick */ onCloseClick: function (e) < e.preventDefault(); this.events.fire('userclose'); >, /** * Используется для автопозиционирования (balloonAutoPan). * @see https://api.yandex.ru/maps/doc/jsapi/2.1/ref/reference/ILayout.xml#getClientBounds * @function * @name getClientBounds * @returns Координаты левого верхнего и правого нижнего углов шаблона относительно точки привязки. */ getShape: function () < if(!this._isElement(this._$element)) < return MyBalloonLayout.superclass.getShape.call(this); >var position = this._$element.position(); return new ymaps.shape.Rectangle(new ymaps.geometry.pixel.Rectangle([ [position.left, position.top], [ position.left + this._$element[0].offsetWidth, position.top + this._$element[0].offsetHeight + this._$element.find('.arrow')[0].offsetHeight ] ])); >, /** * Проверяем наличие элемента (в ИЕ и Опере его еще может не быть). * @function * @private * @name _isElement * @param [element] Элемент. * @returns Флаг наличия. */ _isElement: function (element) < return element && element[0] && element.find('.arrow')[0]; >>), // Создание вложенного макета содержимого балуна. MyBalloonContentLayout = ymaps.templateLayoutFactory.createClass( '$[properties.balloonHeader]' + '$[properties.balloonContent]' ), // Создание метки с пользовательским макетом балуна. myPlacemark = window.myPlacemark = new ymaps.Placemark(myMap.getCenter(), < balloonHeader: 'Заголовок балуна', balloonContent: 'Контент балуна' >, < balloonShadow: false, balloonLayout: MyBalloonLayout, balloonContentLayout: MyBalloonContentLayout, balloonPanelMaxMapArea: 0 // Не скрываем иконку при открытом балуне. // hideIconOnBalloonOpen: false, // И дополнительно смещаем балун, для открытия над иконкой. // balloonOffset: [3, -40] >); myMap.geoObjects.add(myPlacemark); >); $(function () < $('#set-balloon-header').click(function () < window.myPlacemark.properties.set( 'balloonHeader', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.' + 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' ); >); $('#set-balloon-content').click(function () < window.myPlacemark.properties.set( 'balloonContent', 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.' + 'Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.' ); >); >);