最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to clear leaflet layer after click - Stack Overflow

programmeradmin1浏览0评论

I try to select/deselect the layer using a mouse click. Firstly my map is in this way

After clicking on a layer I want to select it and highlight

Now if I click again on the previously selected layer, I want to deselect it and reset the highlight. This is the code that I use to do this:

  onEachFeature: function(feature,layer) {

      layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
      layer.on('click', function(e) {

      let isLayerAlreadySelected =  // Some logic to undestand if layer alreeady selected

      if(isLayerAlreadySelected) 
         layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
      else
          layer.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});
      }

  }

But sometimes when I try to deselect previously selected layer, the layer style is not resetting the opacity remains. Some suggestions about this?

I try to select/deselect the layer using a mouse click. Firstly my map is in this way

After clicking on a layer I want to select it and highlight

Now if I click again on the previously selected layer, I want to deselect it and reset the highlight. This is the code that I use to do this:

  onEachFeature: function(feature,layer) {

      layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
      layer.on('click', function(e) {

      let isLayerAlreadySelected =  // Some logic to undestand if layer alreeady selected

      if(isLayerAlreadySelected) 
         layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
      else
          layer.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});
      }

  }

But sometimes when I try to deselect previously selected layer, the layer style is not resetting the opacity remains. Some suggestions about this?

Share Improve this question edited Jan 14, 2020 at 7:55 Mukyuu 6,7698 gold badges41 silver badges63 bronze badges asked Jan 9, 2020 at 11:21 SkizzoSkizzo 2,9839 gold badges59 silver badges102 bronze badges 1
  • 1 can you create stackblitz? – Chellappan வ Commented Jan 13, 2020 at 14:51
Add a ment  | 

5 Answers 5

Reset to default 10 +100

Simply you can use resetStyle() method to reset given vector layer's style to the original GeoJSON style.

var map = L.map('map').setView([37.8, -96], 4);

	L.tileLayer('http://{s}.tile.osm/{z}/{x}/{y}.png', {
		maxZoom: 18,
		attribution: '&copy; <a href="http://osm/copyright">OpenStreetMap</a> contributors'
	}).addTo(map);




	// get color depending on population density value
	function getColor(d) {
		return d > 1000 ? '#800026' :
				d > 500  ? '#BD0026' :
				d > 200  ? '#E31A1C' :
				d > 100  ? '#FC4E2A' :
				d > 50   ? '#FD8D3C' :
				d > 20   ? '#FEB24C' :
				d > 10   ? '#FED976' :
							'#FFEDA0';
	}

	function style(feature) {
		return {
			weight: 2,
			opacity: 1,
			color: 'white',
			dashArray: '3',
			fillOpacity: 0.7,
			fillColor: getColor(feature.properties.density)
		};
	}

	function highlightFeature(e) {
    geojson.resetStyle();
		var layer = e.target;

		layer.setStyle({
			weight: 5,
			color: '#666',
			dashArray: '',
			fillOpacity: 0.7
		});

		if (!L.Browser.ie && !L.Browser.opera && !L.Browser.edge) {
			layer.bringToFront();
		}

	}

	var geojson;

	function resetHighlight(e) {
		geojson.resetStyle(e.target);
	}

	function zoomToFeature(e) {
		map.fitBounds(e.target.getBounds());
	}
    // Set style function that sets fill color property
function style(feature) {
    return {
        fillColor: '#004691', 
        fillOpacity: 0.5,  
        weight: 1,
        opacity: 1,
        color: '#424a44',
        dashArray: '1'
    };
}
	var highlight = {
		'fillColor': 'yellow',
		'weight': 1,
		'opacity': 1
	};

	function onEachFeature(feature, layer) {
		layer.on({
			
			click: highlightFeature
		});
        
	}

	geojson = L.geoJson(statesData, {
		style: style,
		onEachFeature: onEachFeature
	}).addTo(map);
#map {
         width: 600px;
         height: 400px;
         }
<link rel="stylesheet" href="https://unpkg./[email protected]/dist/leaflet.css" crossorigin=""/>
    <script src="https://unpkg./[email protected]/dist/leaflet.js"crossorigin=""></script>
      
       <div id='map'></div>
      <script type="text/javascript" src="https://leafletjs./examples/choropleth/us-states.js"></script>

You can refer this and this for more info.

Hope this will helps you.

First you could slightly simplify your code by setting your "base" style using the Leaflet GeoJSON factory style option. That way, your highlight function can reset the style conveniently using the Leaflet GeoJSON Layer Group resetStyle() method:

let selected = false;

function onEachFeature(feature, layer) {
  layer.on("click", function() {
    selected = !selected;
    if (selected) {
      layer.setStyle({
        fillOpacity: 0.4,
        color: '#004691',
        weight: 3
      });
    } else {
      geojsonLayerGroup.resetStyle(layer);
    }
  });
}

const map = L.map('map').setView([48.86, 2.35], 11);

const geojsonData = {
  "type": "Feature",
  "geometry": {
    "type": "Polygon",
    "coordinates": [
      [
        [2.35, 48.88],
        [2.32, 48.84],
        [2.38, 48.84],
        [2.35, 48.88]
      ]
    ]
  },
  "properties": {}
};

const geojsonLayerGroup = L.geoJSON(geojsonData, {
  onEachFeature: onEachFeature,
  style: {
    fillOpacity: 0.0,
    color: '#424a44',
    weight: 2
  }
}).addTo(map);

L.tileLayer('https://{s}.tile.openstreetmap/{z}/{x}/{y}.png', {
  attribution: '&copy; <a href="http://osm/copyright">OpenStreetMap</a> contributors'
}).addTo(map);
html,
body,
#map {
  height: 100%;
  margin: 0;
}
<link rel="stylesheet" href="https://unpkg./[email protected]/dist/leaflet.css" integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ==" crossorigin="" />
<script src="https://unpkg./[email protected]/dist/leaflet.js" integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew==" crossorigin=""></script>

<div id="map"></div>

Now from your ments, it sounds like you might run in the funny troubles of Angular zone. Actions that occur outside Angular Zone may not be painted by the browser.

If you try deselecting your layer and nothing seems to happen, try another action somewhere else in the browser: click somewhere else, resize the window, etc. If the deselection suddenly triggers, then it is most probably the effect of Angular Zone.

You could check by color and or the weight this will mean you have to overwrite the current behavior of highlight(Hover ie both the mouseover and mouseout) behavior so that you can differentiate when there is a click. this will mean doing something like

function onEachFeature(feature, layer) {
    layer.on({
        mouseover: highlightFeature,
        mouseout: resetHighlight,
        click: selectLayer
    });
}

then selectLayer will be as

function selectLayer(e) {
      let isLayerAlreadySelected =  ((e.target.options.color === '#004691') &&(e.target.options.weight === 3))

      if(isLayerAlreadySelected) 
         layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
      else
          layer.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});
}

This will mean that the highlightFeature will be as follows

//Here you should set the highlight features different from when its clicked particularly take note of your wight and color since its what we use for the logic.
function highlightFeature(e) {
    let layer = e.target;

    layer.setStyle({
        weight: 1,
        color: '#666',
        fillOpacity: 0.1
    });

}

similarly resetHighlight will be like

//basically you will be putting the styles to their default here what ever values you choosed as default
function resetHighlight(e) {
    let layer = e.target;

    layer.setStyle({
        weight: 0,
        color: '#424a44',
        fillOpacity: 0
    });

}

You might find this documentation useful leaflet layer

you can prefer a swapping of mouse event functions to perform delection of highlighted layer

layer.setStyle({
                    fillColor: getRandomColor(),
                    fillOpacity: 0.50,
                    stroke: false
                });
                layer.on('mouseover', function(e) {
           highlightFeature(e);
  //open popup;
    var popup = L.popup()
   .setLatLng(e.latlng)
   .setContent(feature.properties.Name)
   .openOn(mymap);

   });
      layer.on('mouseout', function(e) {
           defaultFeature(e);
  //open popup;
    var popup = L.popup()
   .setLatLng(e.latlng)
   .setContent(feature.properties.Name)
   .openOn(mymap);
    });

defaultfeature() is defined to perform deselection

function getRandomColor() {
  var letters = '0123456789ABCDEF';
  var color = '#';
  for (var i = 0; i < 6; i++) {
    color += letters[Math.floor(Math.random() * 16)];
  }
  return color;
}


function highlightFeature(e) {
    highlightLayer = e.target;
    if (e.target.feature.geometry.type === 'LineString') {
      highlightLayer.setStyle({
        color: '#ffff00',
      });
    } else {
      highlightLayer.setStyle({
        fillColor: getRandomColor(),
        fillOpacity: .25
      });
    }
}
function defaultFeature(e) {

    if (e.target!=null) {
      highlightLayer.setStyle({
        color: getRandomColor(),
        fillOpacity:.50
      });
    } else {
      highlightLayer.setStyle({
        fillColor: highlightFeature(),
        fillOpacity: .25
      });
    }
}

You can test which color the layer has:

onEachFeature: function(feature,layer) {

      layer.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
      layer.on('click', function(e) {

          let isLayerAlreadySelected =  e.target.options.color === '#004691';

          if(isLayerAlreadySelected) 
             e.target.setStyle({fillOpacity: 0.0 , color: '#424a44', weight: 2});
          else
             e.target.setStyle({fillOpacity: 0.4 , color: '#004691', weight: 3});

     });
}
发布评论

评论列表(0)

  1. 暂无评论