我有一个数组和一些 svg path
元素(我正在使用 传单地图).我需要检查路径的类是否与我的数组中的某个值匹配,如果是,请向其添加一个类 fadeIn
.
I have an array and some svg path
elements (I am using leaflet map). I need to check if the class of a path matches one of the values in my array and if so add a class fadeIn
to it.
var foundNations = ["usa", "France", "Italy"];
document.querySelectorAll('path').forEach(path => {
if (foundNations.includes(path.className)) {
path.className.add('fadeIn');
console.log(path.className);
}
});
(function($) {
var map = L.map('map').setView([45.4655171, 12.7700794], 2);
map.fitWorld().zoomIn();
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' + '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' + 'Imagery © <a href="http://mapbox.com">Mapbox</a>',
id: 'mapbox.light'
}).addTo(map);
var mapHalfHeight = map.getSize().y / 2,
container = map.zoomControl.getContainer(),
containerHalfHeight = parseInt(container.offsetHeight / 2),
containerTop = mapHalfHeight - containerHalfHeight + 'px';
container.style.position = 'absolute';
container.style.top = containerTop;
map.scrollWheelZoom.disable();
var southWest = L.latLng(-89.98155760646617, -180),
northEast = L.latLng(89.99346179538875, 180);
var bounds = L.latLngBounds(southWest, northEast);
map.setMaxBounds(bounds);
map.on('drag', function() {
map.panInsideBounds(bounds, { animate: false });
});
// 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: 1,
opacity: 1,
color: '#ffffff',
dashArray: '',
fillOpacity: 0,
fillColor : '#FF0080',
className: feature.properties.name
};
}
var geojson;
function selectNation(e) {
}
function onEachFeature(feature, layer) {
layer.on({
click: selectNation
});
}
geojson = L.geoJson(statesData, {
style: style,
onEachFeature: onEachFeature
}).addTo(map);
})( jQuery );
#map {
width: 100vw;
height: 100vh;
}
.fadeIn {
fill: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet.js"></script>
<link href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" rel="stylesheet"/>
<script src="https://www.jikupin.com/world.json"></script>
<div id='map'></div>
你的错误很微妙.您从 String
s:
Your bug is subtle. You are starting with an Array
of String
s:
var nationList = ["usa", "france", "italy"];
然后你调用 String.prototype.includes
,将 path.className
作为参数传递.
Then you're calling String.prototype.includes
, passing path.className
as an argument.
if (foundNations.includes(path.className)) { path.classList.add('fadeIn')
在那里,您隐含地假设 path.className
是一个String
.但是,令人惊讶的是,它不是 String
,而是 SVGAnimatedString
!
In there, you're implicitly assuming that path.className
is a String
. But, surprise surprise, it's not a String
, it's a SVGAnimatedString
!
console.log(path.className)
> [object SVGAnimatedString] {
animVal: "germany",
baseVal: "germany"
}
是的,在某些极端情况下,SVG 元素的类名可以在动画期间进行修改.
Yes, class names for SVG elements can be modified during animations in some edge cases.
您可能想要做的是使用 SVGAnimatedString
s 的>baseVal 属性:
What you probably want to do is use the baseVal
property of the SVGAnimatedString
s:
console.log(typeof path.className.baseVal)
> "string"
现在一切都应该按照您期望的方式更紧密地工作:
And now everything should work more closely to the way you expect:
if (foundNations.includes(path.className.baseVal)) {
path.classList.add('fadeIn')
}
console.log(path.className.baseVal);
> "spain fadeIn"
<小时><小时>
由于另一个假设,您还有第二个问题.您假设 path.className
只包含 一个 类名,但 根据文档,强调我的:
You have a second problem, due to another assumption. You're assuming that path.className
contains just one class name, but according to the documentation, emphasis mine:
cName
是一个字符串变量,表示当前元素的类或空格分隔的类.
cName
is a string variable representing the class or space-separated classes of the current element.
事实上,如果您使用浏览器中提供的开发人员工具来检查 SVG 元素,您会看到类似...
In fact, if you use the developer tools available in your browser to inspect the SVG elements, you'll see things like...
<path class="Italy leaflet-interactive" stroke="#ffffff" ....></path>
所以在这种情况下,您假设 className.baseVal
将是字符串 "Italy"
,但实际上,它的值是 意大利传单互动"
.
So in this case, you're assuming that the className.baseVal
is going to be the string "Italy"
, but in reality, it takes the value "Italy leaflet-interactive"
.
这里的方法是使用 Element.classList
遍历类名s 以查看其中是否有 任何 匹配给定组.
The approach here is to use Element.classList
to iterate through the class names to see if any of them match a given
group.
此外,我认为这是 XY 问题的一个实例.我想你不想问
Furthermore, I think that this is an instance of the XY problem. I don't think you wanted to ask
如何检查 SVG 路径是否有一个匹配 foo
的类?
How to check if a SVG path has a class that maches
foo
?
而是
当特征匹配 foo
时,如何在 Leaflet 中符号化 SVG 多边形?
How to symbolize a SVG polygon in Leaflet when the feature matches
foo
?
因为我认为将检查移到 style
回调函数中更优雅,例如:
Because I think that it is way more elegant to move the checks into the style
callback function, like:
geojson = L.geoJson(statesData, {
style: function(feature){
var polygonClassName = feature.properties.name;
if (nationList.contains(feature.properties.name)) {
polygonClassName += ' fadeIn';
}
return {
weight: 1,
opacity: 1,
color: '#ffffff',
dashArray: '',
fillOpacity: 0,
fillColor : '#FF0080',
className: polygonClassName
};
},
onEachFeature: onEachFeature
}).addTo(map);
Leaflet 提供了方便的功能,例如 L.Path.setStyle
隐藏了直接处理选择器和 SVG 类的复杂性,只要您保留对 L.Polygon
实例的引用(在这种情况下,您可以这样做在 onEachFeature
回调中).
Leaflet offers convenient functionality like L.Path.setStyle
that hides the complexity of dealing with selectors and SVG classes directly, as long as you keep references to your instances of L.Polygon
around (which, in this case, you can do in the onEachFeature
callback).
这篇关于如何检查 svg 路径是否具有与数组中的值匹配的类,如果是,则添加新类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!