Skip to content

Instantly share code, notes, and snippets.

@uupaa uupaa/code.md
Last active Jan 17, 2018

Embed
What would you like to do?
Custom Components + Google Maps API does not work well.
<!DOCTYPE html><head><meta charset="utf-8"><title>MapView</title>
<style>html,body,map-view{height:100%;margin:10px}</style>
</head><body>
  <map-view type="google" key="..."></map-view>
  <script type="module" src="./app.js" charset="uft-8"></script>
</body>
</html>
// app.js
import { MapView } from "./MapView.js";

MapView.define();
// MapView.js
import { MapProvider } from "./MapProvider.js";
import { Map } from "./Map.js";

export class MapView extends HTMLElement {
  static get observedAttributes() {
    return [ "key", "type", "width" ];
  }
  static define() {
    customElements.define("map-view", MapView, { extends: "div" });
  }
  constructor() {
    super();
    this._map = null;
  }
  attr(name) { return this.getAttribute(name) || ""; }
  connectedCallback() {
    console.log("connectedCallback");
    this._shadowRoot = this.attachShadow({ mode: "open" }); // { mode, host, innerHTML }
    this._shadowRoot.innerHTML = MapView.template;
    const div = this._shadowRoot.querySelector("div");

    const type = this.attr("type");
    const key  = this.attr("key");

    MapProvider.getContext(type).load(key).then(() => {
      console.log("map script loaded");
      this._map = new Map(div, {});

    }).catch(err => {
      console.error(err.message);
      throw err;
    });
  }
  disconnectedCallback() {
    console.log("disconnectedCallback");
  }
  attributeChangedCallback(attributeName, oldValue, newValue, namespace) {
    if (oldValue === null) {
      console.log("attributeChangedCallback init", attributeName, oldValue, newValue, namespace);
    } else if (oldValue !== null) {
      console.log("attributeChangedCallback changed", attributeName, oldValue, newValue, namespace);
    }
  }
  adoptedCallback() {
    console.log("adoptedCallback");
  }
  static get template() {
    const tempNode = document.querySelector("#map-view");
    if (tempNode && tempNode.content) {
      return tempNode.content.cloneNode(true);
    }
    return `
<style>
  div { width: 100%; height: 100%; background-color: red; }
</style>
<div>
  <slot></slot>
</div>
`;
  }
};
// Map.js
export class Map {
  constructor(parentNode, options) {
    const mapTypeIds = [google.maps.MapTypeId.ROADMAP];

    this._map = new google.maps.Map(parentNode, {
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      center: { lat: 35.658, lng: 139.702 },
      zoom: 17,
      minZoom: 4,
      maxZoom: 20,
      fullscreenControl: false,
      zoomControlOptions: {
        position: google.maps.ControlPosition.LEFT_BOTTOM,
      },
      streetViewControlOptions: {
        position: google.maps.ControlPosition.LEFT_BOTTOM,
      },
      mapTypeControlOptions: {
        position: google.maps.ControlPosition.TOP_RIGHT,
        mapTypeIds: mapTypeIds,
      },
      scaleControl: true,
    });
  }
}
// MapsProvider.js
import { GoogleMapsProvider } from "./GoogleMapsProvider.js";

export class MapProvider {
  static getContext(type = "") {
    switch (type.toLowerCase()) {
    case "google":
    case "googlemap":
    case "googlemaps":
      return new GoogleMapsProvider();
    case "":
      throw new TypeError(`Need map-view type attribute`);
    default:
      throw new TypeError(`Unknown map-view type attribute: ${type}`);
    }
  }
}
// GoogleMapsProvider.js
export class GoogleMapsProvider {
  constructor() {}
  load(key) {
    return new Promise((resolve, reject) => {
      const script = document.createElement("script");
      script.onload = resolve;
      script.onerror = reject;
      script.id = "GoogleMapsProvider";
      script.src = `//maps.googleapis.com/maps/api/js?key=${key}&v=3&language=jp`;
      document.head.appendChild(script);
    });
  }
}
<!DOCTYPE html><head><meta charset="utf-8"><title>MapView</title>
<style>html,body,#map{height:100%;margin:10px}</style>
</head><body>
  <div id="map"></div>
  <script defer src="//maps.googleapis.com/maps/api/js?key=...&v=3&language=jp&callback=initMap"></script>
  <script defer>
  function initMap() {
    var map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: -34.397, lng: 150.644},
      zoom: 8
    });
    var myLatLng = {lat: -34.397, lng: 150.644};
    var marker = new google.maps.Marker({
      position: myLatLng,
      map: map,
      title: 'Hello World!'
    });
  }
  </script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.