【问题标题】:Google Places Autocomplete SearchBox: How to control (enable/disable) predictionsGoogle Places Autocomplete SearchBox:如何控制(启用/禁用)预测
【发布时间】:2016-12-31 16:19:18
【问题描述】:

是否可以控制(启用/禁用)Google Places Autocomplete SearchBox (google.maps.places.SearchBox) 服务预测?

或者换句话说:是否可以暂时从自动完成搜索框服务中分离 HTML 输入元素,然后重新附加它?

问题是我在附加到 SearchBox 服务的 HTML 输入元素下方显示服务结果。问题是在显示结果并且用户重新关注输入元素后,预测会显示在结果上并模糊他们的视图。我想禁用预测,直到用户更改输入元素中的文本。

2016 年 8 月 26 日编辑

Javascript API 目前不支持禁用预测。因此,我刚刚在 Google 上打开了一个功能请求。如果您对该功能感兴趣,请为它投票:Autocomplete SearchBox - Control (enable/disable) predictions.

编辑 2016 年 9 月 7 日 - 赏金更新

感谢所有参与回答和推广问题的人。

该奖项的主要目标是使用当前可用的方法找到解决方案。恐怕这没有发生,所以我决定不授予赏金。

虽然下面的答案都没有提供解决方案,但每个答案都提供了某种线索,所以谢谢!也许这些线索将指向未来的解决方案。

该奖项的次要目标(尽管没有直接传达)是推广Autocomplete SearchBox - Control (enable/disable) predictions 功能请求。其状态更改为 NeatIdea 并已分配内部跟踪号。这是一个好兆头。

【问题讨论】:

    标签: javascript google-maps google-maps-api-3 autocomplete google-places-api


    【解决方案1】:

    没有办法,也没有太多意义:预测是SearchBox 的全部意义,它的理由。如果你不想要预测,你可以使用Text Search in the Places library

    如果用户再次点击/关注搜索框,他/她可能不在乎被建议遮蔽的结果。谷歌地图中也有同样的行为,这不是问题,不是吗?

    如果您不能在 SearchBox 和结果之间放置一些空间(例如在 this tool 中),并且您绝对必须暂时禁用建议,我会说您可以销毁 google.maps.places.SearchBox 对象并创建一个新的一个之后,附加到同一个 HTML 输入元素。

    【讨论】:

    • 它用于移动应用程序,因此屏幕空间和键盘点击次数非常宝贵,这样我就无法将结果移动到下面并想使用SearchBox服务(Text SearchSearchBox没有预测)。销毁并重新创建 SearchBox 服务不起作用。无论如何,谢谢你的回答。
    【解决方案2】:

    您可以做的是,在用户选择地点后,您可以在该输入字段中添加一个类disabled..,这将帮助您启用/禁用基于类名称的预测。

    如果您有自动完成代码,您可以将其包装在 if else 语句中。

    let field = document.getElementById('location');
    if ( field.className.indexOf('disabled') > -1 ) {
      google.maps.event.clearInstanceListeners(field);
    }
    else {
    
      let autocomplete = new google.maps.places.Autocomplete( field, {types: ['geocode']} );
      autocomplete.addListener('place_changed', () => {
        let place = autocomplete.getPlace();
        let filed_val = field.value; // incase you need it
        field.classList.add('disabled');
      });
    
    }
    

    这将在用户选择一个地点后删除自动完成功能。以后如果需要,您可以从该字段中删除 disabled 类,它会再次起作用。

    【讨论】:

    • 虽然您使用google.maps.places.Autocomplete 而不是google.maps.places.SearchBox,但我理解您的示例的含义。我不喜欢它通过在旧服务对象仍在内存中时创建新服务对象来重新启用预测。理想的做法是在旧对象上重新启用 DOM 事件。
    • 没错,做最理想的,适合你需要的,这只是向你展示其中一种方法......
    【解决方案3】:

    我在 AngularJS 中的解决方案——它是一个指令的摘录。

    .pac-contained 在创建自动完成服务实例后创建,例如:new google.maps.places.Autocomplete(…)new google.maps.places.SearchBox(…)

    我所做的是在文档中找到刚刚创建的.pac-container,存储它的引用并将该容器标记为已处理(通过在其上添加任意类.predictions-control)。仅当应用程序中预计存在多个 .pac-container 时才需要“标记”容器。

    现在有了参考,我可以通过预测控制.pac-contained 的可见性(隐藏或显示)。

    // Container element with predictions.
    var pacContainer = null;
    
    /***
     * Find predictions container without predictions-control class set.
     * Then set  predictions-control class to it and convert it into
     * Angular's jqLite object.
     * @return {jqLite object} - container or null when not found.
     */
    function getPredictionsContainer() {
        // Get div.pac-container without predictions-control class.
        var e = document.querySelector('div.pac-container:not(.predictions-control)');
        if (e){
            var container = angular.element(e);
            container.addClass('predictions-control');
            console.log('predictions-control: Container found.');
            return container;
        } else {
            console.warn('predictions-control: Container not found!');
        }
        return null;
    } // getPredictionsContainer
    
    /***
     * Loop in 50ms intervals until container is found.
     */
    function untilContainerFound(){
        pacContainer = getPredictionsContainer();
        if (pacContainer == null){
            $timeout(untilContainerFound, 50);
        }
    } // untilContainerFound
    
    this.init = function() {
        untilContainerFound();
    }; // this.init
    
    /***
     * Prevent predictions to be displayed when user clicks on the
     * input element. It is achieved by adding ng-hide CSS class to
     * predictions container. Predictions container is identified by
     * ".pac-container" CSS class selector.
     */
    this.hidePredictions = function() {
        // If predictions container was not found at directive
        // initialization try to find it now.
        if (pacContainer === null){
            pacContainer = getPredictionsContainer();
        }
        if (pacContainer){
            console.log('predictions-control: Hiding predictions.');
            pacContainer.addClass('ng-hide');
        } else {
            console.warn('predictions-control: Container not found!');
        }
    }; // this.hidePredictions
    
    /***
     * Show predictions again by removing ng-hide CSS class from
     * predictions container.
     */
    this.showPredictions = function() {
        console.log('predictions-control: Showing predictions.');
        if (pacContainer){
            pacContainer.removeClass('ng-hide');
        }
    }; // this.showPredictions
    

    在服务实例创建后立即调用init()

    // Create SearchBox service for auto completing search terms.
    autocomplete = new google.maps.places.SearchBox( inputElem[0] );
    // OR
    // autocomplete = new google.maps.places.Autocomplete( ..... );
    autocomplete .addListener('places_changed', callback);
    
    predictionsCtrl.init();
    

    注意: 只要保证不会同时创建两个自动完成服务(例如:每个服务都在不同的选项卡上)或者可以等待创建下一个服务直到找到上一个服务的.pac-container,它即使在使用自动完成服务的多个实例。

    【讨论】:

      【解决方案4】:

      可能有价值的信息。

      这与 API V3.29 相关(不确定它是否始终准确)。
      API 为自动完成创建的 div 元素具有“pac-container pac-logo”类。
      利用 document.querySelector('.pac-container') 您可以将其样式属性设置为 display: none 在其他地方的点击事件中。

      注意:当您的用户在 searchBox 中单击返回时,google 会将样式属性更改回适当的值,因此您只需设置一次,无需再次设置。
      (这可能比涉及角度更容易和更清洁)。

      希望对某人有所帮助(我必须添加一条 CSS 规则来增加应用程序中的 z-index 以显示自动完成功能)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-10
        • 1970-01-01
        • 2016-06-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-01-25
        相关资源
        最近更新 更多