如何检查 svg 路径是否具有与数组中的值匹配的类,如果是,则添加新类

How to check if a svg path has a class that matches a value in array and if so add a new class(如何检查 svg 路径是否具有与数组中的值匹配的类,如果是,则添加新类)

本文介绍了如何检查 svg 路径是否具有与数组中的值匹配的类,如果是,则添加新类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个数组和一些 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 &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/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>

推荐答案

你的错误很微妙.您从 Strings:

Your bug is subtle. You are starting with an Array of Strings:

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.

您可能想要做的是使用 SVGAnimatedStrings 的>baseVal 属性:

What you probably want to do is use the baseVal property of the SVGAnimatedStrings:

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 路径是否具有与数组中的值匹配的类,如果是,则添加新类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何检查 svg 路径是否具有与数组中的值匹配的类,如果是,则添加新类

基础教程推荐