У меня есть массив и некоторые элементы svg path (я использую листовка карта). Мне нужно проверить, соответствует ли класс пути одному из значений в моем массиве, и, если да, добавить к нему класс fadeIn.
var foundNations = ["usa", "France", "Italy"];
document.querySelectorAll('path').forEach(path => {
if (foundNations.includes(path.className)) {
path.className.add('fadeIn');
console.info(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/[email protected]/dist/leaflet.js"></script>
<link href = "https://unpkg.com/[email protected]/dist/leaflet.css" rel = "stylesheet"/>
<script src = "https://www.jikupin.com/world.json"></script>
<div id='map'></div>@ CarstenLøvboAndersen Меня попросили удалить второй и перефразировать его, проверьте последние комментарии прямо под другим вопросом
Пожалуйста, сделайте пример работоспособный (как я сказал раньше); вот как.
@ rob.m - Лучше всего удалить этот вопрос. Что касается этого комментария, он все еще там.
@ T.J.Crowder Я пытаюсь запустить код, как вы предложили ... но я не могу удалить другой вопрос, поскольку есть ответы, и он не позволяет мне отказаться.
@ T.J. Crowder, вот и мы, я сделал интерактивный пример, работающий здесь



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Ваша ошибка неуловима. Вы начинаете с Array из String:
var nationList = ["usa", "france", "italy"];
Затем вы вызываете String.prototype.includes, передавая path.className в качестве аргумента.
if (foundNations.includes(path.className)) { path.classList.add('fadeIn')
Там вы неявно предполагая, что path.className - это String. Но, сюрприз-сюрприз, это не String, это SVGAnimatedString!
console.info(path.className)
> [object SVGAnimatedString] {
animVal: "germany",
baseVal: "germany"
}
Да, в некоторых крайних случаях имена классов для элементов SVG можно изменять во время анимации.
Вероятно, вы захотите использовать baseVal свойство SVGAnimatedStrings:
console.info(typeof path.className.baseVal)
> "string"
И теперь все должно работать более точно так, как вы ожидаете:
if (foundNations.includes(path.className.baseVal)) {
path.classList.add('fadeIn')
}
console.info(path.className.baseVal);
> "spain fadeIn"
У вас есть вторая проблема, связанная с другим предположением. Вы предполагая, что path.className содержит только имя класса один, но согласно документации, акцент мой:
cNameis a string variable representing the class or space-separated classes of the current element.
Фактически, если вы используете инструменты разработчика, доступные в вашем браузере, для проверки элементов SVG, вы увидите такие вещи, как ...
<path class = "Italy leaflet-interactive" stroke = "#ffffff" ....></path>
Итак, в этом случае вы предполагаете, что className.baseVal будет строкой "Italy", но на самом деле она принимает значение "Italy leaflet-interactive".
Подход здесь состоит в том, чтобы использовать Element.classList для итерации по имени класса s, чтобы увидеть, соответствует ли любой из них заданному
группа.
Кроме того, я думаю, что это экземпляр XY проблема. Я не думаю, что ты хотел спросить
How to check if a SVG path has a class that maches
foo?
скорее
How to symbolize a SVG polygon in Leaflet when the feature matches
foo?
Потому что я считаю более элегантным переместить проверки в функцию обратного вызова style, например:
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).
Спасибо, я добавил этот бит в код вопроса, но он все еще не работает
Отлично! Большое спасибо, имеет смысл
чем этот вопрос отличается от stackoverflow.com/questions/50717978/…