【问题标题】:Dynamically add google maps div into DOM将谷歌地图 div 动态添加到 DOM
【发布时间】:2021-01-27 20:24:44
【问题描述】:

我想在用户输入搜索后在动态添加到 DOM 的卡片中添加 Google Maps API div <div id="map"></div>。作为测试,我可以将它附加到主 div 中,但不能在卡片插入 DOM 后添加到卡片中。

代码如下。

const APIURL = 'https://restcountries.eu/rest/v2/name/'
const GOOGLE_MAPS_API = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyDhlU1KMTlTh4C__bTJBxbVA-s7wvQbO9E&callback=initMap'
const main = document.getElementById('main')
const form = document.getElementById('form')
const search = document.getElementById('search')

async function getCountryData(name) {
    try {
        const { data } = await axios.get(APIURL + name)

        data.forEach(res => {
            const countryData = res

            addGMapsEl()
            createCountryCard(countryData)
            getLatLngPos(countryData)
        } )
        } catch (err) {
        if(err.response.status == 404) {
            createErrorCard('No countries found')
            setTimeout(() => { 
                main.innerHTML = ''}
                , 1500);
        }
    }
}

// Google Map API 
function addGMapsEl() {
const script = document.createElement('script');
script.src = GOOGLE_MAPS_API;
script.defer = true;

document.head.appendChild(script);

const mapDiv = document.createElement('div')

      mapDiv.id = 'map'
      main.appendChild(mapDiv)
}

let map;

function initMap() {
  
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 51, lng: 9},
    zoom: 7
  });
}

function createCountryCard(country) {
    const cardHTML = `
    <div class="content-container">
        <div class="card">
         <div class="wrapper">
             <div class="card-title">
              <h2>${country.name}</h2>
              <h4>Capital: ${country.capital}</h4>
              <h5>Population: ${country.population.toLocaleString('en')}</h5>
        </div>
        <div class="card-image">
          <img
            src="${country.flag}"
            alt="${country.name +'-flag'}"
          />
        </div>
      </div>
      <div class="wrapper">
        <div class="map-content">
        </div>
        <div class="card-content">
          <ul class="card-list">
            <li><strong>Region:</strong> ${country.region}</li>
            <li><strong>Subregion:</strong> ${country.subregion}</li>
            <li><strong>Currency:</strong> ${country.currencies[0].name}<span> ${country.currencies[0].symbol}</span></li>
            <li><strong>Spoken Language:</strong> ${country.languages[0].name}</li>
            <li><strong>Timezone:</strong> ${country.timezones}</li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  `
  main.innerHTML += cardHTML
}

// Creates error card after no results found
function createErrorCard(msg) {
    const cardHTML = `
    <div class="card">
        <h1>${msg}</h1>
    </div>
    `
    main.innerHTML = cardHTML
}

// Clears the DOM on search 
function clearDOM() {
  main.innerHTML = ''
}



// Search Input
form.addEventListener('submit', (e) => {
    e.preventDefault()
 
    clearDOM()

    const countryName = search.value
    if(countryName) {
        getCountryData(countryName)

        search.value = ''
    }
})
<body>
        <div class="search-container">
          <form id="form" class="form">
            <input type="text" id="search" placeholder="Search for country..." />
          </form>
        </div>
        <main id="main"></main>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
        <script src="script.js"></script>
      </body>

【问题讨论】:

  • 嗨,马特 - 您需要将您拥有的所有代码添加到 sn-p 中,或者至少放在那里以使其运行。现在没有什么可以工作的。函数createCountryCard 从未使用过。 Map init 函数在 ID 为 map 的元素上创建映射。如果您想在自定义元素中制作地图,只需给它一些不同的 id,当您的元素存在于 DOM 中时,使用您的元素的自定义 ID 初始化地图。
  • 对不起,我虽然已经全部粘贴了。我现在添加它。谢谢

标签: javascript html dom google-maps-api-3


【解决方案1】:

好的 - 所以 - 要创建一个 MAP,您需要使用 new google.maps.Map( ELEMENT_TO_CONTAIN_THE_MAP, MAP_OPTIONS),它位于您的 mapInit 函数中。 你也应该只加载一次 API - 所以我在你的代码中移动了一些东西......

我已从您的地图网址中删除了 callback=initMap - 因为在加载 google 脚本时您的元素在 DOM 中不存在。 然后在你的createCountryCard 调用之后调用mapInit - 因为它会将你的地图元素添加到DOM - 现在我们可以将地图放置在其中。

给定你的元素 id 参数&lt;div class="map-content" id="map-content"&gt;。然后更改 mapInit 函数中的 id 以匹配您的元素 id,即 map-content

const APIURL = 'https://restcountries.eu/rest/v2/name/'
const GOOGLE_MAPS_API = 'https://maps.googleapis.com/maps/api/js?key=AIzaSyDhlU1KMTlTh4C__bTJBxbVA-s7wvQbO9E'
const main = document.getElementById('main')
const form = document.getElementById('form')
const search = document.getElementById('search')

async function getCountryData(name) {
  try {
    const {
      data
    } = await axios.get(APIURL + name)

    data.forEach(res => {
      const countryData = res

      //gmaps element is on card
      createCountryCard(countryData);
      initMap();
      getLatLngPos(countryData)
    })
  } catch (err) {
    if (err.response.status == 404) {
      createErrorCard('No countries found')
      setTimeout(() => {
        main.innerHTML = ''
      }, 1500);
    }
  }
}

// Google Map API 
function addGMapsEl() {
  const script = document.createElement('script');
  script.src = GOOGLE_MAPS_API;
  script.defer = true;

  document.head.appendChild(script);
  const mapDiv = document.createElement('div')

  mapDiv.id = 'map'
  main.appendChild(mapDiv)
}

let map;

function initMap() {

  map = new google.maps.Map(document.getElementById("map-content"), {
    center: {
      lat: 51,
      lng: 9
    },
    zoom: 7
  });
}

function createCountryCard(country) {
  const cardHTML = `
    <div class="content-container">
        <div class="card">
         <div class="wrapper">
             <div class="card-title">
              <h2>${country.name}</h2>
              <h4>Capital: ${country.capital}</h4>
              <h5>Population: ${country.population.toLocaleString('en')}</h5>
        </div>
        <div class="card-image">
          <img
            src="${country.flag}"
            alt="${country.name +'-flag'}"
          />
        </div>
      </div>
      <div class="wrapper">
        <div id="map-content" class="map-content">
        </div>
        <div class="card-content">
          <ul class="card-list">
            <li><strong>Region:</strong> ${country.region}</li>
            <li><strong>Subregion:</strong> ${country.subregion}</li>
            <li><strong>Currency:</strong> ${country.currencies[0].name}<span> ${country.currencies[0].symbol}</span></li>
            <li><strong>Spoken Language:</strong> ${country.languages[0].name}</li>
            <li><strong>Timezone:</strong> ${country.timezones}</li>
          </ul>
        </div>
      </div>
    </div>
  </div>
  `
  main.innerHTML += cardHTML
}

// Creates error card after no results found
function createErrorCard(msg) {
  const cardHTML = `
    <div class="card">
        <h1>${msg}</h1>
    </div>
    `
  main.innerHTML = cardHTML
}

// Clears the DOM on search 
function clearDOM() {
  main.innerHTML = ''
}



// Search Input
form.addEventListener('submit', (e) => {
  e.preventDefault()

  clearDOM()

  const countryName = search.value
  if (countryName) {
    getCountryData(countryName)

    search.value = ''
  }
})

addGMapsEl();
.map-content {
  width: 100%;
  height: 300px;
}
.card-image img {
    max-height: 50px;
    box-shadow: 1px 1px 5px #aaa;
}
<body>
  <div class="search-container">
    <form id="form" class="form">
      <input type="text" id="search" placeholder="Search for country..." />
    </form>
  </div>
  <main id="main"></main>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.21.1/axios.min.js"></script>
  <script src="script.js"></script>
</body>

看起来它现在可以工作了...您可能想稍后在您的地图上使用 setCenter 将视图移动到新位置 - 在 mapInit 之后执行此操作

还添加了一些 CSS - 为地图元素指定大小并缩小您拥有的巨大标志。

【讨论】:

  • 效果很好,谢谢!现在我只需要弄清楚如何为每个搜索请求将 API 中的 long 和 lat 值传递到地图中。哈!
  • @MattDavis 只需将map.setCenter(new google.maps.LatLng(...countryData.latlng)); 放在mapInit() 调用下... P.S.:您还应该阅读参考资料 - 您可以做的更多。 developers.google.com/maps/documentation/javascript/reference/…
【解决方案2】:

我可以看到你常量中的 url 是错误的......正确的是:

'https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap'

另一件事你永远不会调用addGMapsEl() 函数来初始化地图。

最后,.card-content 元素没有出现在 DOM 上。

要在地图上显示国家/地区,您应该创建一个事件来处理它

$(document).on("input", "#search", function(e){
   //handle input information here
})

【讨论】:

  • 我错过了sn-p中的一些JS,我现在已经更正了。我可以追加到主 div,但我想在卡片插入 DOM 后追加到
    中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-02-06
  • 2012-04-19
  • 2012-06-14
  • 2015-12-12
  • 1970-01-01
相关资源
最近更新 更多