Deepak Pandey
Deepak Pandey

Reputation: 628

Openlayers tiles not loading on a tabed web page

If I have three tabs on a page and the openlayer map is on the second page which is not current by default. The map tiles does not load when I click on the second tab. the map tiles load only when I resize the web document window. this is happening on all the browsers. below is the code for your reference. jsfiddle link

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://openlayers.org/en/v4.0.1/css/ol.css" type="text/css">
<style>
.map {
        height: 400px;
        width: 100%;
      }
body {font-family: "Lato", sans-serif;}

/* Style the tab */
div.tab {
    overflow: hidden;
    border: 1px solid #ccc;
    background-color: #f1f1f1;
}

/* Style the buttons inside the tab */
div.tab button {
    background-color: inherit;
    float: left;
    border: none;
    outline: none;
    cursor: pointer;
    padding: 14px 16px;
    transition: 0.3s;
    font-size: 17px;
}

/* Change background color of buttons on hover */
div.tab button:hover {
    background-color: #ddd;
}

/* Create an active/current tablink class */
div.tab button.active {
    background-color: #ccc;
}

/* Style the tab content */
.tabcontent {
    display: none;
    padding: 6px 12px;
    border: 1px solid #ccc;
    border-top: none;
}

/* Style the close button */
.topright {
    float: right;
    cursor: pointer;
    font-size: 20px;
}

.topright:hover {color: red;}
</style>
</head>
<body>

<p>Click on the x button in the top right corner to close the current tab:</p>

<div class="tab">
  <button class="tablinks" onclick="openCity(event, 'London')" id="defaultOpen">London</button>
  <button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
  <button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>

<div id="London" class="tabcontent">
  <span onclick="this.parentElement.style.display='none'" class="topright">x</span>
  <h3>London</h3>
  <p>London is the capital city of England.</p>
</div>

<div id="Paris" class="tabcontent">
  <span onclick="this.parentElement.style.display='none'" class="topright">x</span>
  <h3>Paris</h3>
  <p>Paris is the capital of France.</p>
  <div id="map" class="map"></div>
</div>

<div id="Tokyo" class="tabcontent">
  <span onclick="this.parentElement.style.display='none'" class="topright">x</span>
  <h3>Tokyo</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>
<script src="https://openlayers.org/en/v4.0.1/build/ol.js" type="text/javascript"></script>
<script>
function openCity(evt, cityName) {
    var i, tabcontent, tablinks;
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }
    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    document.getElementById(cityName).style.display = "block";
    evt.currentTarget.className += " active";
}

// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();

    var map = new ol.Map({
        target: 'map',
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        view: new ol.View({
          center: ol.proj.fromLonLat([37.41, 8.82]),
          zoom: 4
        })
      });
</script>

</body>
</html>

Upvotes: 2

Views: 1602

Answers (4)

Deepak Pandey
Deepak Pandey

Reputation: 628

The problem with the codebase I am working with is that, the create a new map is called when the page is being loaded, so if I try to create a new map with something like this

onclick="openCity(event, 'Paris'), init()"

this is creating one more map div container.

I am able to solve the issue by using

map.updateSize();

but I am calling it asynchronously on onClick event is fired

setTimeout(function() { Compass.map.updateSize(); }, 0);

Upvotes: 1

rrrm93
rrrm93

Reputation: 416

Hope this works

on the onclick event for the tabs add function init like this

   <button class="tablinks" onclick="openCity(event, 'Paris'), init()">Paris</button>

then on the js code create function init and put the map inside it

  function init() {
    var map = new ol.Map({
      target: 'map',
      layers: [
        new ol.layer.Tile({
          source: new ol.source.OSM()
        })
      ],
      view: new ol.View({


        center: ol.proj.fromLonLat([37.41, 8.82]),
        zoom: 4
      })
    });
  }

https://jsfiddle.net/4cm8eqvn/2/

Upvotes: 0

Roger Russel
Roger Russel

Reputation: 759

The main problem is because image not load when it is not visible on page. That is why the background is not showing.

All times that I had this problem I changed my JS to walkaround this.

This is JsFindle is not the best solution, but it will work.

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://openlayers.org/en/v4.0.1/css/ol.css" type="text/css">
<style>
.map {
        height: 400px;
        width: 100%;
      }
body {font-family: "Lato", sans-serif;}

/* Style the tab */
div.tab {
    overflow: hidden;
    border: 1px solid #ccc;
    background-color: #f1f1f1;
}

/* Style the buttons inside the tab */
div.tab button {
    background-color: inherit;
    float: left;
    border: none;
    outline: none;
    cursor: pointer;
    padding: 14px 16px;
    transition: 0.3s;
    font-size: 17px;
}

/* Change background color of buttons on hover */
div.tab button:hover {
    background-color: #ddd;
}

/* Create an active/current tablink class */
div.tab button.active {
    background-color: #ccc;
}

/* Style the tab content */
.tabcontent {
    display: none;
    padding: 6px 12px;
    border: 1px solid #ccc;
    border-top: none;
}

/* Style the close button */
.topright {
    float: right;
    cursor: pointer;
    font-size: 20px;
}

.topright:hover {color: red;}
</style>
</head>
<body>

<p>Click on the x button in the top right corner to close the current tab:</p>

<div class="tab">
  <button class="tablinks" onclick="openCity(event, 'London')" id="defaultOpen">London</button>
  <button class="tablinks" onclick="openCity(event, 'Paris'); newMap('Paris')">Paris</button>
  <button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>

<div id="London" class="tabcontent">
  <span onclick="this.parentElement.style.display='none'" class="topright">x</span>
  <h3>London</h3>
  <p>London is the capital city of England.</p>
</div>

<div id="Paris" class="tabcontent">
  <span onclick="this.parentElement.style.display='none'" class="topright">x</span>
  <h3>Paris</h3>
  <p>Paris is the capital of France.</p>
  <div id="map" class="map"></div>
</div>

<div id="Tokyo" class="tabcontent">
  <span onclick="this.parentElement.style.display='none'" class="topright">x</span>
  <h3>Tokyo</h3>
  <p>Tokyo is the capital of Japan.</p>
</div>
<script src="https://openlayers.org/en/v4.0.1/build/ol.js" type="text/javascript"></script>
<script>
function openCity(evt, cityName) {
    var i, tabcontent, tablinks;
    tabcontent = document.getElementsByClassName("tabcontent");
    for (i = 0; i < tabcontent.length; i++) {
        tabcontent[i].style.display = "none";
    }
    tablinks = document.getElementsByClassName("tablinks");
    for (i = 0; i < tablinks.length; i++) {
        tablinks[i].className = tablinks[i].className.replace(" active", "");
    }
    document.getElementById(cityName).style.display = "block";
    evt.currentTarget.className += " active";
}

// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
var maps = {};
function newMap(name){

        if(!maps[name]){

    maps[name] = new ol.Map({
        target: 'map',
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        view: new ol.View({
          center: ol.proj.fromLonLat([37.41, 8.82]),
          zoom: 4
        })
      });

    }


}      
</script>

</body>
</html>

these are the parts wich I changed.

  <button class="tablinks" onclick="openCity(event, 'Paris'); newMap('Paris')">Paris</button>

var maps = {};
function newMap(name){

        if(!maps[name]){

    maps[name] = new ol.Map({
        target: 'map',
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        view: new ol.View({
          center: ol.proj.fromLonLat([37.41, 8.82]),
          zoom: 4
        })
      });

    }

}  

Upvotes: 0

kaycee
kaycee

Reputation: 911

You could just add this in your openCity() function and it will work:

if(cityName == 'Paris') {
    map.updateSize();
}

Working fiddle: https://jsfiddle.net/rLa0bk2d/1/

Upvotes: 0

Related Questions