Как проверить, есть ли в пути svg класс, который соответствует значению в массиве, и если да, добавить новый класс

У меня есть массив и некоторые элементы 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 &copy; <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>

чем этот вопрос отличается от stackoverflow.com/questions/50717978/…

Carsten Løvbo Andersen 06.06.2018 12:48

@ CarstenLøvboAndersen Меня попросили удалить второй и перефразировать его, проверьте последние комментарии прямо под другим вопросом

rob.m 06.06.2018 12:49

Пожалуйста, сделайте пример работоспособный (как я сказал раньше); вот как.

T.J. Crowder 06.06.2018 12:56

@ rob.m - Лучше всего удалить этот вопрос. Что касается этого комментария, он все еще там.

T.J. Crowder 06.06.2018 12:57

@ T.J.Crowder Я пытаюсь запустить код, как вы предложили ... но я не могу удалить другой вопрос, поскольку есть ответы, и он не позволяет мне отказаться.

rob.m 06.06.2018 13:04

@ T.J. Crowder, вот и мы, я сделал интерактивный пример, работающий здесь

rob.m 06.06.2018 13:06
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
6
444
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваша ошибка неуловима. Вы начинаете с 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 содержит только имя класса один, но согласно документации, акцент мой:

cName is 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).

Спасибо, я добавил этот бит в код вопроса, но он все еще не работает

rob.m 06.06.2018 13:39

Отлично! Большое спасибо, имеет смысл

rob.m 06.06.2018 14:05

Другие вопросы по теме