You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

仅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">&times;</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 + "&nbsp;&nbsp;" + 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:09:23