問題描述
我有一個數組和一些 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 >OpenStreetMap</a> contributors, ' + '<a + 'Imagery ? <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 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模板網!