web-dev-qa-db-ja.com

グーグルはオートコンプリートを配置します、pac-containerをクリーンアップする方法は?

私はグーグルプレイスのオートコンプリートコントロールを使用しています、そしてそれはクラスpac-containerでドロップダウンのための要素を作成します。

emberアプリでオートコンプリートを使用しています。使い終わると、オートコンプリートがバインドされているDOM要素は削除されますが、pac-container要素は残ります。次回、新しいオートコンプリートをインスタンス化すると、新しいpac-containerが作成され、古いものが残ります。APIでdisposeメソッドのようなものが見つからないようですので、その方法はありますか。これは正しくありますか?そうでない場合は、jqueryを使用して要素をクリアする必要があると思います。

18
Charlie

私は同じ問題を抱えていました、そしてうまくいけばグーグルは最終的にクリーンアップの公式の手段を提供します、しかし今のところ私は手動でpac-containerオブジェクトを削除することによって問題を解決することができました、それへの参照はから返されたオートコンプリートクラスにあります:

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はこの問題をすぐに修正します。

6
Lachlan

上記のコード 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()
2
Driver

これは今のところ機能しますGoogleがクラス名を変更するまで

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

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

});
1
Milk Man

オートコンプリートオブジェクト内の要素の位置を特定するために、この再帰関数を作成しました。


最初に一致するオブジェクトを取得する

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);
}
0
rovercoder