Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 26.04.2024, 12:22
Профессор
Отправить личное сообщение для giwuf Посмотреть профиль Найти все сообщения от giwuf
 
Регистрация: 16.05.2017
Сообщений: 165

Как правильно скопировать google карту в модальное окно и добавить в неё указатели?
Есть карта google map. Теперь я хочу скопировать и отобразить текущую карту в модальном окне bootstarp и по условию производить с ней действия (добавлять маркеры).

Но, сталкиваюсь с двумя проблемами:

Копирую с помощью функции map.getDiv() и получаю HTMLElement MapDiv карты, который помещаю внутрь компонента модального окна
modalmaped.append(map.getDiv());

Однако, исходная карта почему-то не копируется, а вырезается из исходного места (мне нужно добиться копирования)
При задании новых границ в карте, которая теперь в модальном окне
modalmaped.fitBounds(bounds);


я получаю ошибку:
Uncaught TypeError: modalmaped.fitBounds is not a function

Как это исправить?

Код
var map = "null";
var lat = 54.6786609;
var lng = 25.3077807;

function myMap() {
  var mapCanvas = document.getElementById("map");
  var mapOptions = {
    center: new google.maps.LatLng(51.508742, -0.120850),
    mapTypeId: google.maps.MapTypeId.ROADMAP,
    styles: [{
      stylers: [{
        saturation: -100
      }]
    }],
    zoom: 30
  };
  map = new google.maps.Map(mapCanvas, mapOptions);
}

document.getElementById('showMap').addEventListener('shown.bs.modal', function(event) {
  modalmaped = document.getElementById('new-map');
  modalmaped.append(map.getDiv());
  var bounds = new google.maps.LatLngBounds();
  bounds.extend(new google.maps.LatLng(lat, lng));

  if ((modalmaped !== undefined) && (modalmaped !== null)) {
    modalmaped.fitBounds(bounds);
    modalmaped.setZoom(30);

  }
});

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" />
<div id="map"></div>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#mapModal">
  Launch demo modal
</button>
<div id="mapModal" class="modal" tabindex="-1">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">Modal title</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <div id="new-map"></div>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary">Save changes</button>
      </div>
    </div>
  </div>
</div>
Ответить с цитированием
  #2 (permalink)  
Старый 26.04.2024, 15:03
Интересующийся
Отправить личное сообщение для roland Посмотреть профиль Найти все сообщения от roland
 
Регистрация: 02.11.2023
Сообщений: 20

giwuf, не подскажу с Google Maps API, это уже на Ваше время чтения документации, но укажу на проблему:

Метод Element.append вставляет узлы (Nodes), а не копирует их. Перед вставкой их нужно клонировать. Для клонирования есть метод Node.cloneNode. Но это не решит вашей проблемы, потому что API будет работать лишь с одним элементом одновременно.

Вам необходимо создать новый экземпляр карты для модального окна и при инициализации или его показе выставлять координаты, взятые из существующей карты.

Что касается ошибки, то "modalmaped" это экземпляр HTMLDivElement (элемент "div"), у которого нет метода "fitBounds". А Вы с ним пытаетесь работать, как с экземплятором Map (из Google Maps API).
Ответить с цитированием
  #3 (permalink)  
Старый 26.04.2024, 22:51
Профессор
Отправить личное сообщение для giwuf Посмотреть профиль Найти все сообщения от giwuf
 
Регистрация: 16.05.2017
Сообщений: 165

roland, за направление мыслей спасибо!
Т.е. при любых раскладах придётся создавать 2 отдельных экземпляра карты и дважды проходить по всем координатам и нет более изящного решения?
Я просто изначально так и делал, создавал два независимых экземпляра. Но, посчитал, что такой подход избыточен и потенциально может приводить к лагам во время открытия окна особенно в мобильной версии, поэтому и стал искать пути клонирования или буферизации карты с установленными маркерами.

Вот этот момент можете пояснить не очень его понял
Цитата:
API будет работать лишь с одним элементом одновременно
Мне единовременно и нужна работа с одной картой стартовой или переключаться на модальную, а при закрытии окна возвращаться обратно. Или вы как раз говорите о невозможности переключения при клонировании?
Ответить с цитированием
  #4 (permalink)  
Старый 27.04.2024, 14:09
Интересующийся
Отправить личное сообщение для roland Посмотреть профиль Найти все сообщения от roland
 
Регистрация: 02.11.2023
Сообщений: 20

giwuf, трудно посоветовать что-то конкретное, не видя дизайна и не зная логики интерфейса. Если предполагается работа только с одной картой одновременно, то почему недопустимо перемещение карты в контейнер модального окна? Вопрос в заглушке на месте основной карты? Слишком много нюансов:

Насколько сильно модальное окно перекрывает основную карту? Можно ли по дизайну сделать заглушку растровым изображением (неактуальной карты)? Насколько глубокое клонирование узла карты ресурсозатратно? Поддерживает ли Google Maps API отображение карты или конвертацию в растровое изображение (HTML5 Canvas)? Допустимо ли использовать на сайте html2canvas для создания заглушки? Были ли изучены примеры с аналогичным использованием карт на других сайтах?

Ответить на эти вопросы и принять решение может только сам разработчик интерфейсов, работая с дизайнером (если это разные люди) и открытой вкладкой Performance в DevTools, зная целевые устройства, на которых это будет использоваться.
Ответить с цитированием
  #5 (permalink)  
Старый 27.04.2024, 17:17
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,733

Признаться, я не читал всего, что вы тут понаписали, но почему не сделать как-то так?
var map = "null";
var lat = 54.6786609;
var lng = 25.3077807;

function launchGMap(container, center, options) {
    if (typeof container === 'string') {
        container = document.querySelector(container);
    }

    if (Array.isArray(center)) {
        center = new google.maps.LatLng(center[0], center[1]);
    }

    return new google.maps.Map(container, Object.assign({}, {
        center: center,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        styles: [{
            stylers: [{
                saturation: -100,
            }],
        }],
        zoom: 30,
    }, options || {}));
}

function myMap() {
    return map = launchGMap('#map', [51.508742, -0.120850]);
}

document.getElementById('showMap').addEventListener('shown.bs.modal', function() {
    modalmaped = launchGMap('#new-map', [lat, lng]);

    var bounds = new google.maps.LatLngBounds();
    bounds.extend(new google.maps.LatLng(lat, lng));

    if (modalmaped != null) {
        modalmaped.fitBounds(bounds);
        modalmaped.setZoom(30);
    }
});
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как правильно настроить Google Cloud CDN? alexriver Серверные языки и технологии 1 27.08.2020 15:01
Как правильно добавить класс при наведении mitrich38 Events/DOM/Window 9 19.09.2016 23:40
Как правильно добавить в javascript несколько стилей css? trixter5 Javascript под браузер 3 04.04.2013 23:20
Как правильно скопировать выпадающий список <select ... diiimonn Элементы интерфейса 1 13.06.2011 09:23
Как правильно добавить форму используя jQuery Casufi jQuery 1 15.02.2010 23:14