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

查看:93
本文介绍了如何检查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>

推荐答案

您的错误很微妙.您从ArrayArray开始:

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.classNameString.但是,令人惊讶的是,它不是String,而是

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 的属性:

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",但实际上,它的值是"Italy leaflet-interactive".

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的类?

但是

当要素与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);

传单提供便捷的功能,例如 L.Path.setStyle 隐藏只要保持对L.Polygon实例的引用(在这种情况下,您可以在onEachFeature回调中完成),直接处理选择器和SVG类的复杂性就可以了.

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

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆