让我们制作可重用的网络组件:谷歌地图

让我们制作可重用的网络组件:谷歌地图

原文:https://medium.com/hackernoon/lets-make-reusable-web-components-google-maps-8be7577d925

推动 web 开发前进的一个巨大挑战是缺乏对 web 组件的完全共识。

事实证明,到处都有框架,每个框架都有自己的开销和想法,一些常见的 UI 组件仍然是从头开始开发的。

这是意料之中的,因为框架迫使你进入他们的世界,所以尽管 React 或 Vue 组件是可重用的,但你必须忠于那个框架。我们中的一些人在承诺方面有问题。

有心理医生,但他们通常什么也治不好。

有一个 Web 组件标准,诞生于这样一个事实:将 HTML/JS/CSS 混杂在一起在概念上是非常不愉快的。

例如,我们可以按照他们的教程指示,将谷歌地图放在我们的页面上。

<div id=”map”></div><script>
 function initMap() {
  // Create a map object and specify the DOM element for display.
  var map = new google.maps.Map(document.getElementById(‘map’), {
    center: {lat: -34.397, lng: 150.644}, zoom: 8
    });
 }
</script>
<script src=”[https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap](https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap)" async defer></script>

但是,这正是重点。是我们页面上的,不是我们 app 里的

当然,在我们使用 google.maps 对象之前,需要加载脚本,这是一个问题。脚本标签应该在 HTML 之后。这不太好。

在一个页面上可能需要很多组件的世界里,我们只能用 initMap 作为入口点。我们可能正在加载其他脚本,等等..变得一团糟。

所以,让我们尝试一种不同的方法。我们必须动态加载 JS。

var e = document.createElement(‘script’)
e.src = s; 
document.body.appendChild(e)

为了简单起见,我们将这个函数称为 load。

const load = async (s) => {
  return new Promise(async r=>{
   for(i=0;i<document.scripts.length;i++)
     if(document.scripts[i].src == s) return r()
   let e = document.createElement('script')
   e.src = s 
   document.body.appendChild(e)
   e.onload = r
  })
}

当脚本加载后,这个承诺就实现了。它还首先检查脚本是否已经加载。

所以,现在我们可以制作我们的可重用组件,一个 gmap 函数:

const gmap = async (e) => {
  return new Promise(async r=>{
     e.style.height = e.style.width = e.getAttribute('size')
     let latlng = e.getAttribute('latlng').split(',')
     await load('[http://maps.googleapis.com/maps/api/js?v=3'](http://maps.googleapis.com/maps/api/js?v=3'))
     let map = new google.maps.Map(e, {
      center: new self.google.maps.LatLng(latlng[0], latlng[1]),
      zoom: 14,
      mapTypeId: google.maps.MapTypeId.ROADMAP
     });
     r(map)
  })
}

这是一个异步函数,它将等待加载脚本完成。这将确保一切都按顺序进行。我们可能希望在一个页面上有多个地图。

<div control=gmap size=200px latlng=33.808678,-117.918921></div>
<div control=gmap size=200px latlng=28.3852377,-81.5660627></div>

并将 div 提供给 gmap“组件”以创建控件

(async () => {
  let controls = document.querySelectorAll(‘div[control=gmap]’)
  for (var i = 0; i < controls.length; i++)
    await gmap(controls[i])
})()

所有的依赖都是免费的,并且是普通的 JS 格式。

重要的是,没什么需要记住的。 Div、函数和语言特性。

不知道哪种模式会胜出,但有可能只是使用语言而没有额外的东西,也很有趣。


本站为非盈利网站,作品由网友提供上传,如无意中有侵犯您的版权,请联系删除