2017-10-14 28 views
1

我正在处理传单项目,其中地图上的超过50个标记需要用〜10个复选框进行过滤。过滤器将控制标记的可见性。除了添加用于过滤的类名之外,是否还有更好的分类DOM的方法?

现在,我的方法是为每个过滤条件的每个标记添加一个相应的类名称。我担心在脚本中为超过50个标记分配10个类名会减慢加载时间。

这里是链接 http://jbk1109.github.io/hiking-info.html

这里是我的代码:标记是基于GeoJSON的数据创建和类名在风格功能添加

<div id="distanceFilterContainer"> 

<input type="checkbox" name="checkboxField" class ="distanceFilter" id="short"> 
<label> Under 3 miles </label> 

<input type="checkbox" name="checkboxField" class ="distanceFilter" id="medium"> 
<label> 3-8 miles </label> 

<input type="checkbox" name="checkboxField" class ="distanceFilter" id="long"> 
<label> 8-12 miles </label> 

</div> 


geojson = L.geoJson(data,{ 
    onEachFeature: featureEvent, 
    pointToLayer:function(feature, latlng){ 
     // console.log(latlng.lat) 
     return L.circleMarker(latlng, geojsonMarkerOptions); 
    }, 
    style: style 
}).addTo(mymap) 

function style(feature){ 
    console.log(feature) 
    var length; 
    if (feature.properties.Length <= 3.0){ 
     length = " short" 
    } 
    else if (feature.properties.Length > 3 && feature.properties.Length < 8) 
    { 
     length = " medium" 
    } 
    else if (feature.properties.Length >= 8.0){ 
     length =" long" 
    } 
    console.log(feature.properties.Name + length) 
    return {className : feature.properties.Name + length} 

} 

document.getElementById("short").addEventListener("change",handleDistanceFilter) 
    document.getElementById("medium").addEventListener("change",handleDistanceFilter) 
    document.getElementById("long").addEventListener("change",handleDistanceFilter) 

function handleDistanceFilter(e){ 
    var x = e.target.id 
    console.log(x) 
    if (!e.target.checked){ 
     var filtered = document.getElementsByClassName(x) 
     console.log(x) 
     for (var i =0; i< filtered.length; i++){ 
      filtered[i].classList.remove("hide") 
      // filtered[i].style.visibility = 'visible'; 
     } 
    } 
    else{ 
     var filtered = document.getElementsByClassName(x) 
     for (var i =0; i< filtered.length; i++){ 
      console.log(x) 
      filtered[i].classList.add("hide") 
      // console.log(filtered) 
      // filtered[i].style.visibility = 'hidden'; 
     } 
    } 
    // console.log(e.target.checked) 

} 
+2

这听起来像过早优化的情况下。 “我担心[X]会伤害表现”这句话是未来时态,意味着你实际上并没有发现这种情况。 [你可能是对的,但你也可能是错的。](https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil)浏览器速度很快,并越来越好。建议先看看这是否是个问题。 – hunteke

+0

_“我担心在脚本中为50个以上的标记分配10个类名会减慢加载时间。”_ - 为什么,有任何特定的原因/证据?而且,您是否确实意味着加载时间或某种方式的运行时间性能? – CBroe

+0

运行时间性能 - 现在只有40个标记,但它可能会增加多达5〜600个标记。 – user3562812

回答

0

我建议使用data属性为每个,而不是给他们每个独特的类,除非他们需要明确风格。我实际上并不知道你是否正在进行优化,但是从可维护性的角度来看,另一位开发人员可能会质疑为何所有这些类都会出现。

element.setAttribute('data-name', x); 

然后,你可以用这种方式选择所需的元素(S):

document.querySelectorAll('[data-name=' + x + ']'); 
+0

感谢您的回复。那么,一个“数据名称”可以包含多个类似数据的数据吗?还是我需要为每个数据添加一个“数据”属性? – user3562812

0

如果你不希望这是你的标志太多的类名,你能代替取代你样式函数,其中一个用密钥更新散列作为过滤器,值为所需的元素ID。

例子:

var the_hash = {"short": [], ...} 
function style(feature){ 
    if (feature.isShort()) 
     the_hash["short"].push(feature); 
} 

function handleFilter(filter) { 
    var elements = the_hash[filter]; 
    for (var i = 0, item; item = elements[i]; i++) { 
     item.doSomething(); 
    } 
} 
+0

感谢您的回复。如果我理解正确,the_hash将包含满足条件的数据集? – user3562812

+0

是啊!这里的想法是关键是属性,而数组包含由关键标准描述的元素列表。 –

0

随着传单应避免直接用于标记操纵DOM,作为库仍然跟踪L.circleMarker对象,认为他们仍然在地图上。

相反,你应该只是remove他们,以便图书馆得到适当的通知。

至于过滤当前显示在地图上的标记,也不需要求助于DOM查询,因此必须事先分配一些元数据类(或数据集)以方便查询。

因为您是通过L.geoJSON工厂建立自己的特色,并保持所产生的GeoJSON Layer Group到您的geojson变量,你可以简单地使用它的方法eachLayer以前创建的每个功能层上应用的回调函数。

然后,您可以访问每个图层的GeoJSON属性,因为它是由小册子在layer.feature中引用的。

var map = L.map("map"); 
 

 
var geoJSONdata = { 
 
    "type": "FeatureCollection", 
 
    "features": [{"type": "Feature","properties": {"Length": 8},"geometry": {"type": "Point","coordinates": [-121.7350, 46.7860]}}, 
 
    {"type": "Feature","properties": {"Length": 12},"geometry": {"type": "Point","coordinates": [-121.0750, 48.4755]}}, 
 
    {"type": "Feature","properties": {"Length": 3.2},"geometry": {"type": "Point","coordinates": [-121.8913, 46.6664]}}, 
 
    {"type": "Feature","properties": {"Length": 6.2},"geometry": {"type": "Point","coordinates": [-123.2321, 47.5066]}}, 
 
    {"type": "Feature","properties": {"Length": 8},"geometry": {"type": "Point","coordinates": [-121.6925, 48.8469]}}, 
 
    {"type": "Feature","properties": {"Length": 7.2},"geometry": {"type": "Point","coordinates": [-120.7354, 48.5162]}}] 
 
}; 
 

 
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { 
 
    attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors' 
 
}).addTo(map); 
 

 
var geoJSONlayerGroup = L.geoJSON(geoJSONdata, { 
 
    onEachFeature: onEachFeature 
 
    }).addTo(map); 
 

 
map.fitBounds(geoJSONlayerGroup.getBounds()); 
 

 
var lengthInput = document.getElementById('length'); 
 
var lengthDisplay = document.getElementById('length2'); 
 

 
function filterFeatures() { 
 
    var length = parseFloat(lengthInput.value); 
 
    lengthDisplay.innerHTML = length; 
 
    
 
    geoJSONlayerGroup.eachLayer(function (layer) { 
 
    // Access the layer associated feature GeoJSON properties. 
 
    if (layer.feature.properties.Length <= length) { 
 
     layer.addTo(map); // Directly add to map, instead of using CSS classes. 
 
    } else { 
 
     layer.remove(); // Directly remove from map. 
 
    } 
 
    }); 
 
} 
 

 
filterFeatures(); 
 

 
lengthInput.addEventListener('input', filterFeatures); 
 

 
function onEachFeature(feature, layer) { 
 
    layer.bindPopup(JSON.stringify(feature.properties)); 
 
}
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css"> 
 
<script src="https://unpkg.com/[email protected]/dist/leaflet-src.js"></script> 
 

 
<input type="range" min="0" max="12" step="0.5" id="length" /> 
 
<label for="length">Max length (<span id="length2"></span>)</label> 
 

 
<div id="map" style="height: 170px;"></div>

相关问题