简体   繁体   中英

Bootstrap carousel with multiple Google maps not working properly

I have couple Google maps as slide in Bootstrap carousel. The problem is only the map with initial active works properly. All others just doesn't work.

I've searched similar questions and people seems to suggest using a function to resize the page. But I am really new to Javascript and not sure how does that work for my multiple maps. I've tried a lot, but it keeps break. Really need help.

What should I do? I actually have more slides, but I thought it might be too many to put them up.

Part of my html is here:

<div class="carousel" id="intro">

          <ol class="carousel-indicators">
              <li data-target="#intro" data-slide-to="0" class="active"></li>
              <li data-target="#intro" data-slide-to="1"></li>
              <li data-target="#intro" data-slide-to="2"></li>
          </ol>



          <div class="carousel-inner">
              <div class="item active">
                  <div class="carousel-content">
                      <div class="carousel-caption">
                          <h2>Spring Dawn at Su Causeway</h2>
                          <img src="img/su.jpg" />
                          <p>Su Shi, an outspoken official as well as a renowned painter, poet and art theorist, was made prefect of Hangzhou in 1089 during the Northern Song Dynasty. By that time, West Lake had shrunken to half its previous size due to increased land usage around the lake and was choked with weeds.</p>

                          <div id="sudi"></div>
                      </div>
                  </div>

              </div>

              <div class="item">
                  <div class="carousel-content">
                      <div class="carousel-caption">
                          <h2>Lotus in the Breeze at Crooked Courtyard</h2>
                          <img src="img/qu.jpg" />
                          <p>The imperial family of the Southern Song Dynasty kept their imperial brewery, Quyuan, close to the banks of West Lake in their capital city, Hangzhou. When the gentle summer breeze blew through lotuses kept in the lake near the brewery, it mixed with the smells of alcohol and was said to make even those not drinking feel intoxicated.</p>
                         <div id="quyuan"></div> 
                      </div>                 
                  </div>
              </div>

              <div class="item">
                  <div class="carousel-content">
                      <div class="carousel-caption">
                          <h2>Melting Snow on Broken Bridge</h2>
                          <img src="img/duan.jpg" />
                          <P>In keeping with the seasonal theme, Lingering Snow on Broken Bridge takes in the view from the arched Broken Bridge, located at the eastern end of the Bai Causeway, the day after snow has fallen. To the northwest, the view takes in the snow-covered buildings and hill at Gu Shan while the rest of the lake stretches out in black contrast to the south, with the snowy white hills around it.</P>
                          <div id="duanqiao"></div>
                      </div>
                  </div>
              </div>
      </div><!-- carousel-inner -->

      </div>

And my google map related code is here:

function initMap() {

    var mapOptions = {
      sudi: {
        center: {lat: 25.7823072, lng: -80.3011205},
        zoom: 9,
        mapTypeId: google.maps.MapTypeId.ROADMAP, // SATELLITE
        mapTypeControl: false
      },
      quyuan: {
        center: {lat: 26.1410956, lng: -80.2200135},
        zoom: 9,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        mapTypeControl: false
      },
      duanqiao: {
        center: {lat: 25.7823072, lng: -80.3011205},
        zoom: 9,
        mapTypeId: google.maps.MapTypeId.ROADMAP, // SATELLITE
        mapTypeControl: false
      },

    }

    var sudiMap = new google.maps.Map(document.getElementById("sudi"), mapOptions.sudi);
    var quyuanMap = new google.maps.Map(document.getElementById("quyuan"), mapOptions.quyuan);
    var duanqiaoMap = new google.maps.Map(document.getElementById("duanqiao"), mapOptions.duanqiao);
    };

Since all the rest of the slides aren't visible at the moment you're initializing their respective maps, the google maps instances can't get a proper height and width and thus fails to initialize properly. You'll need to trigger a resize on the map instance when it becomes visible. You can do that by listening for the slid.bs.carousel event and then firing the resize event on the corresponding map instance. To get the correct map instance you'll need to somehow create a reference to it in your slide item. A good way to do so is by storing the maps in an object with keys, and storing the keys in a data attribute of the corresponding slide.

Here's html markup, take note of the data-map attributes:

<div id="carousel" class="carousel slide" data-ride="carousel">
    <ol class="carousel-indicators">
        <li data-target="#carousel-example-generic" data-slide-to="0" class="active"></li>
        <li data-target="#carousel-example-generic" data-slide-to="1"></li>
        <li data-target="#carousel-example-generic" data-slide-to="2"></li>
    </ol>
    <div class="carousel-inner" role="listbox">
        <div class="item active" data-map="foo">
            <div id="foo" class="map"></div>
            <div class="carousel-caption">
            ...
            </div>
        </div>
        <div class="item" data-map="bar">
            <div id="bar" class="map"></div>
            <div class="carousel-caption">
            ...
            </div>
        </div>
    </div>
    <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
        <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
        <span class="sr-only">Previous</span>
    </a>
    <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
        <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
        <span class="sr-only">Next</span>
    </a>
</div>

Creating the maps in an object with corresponding keys:

var maps = {
    foo: new google.maps.Map(document.getElementById('foo'), {
        center: new google.maps.LatLng(44.5403, -78.5463),
        zoom: 8,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    }),
    bar: new google.maps.Map(document.getElementById('bar'), {
        center: new google.maps.LatLng(44.5403, -78.5463),
        zoom: 8,
        mapTypeId: google.maps.MapTypeId.SATELLITE
    })
};

Now you can add a listener to the slid.bs.carousel event:

$('#carousel').on('slid.bs.carousel', function (e) {
    // Fetch map from maps object by key from element's data attribute
    var map = maps[e.relatedTarget.dataset.map];
    // Trigger the resize
    google.maps.event.trigger(map, 'resize');
});

Example on Plunker: http://plnkr.co/edit/ROheU2vcGrreAMu3JbAV?p=preview

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM