【问题标题】:InvalidValueError: not an instance of HTMLInputElementInvalidValueError:不是 HTMLInputElement 的实例
【发布时间】:2016-03-07 21:59:07
【问题描述】:

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

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

代码保持不变。设计改变了。输入字段的 id 和 name 也相同。 JS代码没有变化。但这东西行不通。

这是website

Google 地图出现错误。

 InvalidValueError: not an instance of HTMLInputElement

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

可能的原因是什么?

代码如下:

        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>

谷歌地图

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

【问题讨论】:

  • 显示您的代码...请不要只显示错误
  • 请添加html相关代码..错误似乎与标签ID有关
  • 我没有看到地图 div id=source_map 的 html 源代码
  • 添加地图 div @scaisEdge

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


【解决方案1】:

InvalidValueError 也会在您尝试在 iframe 中配置 Google 地方信息自动完成时发生。如果您从父 DOM 执行此操作,则会收到此错误,因为:

如果您的应用是少数使用具有跨窗口 DOM 检查(或类似)的多个窗口的应用之一,则 window.HTMLInputElement === otherWindow.HTMLInputElement 将为 false,因此 instanceof 运算符也可能意外返回 false。也适用于 iframe 和弹出窗口。在这些情况下,检查 tagName 可以工作,正如已经提到的其他答案。 – 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();
  });
});

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      在学习 Google 教程时遇到了同样的问题。就我而言,问题出在async 关键字上,它导致Google Maps 脚本在页面的其余部分继续解析时异步执行。这是修复:

      1. 将 Google 地图脚本放在相关的 HTML 元素之后(如 Prashant 所指出的那样)
      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)。

      【讨论】:

        【解决方案4】:

        您的字段是TEXTAREA,从上次更新开始,谷歌地图自动完成现在只支持window.HTMLInputElement (INPUT tag)

        【讨论】:

        • 你知道为什么 google 停产了吗?有官方链接吗?
        • o m g。谢谢你.. 花几个小时修改我的代码。这就是解决方案。将
        • 我没有文本区域,但输入标签仍然出现此错误
        【解决方案5】:

        对于角

        我在ngOnInit() 中初始化autocomplete,因此我收到了错误。 我只是将初始化移动到ngAfterViewInit(),一切正常。

        代码:

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

        【讨论】:

          【解决方案6】:

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

          想法是添加一个自定义的textarea,并将原始输入文本值绑定到textarea(带有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 来“隐藏”原始输入。它会隐藏你在输入中写的内容,然后你只会看到你的 textarea 中写的内容(重要提示:输入的 z-index 必须优于 textarea 之一!

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

          它远非完美,如果有人有更好的解决方案,我很乐意!

          【讨论】:

            【解决方案7】:

            .pac 容器 { z-index:1051!重要; }

            【讨论】:

              【解决方案8】:

              我在 Angular2 中遇到了同样的问题。我的解决方案是将谷歌地图的初始化移动到当用户关注自动完成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>
              

              【讨论】:

                【解决方案9】:

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

                确保您的 html 元素先加载,然后仅加载 javascript。

                喜欢

                然后

                你的 JavaScript 代码

                【讨论】:

                  【解决方案10】:

                  这是我在学习 Google 教程时遇到的问题。 问题是您应该在页面加载后执行javascript,您可以在调用Google Map脚本时调用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 Maps API 的操作,例如 document.getElementById('source_map') 以及属于 google 类的所有方法。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2017-11-25
                    • 1970-01-01
                    • 2020-10-04
                    • 1970-01-01
                    • 1970-01-01
                    • 2019-11-02
                    • 2019-07-17
                    • 1970-01-01
                    相关资源
                    最近更新 更多