Google 地图标记无法在 Safari 中使用 Shadow DOM
Google map markers not working with Shadow DOM in Safari
如果您在 Safari 中加载带有 marker 的 map,地图就在里面一个 Shadow DOM,它似乎挂在 无限页面重新加载循环 中,直到该无限循环被浏览器停止,然后显示以下错误(翻译自西班牙语):
There has been a problem repeatedly with http://localhost:8000/index.html. Try loading the web page again.
我创建了以下非常简单的 Polymer 项目来重现该问题。
Index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Markers test</title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 300px;
width: 300px;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
<script src="bower_components/webcomponentsjs/webcomponents-loader.js"></script>
<!-- Load your application shell -->
<link rel="import" href="test-el.html">
</head>
<body>
<test-el></test-el>
<div id="map"></div>
<script>
function initMap() {
const mapsEvent = new CustomEvent('map-ready');
document.dispatchEvent(mapsEvent);
window.MAP_READY = true;
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_MAPS_API_KEY_HERE&callback=initMap">
</script>
</body>
</html>
test-el.html,这是我创建的用于将贴图封装在 Shadow 中的 Poylmer 测试元素 DOM
<link rel="import" href="bower_components/polymer/polymer-element.html">
<dom-module id="test-el">
<template>
<style>
#map {
width: 300px;
height: 300px;
}
</style>
<div id="map"></div>
</template>
<script>
class TestEl extends Polymer.Element {
static get is() { return 'test-el'; }
static get properties() {
return {
// This shouldn't be neccessary, but the Analyzer isn't picking up
// Polymer.Element#rootPath
rootPath: String,
};
}
ready() {
super.ready();
if (window.MAP_READY) {
this.loadMap();
} else {
document.addEventListener('map-ready', () => this.loadMap());
}
}
loadMap() {
var myLatLng = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
var mapShadowDom = new google.maps.Map(this.$.map, {
zoom: 4,
center: myLatLng
});
var markerShadowDom = new google.maps.Marker({
position: myLatLng,
map: mapShadowDom,
title: 'Hello World!'
});
}
}
window.customElements.define(TestEl.is, TestEl);
</script>
</dom-module>
如果你想 运行 我做的相同测试,你需要以下小 bower.json 文件,和 运行ning bower install
在你保存这三个文件的文件夹中,供bower安装webcomponents和Polymer依赖。
{
"name": "markers_test",
"dependencies": {
"polymer": "Polymer/polymer#^2.5.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0"
},
"resolutions": {
"polymer": "^2.0.0"
},
"private": true
}
最后,使用本地服务器 index.html。
测试
如您所见,index.html中test-el
实例化<test-el></test-el>
的正下方实际上有一个<div id="map"></div>
。 div
不在阴影 DOM 内,所以它只是为了表明地图和标记即使不在阴影 DOM.
内也能正常工作
在 test-el.html 文件的 <script>
部分,在 loadMap()
函数内,你可以看到我创建了 2 Google 每个地图都有一个标记。第一个 Google Maps 实例化分配给位于 index.html 的非 Shadow DOM div,而 mapShadowDom
被分配给 test-el 的影子 DOM.
内的 <div id="map"></div>
例如,运行 Google Chrome 中的示例代码应该呈现两张澳大利亚地图,每张地图的中心都有一个标记。
运行 Safari 上的相同代码(我在 Safari 11.1 上测试过)应该会导致我在顶部描述的错误情况。
但是,如果您要在 test-el.html
中注释以下行
var markerShadowDom = new google.maps.Marker({
position: myLatLng,
map: mapShadowDom,
title: 'Hello World!'
});
Safari 中的结果应如下所示:
所以问题似乎与在位于阴影 DOM.
内的 Google 地图中绘制 Google 标记有关
感谢您提供非常详细的信息和重现步骤!
这里的 an issue that was reported on a Google Maps web component 似乎代表了同样的问题。就像你说的,只有在阴影 DOM 中将标记添加到地图时才会出现。
它发生在 Safari 11.1 中(我今天早上还有 Safari 11.0,无法用那个版本重现)。它似乎已在技术预览 (Safari 12) 中修复。
如果您需要快速解决方法,您可以尝试强制 Safari 11.1 使用可疑的 DOM polyfill。像
<script>
// Force Safari 11.1.* to use shady DOM because of a bug
// See https://github.com/GoogleWebComponents/google-map/issues/419
// i don't know how to parse user agents
// this is probably bad
var s1 = 'Version/11.1';
var s2 = 'Safari/605.1.15';
var agent=navigator.userAgent;
if ((agent.search(s1) >= 0 ) && (agent.search(s2) >= 0 )) {
ShadyDOM = { force: true };
}
</script>
<script src="/bower_components/webcomponentsjs/webcomponents-loader.js"></script>
有同样的问题。这就是我最终为临时修复所做的事情
var markerShadowDom = new google.maps.Marker({
icon: 'https://maps.gstatic.com/mapfiles/api-3/images/spotlight-poi.png',
position: myLatLng,
map: mapShadowDom,
title: 'Hello World!'
});
自定义标记似乎适用于 safari
如果您在 Safari 中加载带有 marker 的 map,地图就在里面一个 Shadow DOM,它似乎挂在 无限页面重新加载循环 中,直到该无限循环被浏览器停止,然后显示以下错误(翻译自西班牙语):
There has been a problem repeatedly with http://localhost:8000/index.html. Try loading the web page again.
我创建了以下非常简单的 Polymer 项目来重现该问题。
Index.html
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
<meta charset="utf-8">
<title>Markers test</title>
<style>
/* Always set the map height explicitly to define the size of the div
* element that contains the map. */
#map {
height: 300px;
width: 300px;
}
/* Optional: Makes the sample page fill the window. */
html, body {
height: 100%;
margin: 0;
padding: 0;
}
</style>
<script src="bower_components/webcomponentsjs/webcomponents-loader.js"></script>
<!-- Load your application shell -->
<link rel="import" href="test-el.html">
</head>
<body>
<test-el></test-el>
<div id="map"></div>
<script>
function initMap() {
const mapsEvent = new CustomEvent('map-ready');
document.dispatchEvent(mapsEvent);
window.MAP_READY = true;
}
</script>
<script async defer
src="https://maps.googleapis.com/maps/api/js?key=YOUR_MAPS_API_KEY_HERE&callback=initMap">
</script>
</body>
</html>
test-el.html,这是我创建的用于将贴图封装在 Shadow 中的 Poylmer 测试元素 DOM
<link rel="import" href="bower_components/polymer/polymer-element.html">
<dom-module id="test-el">
<template>
<style>
#map {
width: 300px;
height: 300px;
}
</style>
<div id="map"></div>
</template>
<script>
class TestEl extends Polymer.Element {
static get is() { return 'test-el'; }
static get properties() {
return {
// This shouldn't be neccessary, but the Analyzer isn't picking up
// Polymer.Element#rootPath
rootPath: String,
};
}
ready() {
super.ready();
if (window.MAP_READY) {
this.loadMap();
} else {
document.addEventListener('map-ready', () => this.loadMap());
}
}
loadMap() {
var myLatLng = {lat: -25.363, lng: 131.044};
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 4,
center: myLatLng
});
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: 'Hello World!'
});
var mapShadowDom = new google.maps.Map(this.$.map, {
zoom: 4,
center: myLatLng
});
var markerShadowDom = new google.maps.Marker({
position: myLatLng,
map: mapShadowDom,
title: 'Hello World!'
});
}
}
window.customElements.define(TestEl.is, TestEl);
</script>
</dom-module>
如果你想 运行 我做的相同测试,你需要以下小 bower.json 文件,和 运行ning bower install
在你保存这三个文件的文件夹中,供bower安装webcomponents和Polymer依赖。
{
"name": "markers_test",
"dependencies": {
"polymer": "Polymer/polymer#^2.5.0",
"webcomponentsjs": "webcomponents/webcomponentsjs#^1.0.0"
},
"resolutions": {
"polymer": "^2.0.0"
},
"private": true
}
最后,使用本地服务器 index.html。
测试
如您所见,index.html中test-el
实例化<test-el></test-el>
的正下方实际上有一个<div id="map"></div>
。 div
不在阴影 DOM 内,所以它只是为了表明地图和标记即使不在阴影 DOM.
在 test-el.html 文件的 <script>
部分,在 loadMap()
函数内,你可以看到我创建了 2 Google 每个地图都有一个标记。第一个 Google Maps 实例化分配给位于 index.html 的非 Shadow DOM div,而 mapShadowDom
被分配给 test-el 的影子 DOM.
<div id="map"></div>
例如,运行 Google Chrome 中的示例代码应该呈现两张澳大利亚地图,每张地图的中心都有一个标记。
运行 Safari 上的相同代码(我在 Safari 11.1 上测试过)应该会导致我在顶部描述的错误情况。
但是,如果您要在 test-el.html
中注释以下行var markerShadowDom = new google.maps.Marker({
position: myLatLng,
map: mapShadowDom,
title: 'Hello World!'
});
Safari 中的结果应如下所示:
所以问题似乎与在位于阴影 DOM.
内的 Google 地图中绘制 Google 标记有关感谢您提供非常详细的信息和重现步骤!
这里的 an issue that was reported on a Google Maps web component 似乎代表了同样的问题。就像你说的,只有在阴影 DOM 中将标记添加到地图时才会出现。
它发生在 Safari 11.1 中(我今天早上还有 Safari 11.0,无法用那个版本重现)。它似乎已在技术预览 (Safari 12) 中修复。
如果您需要快速解决方法,您可以尝试强制 Safari 11.1 使用可疑的 DOM polyfill。像
<script>
// Force Safari 11.1.* to use shady DOM because of a bug
// See https://github.com/GoogleWebComponents/google-map/issues/419
// i don't know how to parse user agents
// this is probably bad
var s1 = 'Version/11.1';
var s2 = 'Safari/605.1.15';
var agent=navigator.userAgent;
if ((agent.search(s1) >= 0 ) && (agent.search(s2) >= 0 )) {
ShadyDOM = { force: true };
}
</script>
<script src="/bower_components/webcomponentsjs/webcomponents-loader.js"></script>
有同样的问题。这就是我最终为临时修复所做的事情
var markerShadowDom = new google.maps.Marker({
icon: 'https://maps.gstatic.com/mapfiles/api-3/images/spotlight-poi.png',
position: myLatLng,
map: mapShadowDom,
title: 'Hello World!'
});
自定义标记似乎适用于 safari