Что такое правильный способ, чтобы уничтожить экземпляр карте?


недавно я разработал мобильное приложение html5. Приложение было одной страницей, где события изменения хэша навигации заменили весь DOM. Одним из разделов приложения была карта Google с использованием API v3. Прежде чем карта div будет удалена из DOM, я хочу удалить любые обработчики/прослушиватели событий и освободить как можно больше памяти, поскольку пользователь не может вернуться в этот раздел снова.

каков наилучший способ уничтожить экземпляр карты?

7 81

7 ответов:

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

но я недавно наткнулся на некоторую информацию, которая непосредственно касается вашего вопроса, и поэтому я хотел бы поделиться. Я не знаю, знаете ли вы об этом, но во время Google Maps API часы работы 9 мая 2012 видео, Крис Бродфут и Люк Маэ из Google обсудили этот вопрос от сайте StackOverflow. Если вы установите воспроизведение видео в 12: 50, это раздел, где они обсуждают ваш вопрос.

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

во всяком случае, просто хотел передать это и убедиться, что он включен в обсуждение stackoverflow и надеюсь, что это поможет вам и другим-

The официальный ответ - вы не. Карта экземпляры в одностраничные приложения должны использоваться повторно и тогда не уничтожили заново.

для некоторых одностраничных приложений это может означать перепроектирование решения таким образом, что после создания карты она может быть скрыта или отключена от DOM, но она никогда не уничтожается/не воссоздается.

поскольку, по-видимому, вы не можете действительно уничтожить экземпляры карты, способ уменьшить эту проблему, если

  • вам нужно показать несколько карт сразу на сайт
  • количество карт может измениться при взаимодействии с пользователем
  • карты должны быть скрыты и повторно показан вместе с другими компонентами (т. е. они не отображаются в фиксированном положении в дом)

сохраняет пул экземпляров карты. Пул отслеживает используемые экземпляры, и когда он запрашивает новый экземпляр, он проверяет, свободен ли какой-либо из доступных экземпляров карты: если это так, он вернет существующий, если это не так, он создаст новый экземпляр карты и вернет его, добавив его в пул. Таким образом, у вас будет только максимальное количество экземпляров, равное максимальному количеству карт, которые вы когда-либо показывали одновременно на экране. Я использую этот код (он требует jQuery):

var mapInstancesPool = {
 pool: [],
 used: 0,
 getInstance: function(options){
    if(mapInstancesPool.used >= mapInstancesPool.pool.length){
        mapInstancesPool.used++;
        mapInstancesPool.pool.push (mapInstancesPool.createNewInstance(options));
    } else { 
        mapInstancesPool.used++;
    }
    return mapInstancesPool.pool[mapInstancesPool.used-1];
 },
 reset: function(){
    mapInstancesPool.used = 0;
 },
 createNewInstance: function(options){
    var div = $("<div></div>").addClass("myDivClassHereForStyling");
    var map =   new google.maps.Map(div[0], options);
    return {
        map: map,
        div: div
    }
 }
}

вы передаете ему начальные параметры карты (согласно второму аргументу гуглить.карты.Конструктор карты), и он возвращает оба экземпляра карты (на котором вы можете вызывать функции, относящиеся к google.карты.Map), и контейнер, который вы можете стилизовать с помощью класса "myDivClassHereForStyling", и вы можете динамично добавить к DOM. Если вам нужно сбросить систему, вы можете использовать mapInstancesPool.сброс.)( Он сбросит счетчик до 0, сохраняя при этом все существующие экземпляры в пуле для повторного использования. В моем приложении мне нужно, чтобы удалить все карты сразу и создать новый набор карт, поэтому нет функции для переработки конкретного экземпляра карты: ваш пробег может отличаться. Чтобы удалить карты с экрана, я использую отсоединение jQuery, которое не уничтожает контейнер карты .

С помощью этой системы, и с помощью

google.maps.event.clearInstanceListeners(window);
google.maps.event.clearInstanceListeners(document);

и под управлением

google.maps.event.clearInstanceListeners(divReference[0]);
divReference.detach()

(где divReference-это объект jQuery div, возвращаемый из пула экземпляров) на каждом div, который я удаляю, мне удалось сохранить использование памяти Chrome более или менее стабильным, в отличие от него увеличивается каждый раз, когда я удаляю карты и добавляю новые.

Я бы предложил удалить содержимое карты div и использовать delete на переменной, содержащей ссылку на карту, и, вероятно, явно deleteing любые слушатели событий.

здесь признанный ошибка, хотя и это может не сработать.

поскольку google не предоставляет gunload () для api v3 лучше использовать iframe в html и назначить карту.HTML в качестве источника этого элемента. после использования сделайте src как null. Это, безусловно, освободит память, потребляемую картой.

при удалении div, что удаляет панель дисплея и карта исчезнет. Чтобы удалить экземпляр карты, просто убедитесь, что ваша ссылка на карту имеет значение null и что любые ссылки на другие части карты используется null. В этот момент JavaScript garbage collection позаботится об очистке, как описано в разделе: как работает сборка мусора в JavaScript?.

Я думаю, вы говорите о addEventListener. При удалении элементов DOM некоторые браузеры пропускают эти события и не удаляют их. Вот почему jQuery делает несколько вещей при удалении элемента:

  • он удаляет события, когда он может использовать removeEventListener. Это означает, что он сохраняет массив с прослушивателями событий, которые он добавил в этот элемент.
  • он удаляет атрибуты события (onclick,onblur и т. д.) С помощью delete на элементе DOM, когда addEventListener не доступен (тем не менее, он имеет массив, где он хранит добавленные события).
  • задает элемент null чтобы избежать утечек памяти в IE 6/7/8.
  • затем он удаляет элемент.