InvalidValueError: not an instance of HTMLInputElement

InvalidValueError: not an instance of HTMLInputElement

仅供参考,我不是 JavaScript 忍者,但最近我根据 Google 地图做了很多事情,感觉我会成为忍者。

我实现了一张地图。用户可以搜索 google 个地点并为其放置标记。有一个文本框。或者用户可以点击地图将标记放置到他要寻找的地方或拖动标记。

代码保持不变。设计改变了。输入字段的 ID 和名称也相同。没有更改 JS 代码。但是这东西没用。

这是website

Google 地图产生错误。

 InvalidValueError: not an instance of HTMLInputElement

我尝试了给定的解决方案 但是错误仍然存​​在。

可能的原因是什么?

代码如下:

        var map;
        var marker;
        var latLngC;

        function initialize() 
        {
            latLngC = new google.maps.LatLng(14.5800, 121.0000);
            var mapOptions = {
        center: latLngC,
        zoom: 12,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        };

            map = new google.maps.Map(document.getElementById('source_map'),
        mapOptions);

        var marker = new google.maps.Marker({
                position: latLngC,
                map: map,
                draggable: true
            });

            google.maps.event.addListener(marker, 'dragend', function (x) 
            {
            document.getElementById('src_lat').value = x.latLng.lat();
            document.getElementById('src_long').value = x.latLng.lng();
            document.getElementById('pickup_location').innerHTML = x.latLng.lat()+' , '+x.latLng.lng();
                var geocoder = new google.maps.Geocoder;
                var infowindow = new google.maps.InfoWindow;                
            geocodeLatLng(geocoder, map, infowindow,x.latLng.lat(),x.latLng.lng(),'source_point');
            }); 

            //Get coordinates,address Upon clicking a location in map (Source Map)
            //By Sajeev
            google.maps.event.addListener(map, 'click', function(x) 
            {
            document.getElementById('src_lat').value = x.latLng.lat();
            document.getElementById('src_long').value = x.latLng.lng();
            document.getElementById('pickup_location').innerHTML = x.latLng.lat()+' , '+x.latLng.lng();
                var geocoder = new google.maps.Geocoder;
                var infowindow = new google.maps.InfoWindow;                
            geocodeLatLng(geocoder, map, infowindow,x.latLng.lat(),x.latLng.lng(),'source_point');
            });

        //Add marker upon clicking on map
            //google.maps.event.addDomListener(map, 'click', addMarker);
            google.maps.event.addDomListener(map, 'click', function() { addMarker(map); }); 



        var places1 = new google.maps.places.Autocomplete(document.getElementById('source_point'));
        google.maps.event.addListener(places1, 'place_changed', function () {
            var place1 = places1.getPlace();

            var src_addr = place1.formatted_address;
            var src_lat = place1.geometry.location.lat();
            var src_long = place1.geometry.location.lng();

            var mesg1 = "Address: " + src_addr;
            mesg1 += "\nLatitude: " + src_lat;
            mesg1 += "\nLongitude: " + src_long;
            //alert(mesg1);

                 document.getElementById('src_lat').value = src_lat;
            document.getElementById('src_long').value = src_long;
            document.getElementById('pickup_location').innerHTML = src_lat+' , '+src_long;                 
        });
        //Add marker upon place change
        //google.maps.event.addDomListener(places1, 'place_changed', addMarker);            
            google.maps.event.addDomListener(places1, 'place_changed', function() { addMarker(map); }); 

        }
        google.maps.event.addDomListener(window,'resize',initialize);
        google.maps.event.addDomListener(window, 'load', initialize); 

我的 HTML 代码如下所示:

   <form role="form" id="frm_source" name="frm_source" method="POST" action="index_action.php">

        <div class="form-group">
            <label for="source_point"><h2>Pickup Address</h2></label>
            <textarea type="text" id="source_point" name="source_point"  class="form-control" placeholder="Enter your pick up address here"></textarea>
        </div>

        <div class="form-group">
            <label for="pickup_location"><h3>GPS Cordinates</h3></label>
            <hr>
            <p id="pickup_location"></p>
        </div>

        <div class="form-group">
            <input type="hidden" id="src_lat" name="src_lat" placeholder="latitude" >
            <input type="hidden" id="src_long" name="src_long" placeholder="longitude" >
        </div>

    <input type="submit" name="submit" id="submit" class="btn btn-primary" value="Next to enter destination address" />
    </form>

Google地图

<div id="source_map"></div>

您的字段是 TEXTAREA,根据上次更新,google 地图自动完成现在仅支持 window.HTMLInputElement (INPUT tag)

这是我在学习 Google 上的教程时遇到的问题。 问题是你应该在页面加载后执行 javascript,你可以在调用 Google 映射脚本时调用 GET 参数上的函数:

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places$callback=YourFunctionHere"></script>

YourFunctionHere是一个回调函数,意味着它只会在页面加载后执行。

或者您可以在页面加载后调用函数。示例:window.onload = Yourfunction();

现在,在该函数中,您可以执行 Google 映射 API 之类的 document.getElementById('source_map') 以及属于 google class 的所有方法].

这是 DOM 的问题。您的 javascript 在加载您的 html 文档之前加载。

确保先加载 html 元素,然后只加载 javascript。

喜欢

然后

您的 javascript 代码

我在 Angular2 中遇到了同样的问题。我的解决方案是将 Google 地图的初始化移动到一个函数,该函数在用户聚焦于自动完成 input 字段时触发。不是最漂亮的解决方案,但它有效。

代码:

private autocomplete_init: boolean: false;

autocompleteFocus() {
 this.autocomplete_init = true;
 if (!this.autocomplete_init) {
  this._autocomplete = new google.maps.places.Autocomplete(document.getElementById("search_address"), {
  componentRestrictions: {'country': 'dk'}
  }
}

HTML:

<input placeholder="Search" type="text" id="search_address" (focus)="autocompleteFocus()" autofocus>

.pac-container { z-index: 1051 !important; }

几天前我遇到了同样的问题,但我找到了解决方案,如果有人感兴趣的话 :) 它并不完美,非常 棘手,但确实如此95%的工作!我知道这是一个非常古老的话题,但如果它可以拯救某人...

想法是添加一个自定义文本区域,并将原始输入文本值绑定到文本区域(使用 keyup、keypress、keydown、change 事件)。

$('.MyInput').on('keyup keydown keypress change', function() {
  $('myTextarea').val($(this).val());
  emptyPlaceholder($(this), 'Myplaceholder text');
});

function emptyPlaceholder(input, placeholder) {
     // The placeholder of the textarea will hide if the input has a value
     if (input.val().length) {
         $('#triggerInput').attr('placeholder', '');
     } else {
         $('#triggerInput').attr('placeholder', placeholder);
     }
 }

添加一些 css 以“隐藏”原始输入。它会隐藏你在输入中写的内容,然后你只会看到你的文本区域中写的内容(重要:输入的 z-index 必须优于文本区域之一!)

.MyInput {
   color: transparent;
   background-color: transparent; 
}

它远非完美,如果有人有更好的解决方案,我会开放!

For Angular

我正在初始化 ngOnInit() 中的 autocomplete,因此出现错误。 我只是将初始化移动到 ngAfterViewInit() 并且一切正常。

代码:

  ngAfterViewInit(): void {
    this.autocomplete = new google.maps.places.Autocomplete(
      (this._document.getElementById('input')),
      { types: ['geocode'] }
    );
  }

在遵循 Google 教程时遇到了同样的问题。在我的例子中,问题原来是 async 关键字,它导致 Google 地图脚本异步执行,而页面的其余部分继续解析。这是修复:

  1. 将 Google 地图脚本 放在 相关 HTML 元素之后(如 所指出)
  2. 使用 defer 关键字 而不是 async 关键字调用 Google 地图脚本。代码:
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places$callback=YourFunctionHere" defer></script>

使用defer确保脚本在页面解析完成时执行(source)。

在我的例子中,错误的原因是 google.maps.ControlPosition 运行 不止一次。我的 google 地图以模式显示。在我第一次打开模态时,一切正常,但下一次,这个错误出现了。 我的解决方案:只初始化一次地图。

constructor(props) {
        super(props);
        this.state = {
            lat: null,
            lng: null,
            visible: false,
            inited: false
        };
        this.initMap = this.initMap.bind(this);
        this.setModalVisible = this.setModalVisible.bind(this);
    }

    setModalVisible(status) {
        if (!this.state.inited) {
            //Khi chưa init map lần nào (chưa từng mở modal)
            this.setState(
                {
                    visible: true,
                    inited: true
                },
                () => {
                    this.initMap();
                }
            );
        } else {
            // Khi đã init, đóng/mở modal mà k cần init lại
            this.setState({
                visible: status
            });
        }
    }
    initMap() {
        if (this.state.visible) {
            let map = new google.maps.Map(document.getElementById("map"), {
                center: { lat: 21.0277644, lng: 105.8341598 },
                zoom: 10
            });
            const card = document.getElementById("pac-card");
            const input = document.getElementById("pac-input");
            const options = {
                fields: ["formatted_address", "geometry", "name"],
                origin: map.getCenter(),
                strictBounds: false
            };
            map.controls[google.maps.ControlPosition.TOP_CENTER].push(card);
            const autocomplete = new google.maps.places.Autocomplete(
                input,
                options
            );
            autocomplete.bindTo("bounds", map);
            const infowindow = new google.maps.InfoWindow();
            const infowindowContent = document.getElementById(
                "infowindow-content"
            );
            infowindow.setContent(infowindowContent);
            var marker = new google.maps.Marker({
                map
            });
            google.maps.event.addListener(map, "click", e => {
                console.log(e);
                var latLng = e.latLng;
                this.setState({
                    lat: e.latLng.lat(),
                    lng: e.latLng.lng()
                });
                console.log(latLng.lat(), latLng.lng());
                if (marker && marker.setMap) {
                    marker.setMap(null);
                }
                marker = new google.maps.Marker({
                    position: latLng,
                    map: map
                });
            });
            autocomplete.addListener("place_changed", () => {
                infowindow.close();
                const place = autocomplete.getPlace();
                console.log(place);

                if (!place.geometry || !place.geometry.location) {
                    window.alert(
                        "Không tìm thấy vị trí " +
                            place.name +
                            " .Vui lòng chọn trên bản đồ."
                    );
                    return;
                }
                this.setState({
                    lat: place.geometry.location.lat(),
                    lng: place.geometry.location.lng()
                });
                if (marker && marker.setMap) {
                    marker.setMap(null);
                }
                marker = new google.maps.Marker({
                    position: place.geometry.location,
                    map: map
                });
                map.setZoom(16);
                infowindowContent.children["place-name"].textContent =
                    place.name;
                infowindowContent.children["place-address"].textContent =
                    place.formatted_address;
                infowindow.open(map, marker);
            });
        }
    }
当您尝试在 iframe 中配置 Google Places Autocomplete 时,

InvalidValueError 也会发生。如果您从父级 DOM 执行此操作,您将收到此错误,因为:

if your app is one of those rare ones that use multiple windows with cross-window DOM inspection (or similar), window.HTMLInputElement === otherWindow.HTMLInputElement will be false, thus the instanceof operator may also unexpectedly return false. Applies to iframes and popup windows as well. In those cases, checking tagName can work, as other answers already mentioned. – John Weisz

解决方法有两个:

  1. 将 Google 脚本注入 iframe。
  2. 使用 iframe.contentWindow 获取 iframe window 对象并从中调用 google.maps.places.Autocomplete()

这是一个例子:

var GOOGLE_API_KEY = 'fill-me';
var AUTOCOMPLETE_CONFIG = { /* fill-me */  };
function handlePlaceSelect() { /* fill-me */  }

var iframeWindow = iframe.contentWindow;
var iframeDocument = iframe.contentDocument;

var googleScript = document.createElement("script");
googleScript.type = "text/javascript";
googleScript.src = "https://maps.googleapis.com/maps/api/js?key=" + GOOGLE_API_KEY + "&libraries=places";
iframeDocument.body.appendChild(googleScript);

googleScript.addEventListener('load', function() {
  autoComplete = new iframeWindow.google.maps.places.Autocomplete(addressInput, AUTOCOMPLETE_CONFIG);
  autoComplete.addListener("place_changed", function () {
    handlePlaceSelect();
  });
});

我知道我回答这个问题晚了,但这可能对某人有帮助:

而不是使用 Jquery 获取元素:

    var autocomplete = new google.maps.places.Autocomplete($("#Location"));

做这样的事情对我有用:

    var input = document.getElementById('Location');
    var autocomplete = new google.maps.places.Autocomplete(input);