Skip to content
Advertisement

Tooltip in leaflet.js flickers so users can’t click on link inside it

I am using bindTool tip to create pop up elements with html and links within them

.bindTooltip(function (layer) {
  let tooltip1 =
    "<h2>" +
    layer.feature.properties.NAME +
    '</h2> <a href="' +
    layer.feature.properties.LINK +
    '" target="_blank">' +
    '<img src="' +
    layer.feature.properties.IMAGE +
    '" width=300></a>';
  return tooltip1;
}, customOptions)

in Custom options I have the following

  className: "popupCustom",
  interactive: true,

EDIT – There is flickering when the tooltip is hovered over – it appears to be activating mouseover and mouseout at the same time.

I am working on this project in a glitch project here /

Code – https://glitch.com/edit/#!/leaflet-map-3valleys?path=script.js%3A95%3A0

Resulting map – https://leaflet-map-3valleys.glitch.me/

What should I change to make this correct / consistent?

Advertisement

Answer

Are you sure this is your problem?
After all, clicking on the icon in the popup is practically impossible. This window is flashing so fast that you really need to be the world champion in CS:GO to shoot the click 😉

Below is a gif of what it looks like. It doesn’t reflect the blink speed because it’s an optimized GIF, but I assure you the problem is that you are using mouseover and mouseout at the same time.

enter image description here

— EDIT —

It no longer blinks like crazy, there is only one blink left, but you will solve this problem yourself 😉

// make the map
let map = L.map("map", {
  center: [53.713, -2.096],
  zoom: 16,
  scrollWheelZoom: false,
});
// add the basemap tiles
L.tileLayer(
  "https://stamen-tiles-{s}.a.ssl.fastly.net/watercolor/{z}/{x}/{y}.png" // stamen toner tiles
).addTo(map);

let geojson; // this is global because of resetHighlight

// change style
function highlightFeature(e) {
  const layer = e.target;

  layer.setStyle({
    weight: 3, // thicker border
    color: "#000", // black
    fillOpacity: 0.5, // a bit transparent
  });

  layer.openPopup();
}

// reset to normal style
function resetHighlight(e) {
  const layer = e.target;

  geojson.resetStyle(layer);

  if (layer.isPopupOpen()) {
    layer.closePopup();
  }
}

// zoom to feature (a.k.a. fit the bounds of the map to the bounds of the feature
function zoomToFeature(e) {
  map.fitBounds(e.target.getBounds());
}

// attach the event handlers to events
function onEachFeature(feature, layer) {
  const popupcontent = `
    <a href="${layer.feature.properties.LINK}" target="_blank">
      <h2>${layer.feature.properties.NAME}</h2>
      <img src="${layer.feature.properties.IMAGE}" width=300>
    </a>`;

  const content = L.DomUtil.create("div", "popup-content");
  content.insertAdjacentHTML("afterbegin", popupcontent);
  const myPopup = L.popup().setContent(content);
  layer.bindPopup(myPopup);

  content.addEventListener("mouseenter", (e) => {
    if (e.target.closest(".leaflet-popup")) {
      layer.openPopup();
      console.log("mouseover");
    }
  });

  content.addEventListener("mouseleave", (e) => {
    if (e.target.closest(".leaflet-popup")) {
      console.log("mouseleave");
      layer.closePopup();
    }
  });

  layer.on("mouseover", highlightFeature);
  layer.on("mouseout", resetHighlight);
  layer.on("click", zoomToFeature);
}

// get the data
fetch("https://leaflet-map-3valleys.glitch.me/data/tod_data.json")
  .then((response) => response.json())
  .then((json) => doThingsWithData(json));

// once the data is loaded, this function takes over
function doThingsWithData(json) {
  // assign colors to each "PATTERN" (a.k.a. Game Mechanics)
  let colorObj = assignColors(json, "PATTERN");
  // add the data to the map
  geojson = L.geoJSON(json, {
    style: function (feature) {
      return {
        color: colorObj[feature.properties.PATTERN], // set color based on colorObj
        weight: 2.7, // thickness of the border
        fillOpacity: 0.6, // opacity of the fill
      };
    },
    onEachFeature,
  }).addTo(map); // add it to the map
}

// create an object where each unique value in prop is a key and
// each key has a color as its value
function assignColors(json, prop) {
  // from ColorBrewer http://colorbrewer2.org
  let colors = [
    "#6a3d9a",
    "#ffff99",
    "#b15928",
    "#a6cee3",
    "#1f78b4",
    "#b2df8a",
    "#33a02c",
    "#fb9a99",
    "#e31a1c",
    "#fdbf6f",
    "#ff7f00",
    "#cab2d6",
  ];
  let uniquePropValues = []; // create an empty array to hold the unique values
  json.features.forEach((feature) => {
    // for each feature
    if (uniquePropValues.indexOf(feature.properties[prop]) === -1) {
      uniquePropValues.push(feature.properties[prop]); // if the value isn't already in the list, add it
    }
  });
  let colorObj = {}; // create an empty object
  uniquePropValues.forEach((prop, index) => {
    // for each unique value
    colorObj[prop] = colors[index]; // add a new key-value pair to colorObj
  });
  return colorObj;
}
*,
:after,
:before {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

html {
  height: 100%;
}

body,
html,
#map {
  width: 100%;
  height: 100%;
}

body {
  position: relative;
  min-height: 100%;
  margin: 0;
  padding: 0;
  background-color: #f1f1f1;
}
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" rel="stylesheet"/>
<div id="map"></div>
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement