Google помещает автозаполнение, как очистить pac-контейнер?

Я использую элемент автозаполнения мест google, и он создает элемент для раскрывающегося списка с классом pac-container.

Я использую автозаполнение в приложении ember, и когда я закончил с ним элемент DOM, автозаполнение обязательно удаляется, но элемент pac-container остается, даже считал его скрытым. В следующий раз, когда я создаю новый автозаполнение, создается новый pac-container, а старый остается. Кажется, я не могу найти ничего подобного методу dispose в API, так ли это можно сделать правильно? Если я не думаю, что я должен просто использовать jquery, чтобы очистить элементы.

Ответ 1

У меня была такая же проблема, и, надеюсь, Google в конечном итоге предоставляет официальные средства очистки, но на данный момент я смог решить проблему, вручную удалив объект pac-container, ссылку на которую можно найти в Autocomplete класс, возвращаемый из:

var autocomplete = new google.maps.places.Autocomplete(element, options);

Ссылка на элемент pac-container можно найти по адресу:

autocomplete.gm_accessors_.place.Mc.gm_accessors_.input.Mc.L

Что я просто удалил из DOM в моем деструкторе виджета:

$(autocomplete.gm_accessors_.place.Mc.gm_accessors_.input.Mc.L).remove();

Надеюсь, что это поможет.


Обновление

Я не уверен, как работает обфускация Google, но части вышеизложенного кажутся запутанными и, очевидно, потерпят неудачу, если обфускация или внутренние структуры API изменится. Не могу много сделать для последнего, но для первого вы могли бы хотя бы искать свойства объекта по ожидаемым критериям. Как мы видим, некоторые имена свойств не запутаны, в то время как некоторые из них, например, "Mc" и "L". Чтобы сделать это немного более надежным, я написал следующий код:

var obj = autocomplete.gm_accessors_.place;
$.each(Object.keys(obj), function(i, key) {
  if(typeof(obj[key]) == "object" && obj[key].hasOwnProperty("gm_accessors_")) {
    obj = obj[key].gm_accessors_.input[key];
    return false;
  }
});
$.each(Object.keys(obj), function(i, key) {
  if($(obj[key]).hasClass("pac-container")) {
    obj = obj[key];
    return false;
  }
});
$(obj).remove();

Код ожидает, что общая структура останется прежней, не полагаясь на (возможно) запутанные имена "Mc" и "L". Ужасно я знаю, но, надеюсь, Google скоро исправит эту проблему.

Ответ 2

Моя реализация кода сверху без jquery.

var autocomplete = new google.maps.places.Autocomplete(element, options);

export function getAutocompletePacContainer(autocomplete) {
 const place: Object = autocomplete.gm_accessors_.place;

 const placeKey = Object.keys(place).find((value) => (
    (typeof(place[value]) === 'object') && (place[value].hasOwnProperty('gm_accessors_'))
 ));

 const input = place[placeKey].gm_accessors_.input[placeKey];

 const inputKey = Object.keys(input).find((value) => (
   (input[value].classList && input[value].classList.contains('pac-container'))
 ));

 return input[inputKey];
}

getAutocompletePacContainer(autocomplete).remove()

Ответ 3

Это работает до тех пор, пока Google не изменит имя класса.

autocomplete.addListener('place_changed', function() {

    $('.pac-container').remove();

});

Ответ 4

Построил эту рекурсивную функцию для определения положения элемента внутри объекта автозаполнения.


Получить первый соответствующий объект

var elementLocator = function(prop, className, maxSearchLevel, level) {

    level++;

    if (level === (maxSearchLevel + 1) || !prop || !(Array.isArray(prop) || prop === Object(prop))) {
        return;
    }

    if (prop === Object(prop) && prop.classList && prop.classList.contains && typeof prop.classList.contains === 'function' && prop.classList.contains(className)) {
        return prop;
    }

    for (const key in prop) {
        if (prop.hasOwnProperty(key)) {
            var element = elementLocator(prop[key], className, maxSearchLevel, level);
            if (element) {
                return element;
            }
        }
    }
};

Использование:

var elm = null;
try {
    //set to search first 12 levels, pass -1 to search all levels
    elm = elementLocator(this.autocomplete, 'pac-container', 12, null); 
} catch(e) {
    console.log(e);
}