InvalidValueError:不是 HTMLInputElement 的实例

Posted

技术标签:

【中文标题】InvalidValueError:不是 HTMLInputElement 的实例【英文标题】:InvalidValueError: not an instance of 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 【参考方案1】:

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

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

解决方案有两个:

    将 Google 脚本注入 iframe。 使用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 脚本在页面的其余部分继续解析时异步执行。这是修复:

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

【讨论】:

以上是关于InvalidValueError:不是 HTMLInputElement 的实例的主要内容,如果未能解决你的问题,请参考以下文章

未捕获的 InvalidValueError:不是数组

为啥这不是 google.maps.Map 的地图实例? InvalidValueError:setMap:不是 Map 的实例;

InvalidValueError:initAutocomplete 不是 Google Places 和 Autocomplete API 的功能

未捕获的 InvalidValueError:不是 Feature 或 FeatureCollection

如何修复Uncaught InvalidValueError:setPosition:不是LatLng或LatLngLiteral:在属性lat中:不是数字?

错误:InvalidValueError:setCenter:不是LatLng或LatLngLiteral:在属性lat中:不是数字