При клике на кнопку "На карте", всегда открывается кастомный балун и карта центрируется на нём, в стилях кастомному балуну ymaps[class$="-balloon__content"] задал max-width 250, балун должен быть именно такой ширины. При этом дочерний элемент ymaps id="@#!%RT" получает ширину в зависимости от текста, и если длина текста больше, он выходит за балун, а не переносится.
Если к тексту или к любым его родительским классам 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;
}
}
}