Google 地图 API V3 在聚合物元素内部不工作
Google Map API V3 not working inside polymer-element
我创建了聚合物元素并在其中添加了 Google 地图。如果我将聚合物元素的代码直接写入我想使用它的主文件中,它可以正常工作,但是如果我将它的代码保存在单独的文件中并通过导入使用它,那么它会在控制台中给出以下错误:
Failed to execute 'write' on 'Document': It isn't possible to write
into a document from an asynchronously-loaded external script unless
it is explicitly opened.
这里是我的-map.html文件的代码:
<link rel="import" href="bower_components/polymer/polymer.html">
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<polymer-element name="my-map">
<template>
<style type="text/css">
:host{
display: block;
}
#mapCanvas {
height: 100%;
margin: 0px;
padding: 0px;
}
</style>
<div id="mapCanvas"></div>
</template>
<script type="text/javascript">
Polymer({
map:null,
ready:function(){
this.map = new google.maps.Map(this.$.mapCanvas, {
center: new google.maps.LatLng(41, -91),
disableDefaultUI: true,
zoom: 5
});
}
});
</script>
</polymer-element>
这是主文件的代码 index.html:
<!DOCTYPE html>
<html>
<head>
<title>My Map</title>
<script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
<link rel="import" href="my-map.html">
</head>
<body>
<my-map style="height:500px,width:500px;"></my-map>
</body>
</html>
问题出在哪里?
如果我在 index.html 文件中编写我的-map.html 文件的代码,那么它工作完美。
粗略的文件结构:
- 文件:index.html
- 文件:我的-map.html
- 目录:bower_components/
- 目录:核心组件页面/...
- 目录:聚合物/...
- 目录:webcomponentsjs/...
当 google-maps 库包含在聚合物元素的定义之上时,google-maps 似乎无法在聚合物元素上构建地图,可以 one/several 原因归咎于此。但至少有两种解决方案对我有用。
第一个解
尝试从您的聚合物元素中排除 google-maps 库并将其包含到您的 index.html 文件中:
index.html:
<!DOCTYPE html>
<html>
<head>
<title>My Map</title>
<!-- include google maps lib into your main index.html file -->
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script src="bower_components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="my-map.html">
</head>
<body>
<my-map width="500px" height="500px"></my-map>
</body>
</html>
聚合物元素(my-map.html):
<link rel="import" href="bower_components/polymer/polymer.html">
<polymer-element name="my-map" attributes="width height">
<template>
<style type="text/css">
:host{
display: block;
}
#mapCanvas {
margin: 0px;
padding: 0px;
}
</style>
<div id="mapCanvas" style="width:{{width}};height:{{height}}"></div>
</template>
<script>
Polymer({
map:null,
width: '100px',// default width
height: '100px',// default height
ready:function(){
// map canvas lies within shadow-dom so it not accessible by ordinary *querySelector*, *querySelectorAll* or *getElementById* methods but this is a way: this.$.mapCanvas
this.map = new google.maps.Map(
this.$.mapCanvas,
{ center: new google.maps.LatLng(41, -91),
disableDefaultUI: true,
zoom: 5
}
);
}
});
</script>
</polymer-element>
第二种解法:
尝试使用 google 地图库的回调参数(url-部分:&callback=callback)并包含 google 地图库进入聚合物元素的定义:
index.html:
<!DOCTYPE html>
<html>
<head>
<title>My Map</title>
<script src="bower_components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="my-map.html">
</head>
<body>
<!-- use default width/height -->
<my-map></my-map>
</body>
</html>
聚合物元素(my-map.html):
<link rel="import" href="bower_components/polymer/polymer.html">
<polymer-element name="my-map" attributes="width height">
<template>
<style type="text/css">
:host{
display: block;
}
#mapCanvas {
margin: 0px;
padding: 0px;
}
</style>
<div id="mapCanvas" style="width:{{width}};height:{{height}}"></div>
</template>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&callback=callback"></script>
<script>
// use IIFE to encapsulate all defined variables to prevent them from being assigned to window object unintentionally
(function(){
var googleMapsReady = false;
var myMapPolymer;
var htmlCanvasMap;
function callback(){
googleMapsReady = true;
if(htmlCanvasMap){
buildUpMap(htmlCanvasMap);
}
}
// !!! unfortunately you have to assign callback function to window object
// because this function has to be accessible globally otherwise google maps lib will not find it and throws an error
window.callback = callback;
// function to show a google map on your site that takes a html element on which a map should be shown
function buildUpMap(htmlmap){
var map = new google.maps.Map(
htmlmap,
{ center: new google.maps.LatLng(38, -91),
disableDefaultUI: true,
zoom: 8
}
);
// at last assign google map object as property to polymer element
myMapPolymer.map = map;
}
// polymer element code definition
Polymer({
map:null,
width: '100px',// default width
height: '100px',// default height
ready:function(){
myMapPolymer = this;
// assign map canvas(div) to varible in order to use it for building up a map,
htmlCanvasMap = this.$.mapCanvas;
if(googleMapsReady){
buildUpMap(htmlCanvasMap);
}
}
});
})();
</script>
</polymer-element>
在第二种解决方案中,仍有机会将初始化的 google 地图对象作为 属性 分配给聚合物元素:
变量 googleMapsReady 在 google 地图加载并准备好使用时设置 [=42] =]Polymer.ready函数。
否则,如果 Polymer.ready 在 callback 之前调用,则变量 htmlCanvasMap 已分配,因此在 callback 函数中检查时 true。
希望对您有所帮助。
我创建了聚合物元素并在其中添加了 Google 地图。如果我将聚合物元素的代码直接写入我想使用它的主文件中,它可以正常工作,但是如果我将它的代码保存在单独的文件中并通过导入使用它,那么它会在控制台中给出以下错误:
Failed to execute 'write' on 'Document': It isn't possible to write into a document from an asynchronously-loaded external script unless it is explicitly opened.
这里是我的-map.html文件的代码:
<link rel="import" href="bower_components/polymer/polymer.html">
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<polymer-element name="my-map">
<template>
<style type="text/css">
:host{
display: block;
}
#mapCanvas {
height: 100%;
margin: 0px;
padding: 0px;
}
</style>
<div id="mapCanvas"></div>
</template>
<script type="text/javascript">
Polymer({
map:null,
ready:function(){
this.map = new google.maps.Map(this.$.mapCanvas, {
center: new google.maps.LatLng(41, -91),
disableDefaultUI: true,
zoom: 5
});
}
});
</script>
</polymer-element>
这是主文件的代码 index.html:
<!DOCTYPE html>
<html>
<head>
<title>My Map</title>
<script src="bower_components/webcomponentsjs/webcomponents.min.js"></script>
<link rel="import" href="my-map.html">
</head>
<body>
<my-map style="height:500px,width:500px;"></my-map>
</body>
</html>
问题出在哪里? 如果我在 index.html 文件中编写我的-map.html 文件的代码,那么它工作完美。
粗略的文件结构:
- 文件:index.html
- 文件:我的-map.html
- 目录:bower_components/
- 目录:核心组件页面/...
- 目录:聚合物/...
- 目录:webcomponentsjs/...
当 google-maps 库包含在聚合物元素的定义之上时,google-maps 似乎无法在聚合物元素上构建地图,可以 one/several 原因归咎于此。但至少有两种解决方案对我有用。
第一个解
尝试从您的聚合物元素中排除 google-maps 库并将其包含到您的 index.html 文件中:
index.html:
<!DOCTYPE html>
<html>
<head>
<title>My Map</title>
<!-- include google maps lib into your main index.html file -->
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp"></script>
<script src="bower_components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="my-map.html">
</head>
<body>
<my-map width="500px" height="500px"></my-map>
</body>
</html>
聚合物元素(my-map.html):
<link rel="import" href="bower_components/polymer/polymer.html">
<polymer-element name="my-map" attributes="width height">
<template>
<style type="text/css">
:host{
display: block;
}
#mapCanvas {
margin: 0px;
padding: 0px;
}
</style>
<div id="mapCanvas" style="width:{{width}};height:{{height}}"></div>
</template>
<script>
Polymer({
map:null,
width: '100px',// default width
height: '100px',// default height
ready:function(){
// map canvas lies within shadow-dom so it not accessible by ordinary *querySelector*, *querySelectorAll* or *getElementById* methods but this is a way: this.$.mapCanvas
this.map = new google.maps.Map(
this.$.mapCanvas,
{ center: new google.maps.LatLng(41, -91),
disableDefaultUI: true,
zoom: 5
}
);
}
});
</script>
</polymer-element>
第二种解法:
尝试使用 google 地图库的回调参数(url-部分:&callback=callback)并包含 google 地图库进入聚合物元素的定义:
index.html:
<!DOCTYPE html>
<html>
<head>
<title>My Map</title>
<script src="bower_components/webcomponentsjs/webcomponents.js"></script>
<link rel="import" href="my-map.html">
</head>
<body>
<!-- use default width/height -->
<my-map></my-map>
</body>
</html>
聚合物元素(my-map.html):
<link rel="import" href="bower_components/polymer/polymer.html">
<polymer-element name="my-map" attributes="width height">
<template>
<style type="text/css">
:host{
display: block;
}
#mapCanvas {
margin: 0px;
padding: 0px;
}
</style>
<div id="mapCanvas" style="width:{{width}};height:{{height}}"></div>
</template>
<script src="https://maps.googleapis.com/maps/api/js?v=3.exp&callback=callback"></script>
<script>
// use IIFE to encapsulate all defined variables to prevent them from being assigned to window object unintentionally
(function(){
var googleMapsReady = false;
var myMapPolymer;
var htmlCanvasMap;
function callback(){
googleMapsReady = true;
if(htmlCanvasMap){
buildUpMap(htmlCanvasMap);
}
}
// !!! unfortunately you have to assign callback function to window object
// because this function has to be accessible globally otherwise google maps lib will not find it and throws an error
window.callback = callback;
// function to show a google map on your site that takes a html element on which a map should be shown
function buildUpMap(htmlmap){
var map = new google.maps.Map(
htmlmap,
{ center: new google.maps.LatLng(38, -91),
disableDefaultUI: true,
zoom: 8
}
);
// at last assign google map object as property to polymer element
myMapPolymer.map = map;
}
// polymer element code definition
Polymer({
map:null,
width: '100px',// default width
height: '100px',// default height
ready:function(){
myMapPolymer = this;
// assign map canvas(div) to varible in order to use it for building up a map,
htmlCanvasMap = this.$.mapCanvas;
if(googleMapsReady){
buildUpMap(htmlCanvasMap);
}
}
});
})();
</script>
</polymer-element>
在第二种解决方案中,仍有机会将初始化的 google 地图对象作为 属性 分配给聚合物元素:
变量 googleMapsReady 在 google 地图加载并准备好使用时设置 [=42] =]Polymer.ready函数。
否则,如果 Polymer.ready 在 callback 之前调用,则变量 htmlCanvasMap 已分配,因此在 callback 函数中检查时 true。
希望对您有所帮助。