仅iPhone端Google Maps脚本失效问题求助
针对iPhone端Google Maps坐标选择脚本失效的排查与修复方案
问题描述
在WordPress主题中嵌入的脚本,功能为点击唤起Google Maps并将选中坐标填充至文本框,该脚本在Android及其他平台运行正常,唯独iPhone端无法工作。
相关代码
const html = `<div id="coordinate-modal" class="coordinate-modal"> <div class="coordinate-modal-content"> <span class="coordinate-modal-close">×</span> <h3 id='coordinate-modal-title'>SELECT LOCATION</h3> <p id='coordinate-modal-text'>You can search a specific location, either by typing in an address or by dragging the cursor on the map. <br />Click on <b>SET THESE COORDINATES</b> below to confirm and continue. </p> <input id="map-search-input" class="controls" type="text" placeholder="Enter a location" /> <div id='coordinate-modal-map'></div> <div class="coordinate-modal-coords"> <div class="coordinate-modal-coords-title">COORDINATES</div> <div id="coordinate-modal-coords-value"></div> </div> <a id='coordinate-modal-button' class="coordinate_button coordinate-modal-button">SET THESE COORDINATES</a> </div> </div>`; document.write(html); function toDegreesMinutesAndSeconds(coordinate) { var absolute = Math.abs(coordinate); var degrees = Math.floor(absolute); var minutesNotTruncated = (absolute - degrees) * 60; var minutes = Math.floor(minutesNotTruncated); var seconds = Math.floor((minutesNotTruncated - minutes) * 60); return degrees + "°" + minutes + "’" + seconds + "”"; } function convertDMS(lat, lng) { var latitude = toDegreesMinutesAndSeconds(lat); var latitudeCardinal = lat >= 0 ? "N" : "S"; var longitude = toDegreesMinutesAndSeconds(lng); var longitudeCardinal = lng >= 0 ? "E" : "W"; return latitude + " " + latitudeCardinal + " " + longitude + " " + longitudeCardinal; } var mapLatitude = ''; var mapLongitude = ''; // Get the modal var modal = document.getElementById("coordinate-modal"); // Get the button that opens the modal var btn = document.getElementById("search-coordinate-button"); // Get the <span> element that closes the modal var span = document.getElementsByClassName("coordinate-modal-close")[0]; function updateLatLng(lat, lng) { mapLatitude = lat; mapLongitude = lng; } const map = new google.maps.Map(document.getElementById("coordinate-modal-map"), { center: { lat: 34.0404676, lng: -118.4681691 }, zoom: 13, streetViewControl: false, fullscreenControl: false, mapTypeControl: false, mapTypeId: "roadmap", }); // Create the search box and link it to the UI element. const input = document.getElementById("map-search-input"); const searchBox = new google.maps.places.SearchBox(input); map.controls[google.maps.ControlPosition.TOP_LEFT].push(input); // Bias the SearchBox results towards current map's viewport. map.addListener("bounds_changed", () => { searchBox.setBounds(map.getBounds()); }); let marker = new google.maps.Marker({ map, draggable: true, animation: google.maps.Animation.DROP, position: { lat: 34.0404676, lng: -118.4681691 }, }); // Listen for the event fired when the user selects a prediction and retrieve // more details for that place. searchBox.addListener("places_changed", () => { const places = searchBox.getPlaces(); if (places.length == 0) { return; } // For each place, get the icon, name and location. const bounds = new google.maps.LatLngBounds(); places.forEach((place) => { if (!place.geometry || !place.geometry.location) { console.log("Returned place contains no geometry"); return; } const lat = place.geometry.location.lat(); const lng = place.geometry.location.lng(); marker.setPosition(new google.maps.LatLng(lat, lng)); updateLatLng(toDegreesMinutesAndSeconds(lat), toDegreesMinutesAndSeconds(lng)); document.getElementById('coordinate-modal-coords-value').innerHTML = convertDMS(lat, lng); if (place.geometry.viewport) { // Only geocodes have viewport. bounds.union(place.geometry.viewport); } else { bounds.extend(place.geometry.location); } }); map.fitBounds(bounds); }); document.getElementById('coordinate-modal-coords-value').innerHTML = convertDMS(34.0404676, -118.4681691); function onMapClick(e) { const lat = e.latLng.lat(); const lng = e.latLng.lng(); marker.setPosition(new google.maps.LatLng(lat, lng)); updateLatLng(toDegreesMinutesAndSeconds(lat), toDegreesMinutesAndSeconds(lng)); document.getElementById('coordinate-modal-coords-value').innerHTML = convertDMS(lat, lng); } map.addListener("click", onMapClick); marker.addListener('dragend', function (event) { const lat = event.latLng.lat(); const lng = event.latLng.lng(); updateLatLng(toDegreesMinutesAndSeconds(lat), toDegreesMinutesAndSeconds(lng)); document.getElementById('coordinate-modal-coords-value').innerHTML = convertDMS(lat, lng); }); // When the user clicks the button, open the modal // btn.onclick = function (ev) { ev.preventDefault(); modal.style.visibility = "visible"; } btn.addEventListener('touchend', function (ev) { ev.preventDefault(); modal.style.visibility = "visible"; }); // When the user clicks on <span> (x), close the modal span.onclick = function (ev) { ev.preventDefault() modal.style.visibility = "hidden"; } var setCoordinateButton = document.getElementById("coordinate-modal-button"); setCoordinateButton.onclick = function () { const el1 = fancyProductDesigner.currentViewInstance.getElementByTitle("COORDINATES FIRST LINE"); const el2 = fancyProductDesigner.currentViewInstance.getElementByTitle("COORDINATES SECOND LINE"); let append = false; if(el1.text.endsWith("”N")) { append = true; } fancyProductDesigner.currentViewInstance.setElementParameters({text: append ? `${mapLatitude}N` : mapLatitude}, el1); fancyProductDesigner.currentViewInstance.setElementParameters({text: append ? `${mapLongitude}W` : mapLongitude}, el2); modal.style.visibility = "hidden"; } // When the user clicks anywhere outside of the modal, close it window.onclick = function (event) { if (event.target == modal) { modal.style.visibility = "hidden"; } }
排查思路与修复方案
1. 事件绑定兼容性优化
iPhone Safari对非交互元素的click事件支持有限,比如你的<a>按钮未设置href。建议:
- 给触发按钮和确认按钮的
<a>标签添加href="javascript:void(0)",确保Safari识别为可交互元素; - 统一使用
addEventListener绑定事件,避免混合使用onclick和addEventListener导致冲突:// 替换原btn.onclick代码 btn.addEventListener('click', function(ev) { ev.preventDefault(); modal.style.visibility = "visible"; });
2. 替换document.write的DOM插入方式
Safari在DOM加载完成后调用document.write会导致内容无法正确插入,改用标准DOM操作:
// 替换document.write(html); const modalElement = document.createElement('div'); modalElement.innerHTML = html; document.body.appendChild(modalElement);
3. 确保Google Maps在DOM就绪后初始化
iPhone上可能存在DOM元素未渲染完成就初始化地图的情况,将地图初始化代码包裹在DOMContentLoaded事件中:
document.addEventListener('DOMContentLoaded', function() { // 这里放入所有地图初始化、事件绑定的代码 const map = new google.maps.Map(document.getElementById("coordinate-modal-map"), { // 地图配置参数 }); // ...其他地图相关代码 });
4. 调整模态框显示控制逻辑
Safari对visibility属性的处理存在差异,改用display属性控制显示:
// 显示模态框 modal.style.display = "block"; // 隐藏模态框 modal.style.display = "none";
同时确保模态框的CSS设置了正确的position和z-index,避免被其他元素遮挡。
5. 利用Safari开发者工具排查报错
连接iPhone到Mac,打开Safari开发者工具查看控制台,重点检查:
- Google Maps API是否加载成功;
fancyProductDesigner是否在iPhone端正常初始化;- 是否有变量未定义、DOM元素获取失败等错误。
内容的提问来源于stack exchange,提问作者Alexander
相关产品推荐
相关产品推荐

