如何简化此javascript单张代码
我对传单还不熟悉,我遇到了这个我必须修改的代码,但它不是我见过的典型javascript结构。这叫什么?这是推荐的做法吗 守则:如何简化此javascript单张代码,javascript,leaflet,Javascript,Leaflet,我对传单还不熟悉,我遇到了这个我必须修改的代码,但它不是我见过的典型javascript结构。这叫什么?这是推荐的做法吗 守则: var map = function() { var self = { config: { circleMarker: function(point, feature) { return new L.circleMarker(point, { fil
var map = function() {
var self = {
config: {
circleMarker: function(point, feature) {
return new L.circleMarker(point, {
fillColor: "#DA3248",
fillOpacity: 0.8,
color: "white",
radius: 9,
className: "event-marker campaign-" + feature.properties.campaign_name +
" event-accessible-" + (feature.properties.is_accessible ? "y" : "n")
});
},
Marker: function(point, feature) {
return new L.circleMarker(point, {
fillColor: "#2B9CD9",
fillOpacity: 1.0,
color: "white",
radius: 9,
strokeWidth: 1,
className: "event-marker campaign-" + feature.properties.campaign_name + " event-accessible-" + (feature.properties.is_accessible ? "y" : "n")
});
},
tileLayer: new L.tileLayer('https://{s}.tiles.mapbox.com/v4/mapbox.streets/{z}/{x}/{y}.png?access_token=' + MAPBOX_TOKEN, {
attribution: '<a href="http://www.openstreetmap.org/copyright" target="_blank">© OpenStreetMap contributors</a>'
})
},
data: {},
init: function() {
self.init_map();
},
init_map: function() {
self.map = new L.Map("map", {
center: [37.8, -96.9],
zoom: self.get_init_zoom(),
tap: false
}).addLayer(self.config.tileLayer);
self.load_event_data();
self.load_zip_codes();
self.bind_events();
self.handle_filter_params();
},
handle_filter_params: function() {
var event_types = new URLSearchParams(window.location.search).get("event_types");
if (event_types == null) {
return;
}
event_types = event_types.split(',');
var filters = document.querySelectorAll('#filter-type-list input[name="type[]"]');
for (var i = 0; i < filters.length; i++) {
var filter = filters[i];
if (event_types.indexOf(filter.getAttribute('id')) == -1) {
filter.click();
}
}
},
bind_events: function() {
document.getElementById('zipcode').addEventListener('keyup', self.handle_zipcode_keydown);
document.getElementById('filter-type-list').addEventListener('click', self.handle_filter_type_click);
document.getElementById('distance').addEventListener('change', self.handle_radius_change);
self.map.on('moveend', self.filter_events_by_viewport);
self.map._container.addEventListener('mouseover', self.handle_map_hover);
self.map._container.addEventListener('mouseout', self.handle_map_mouseout);
},
is_mobile: function() {
return window.navigator.userAgent.toLowerCase().indexOf('mobile') !== -1;
},
get_init_zoom: function() {
if (!self.is_mobile()) {
return 4;
} else {
return 3;
}
},
filter_events_by_viewport: function() {
if (self.map.getZoom() < 8) {
self.clear_events_list();
} else {
var center = self.map.getCenter();
var bounds = self.map.getBounds();
var events = [];
window.bounds = bounds;
for (var i = 0; i < self.data.events.features.length; i++) {
var event = self.data.events.features[i];
var coords = event.geometry.coordinates;
var p = L.latLng(coords[1], coords[0]);
if (bounds.contains(p)) {
events.push(event);
}
}
events = self.sort_by_distance(events, center);
self.data.filtered_events = events;
self.populate_events_list();
}
},
sort_by_distance: function(events, center) {
for (var i = 0; i < events.length; i++) {
var event = events[i];
event.distance = center.distanceTo(L.latLng(event.geometry.coordinates[1], event.geometry.coordinates[0]));
}
events.sort(function(a, b) {
return a.distance - b.distance
});
return events;
},
handle_filter_type_click: function() {
if (event.target.tagName != 'INPUT') {
return;
}
var events_list = document.getElementById('events-list');
var event_accessible_id = 'event_accessible';
var event_accessible_toggle_class = 'event-show-accessible';
if (event.target.id == event_accessible_id) {
self.map._container.classList.toggle(event_accessible_toggle_class);
events_list.classList.toggle(event_accessible_toggle_class);
} else if (event.target.checked) {
self.map._container.classList.remove('hide-campaign-' + event.target.value);
events_list.classList.remove('hide-campaign-' + event.target.value);
} else {
self.map._container.classList.add('hide-campaign-' + event.target.value);
events_list.classList.add('hide-campaign-' + event.target.value);
}
},
handle_radius_change: function(event) {
if (event.target.tagName != 'SELECT') {
return;
}
var value = event.target.options[event.target.selectedIndex].value;
if (value == "5") {
self.map.setZoom(12);
} else if (value == "20") {
self.map.setZoom(10);
} else if (value == "50") {
self.map.setZoom(9);
} else if (value == "100") {
self.map.setZoom(6);
}
},
handle_zipcode_keydown: function(event) {
if (event.target.value.length != 5) {
return;
}
var latlng = self.data.zipcodes[event.target.value];
if(latlng != undefined){
self.map.setView(new L.LatLng(latlng[0], latlng[1]), 9, {
pan: true
});
}
},
load_event_data: function() {
self.xhr('GET', events_url, function(xhr) {
var newJson = JSON.parse(xhr.responseText);
var oldJson = {};
oldJson["type"]="FeatureCollection";
oldJson["features"] = [];
for (var i = 0; i < newJson.data.length; i++) {
if(newJson.data[i]['location'] != undefined) {
var address1="";
var address2="";
if(newJson.data[i]['location']['address_lines'] != undefined){
address1= newJson.data[i]['location']['address_lines'][0];
address2= newJson.data[i]['location']['address_lines'][1];
}
var city="";
if(newJson.data[i]['location']['locality'] != undefined){
city = newJson.data[i]['location']['locality'];
}
var postal_code="";
if(newJson.data[i]['location']['postal_code'] != undefined){
postal_code = newJson.data[i]['location']['postal_code'];
}
var region="";
if(newJson.data[i]['location']['region'] != undefined){
region = newJson.data[i]['location']['region'];
}
var start_time="";
var end_time="";
if(newJson.data[i]['timeslots'][0] != undefined){
var lengthOfTimeslots=newJson.data[i]['timeslots'];
start_time = newJson.data[i]['timeslots'][0]['start_date'];
if(newJson.data[i]['timeslots'][lengthOfTimeslots-1] != undefined && newJson.data[i]['timeslots'][lengthOfTimeslots-1]['end_date'] != undefined ){
end_time = newJson.data[i]['timeslots'][lengthOfTimeslots-1]['end_date'];
}else{
end_time = newJson.data[i]['timeslots'][0]['end_date'];
}
}
var features = {
"type": "Feature",
"properties": {
"id": newJson.data[i]['id'],
"campaign_name": newJson.data[i]['event_type'],
"title": newJson.data[i]['title'],
"starts_at": (new Date(start_time*1000)).toLocaleString("en-US", {timeZone: newJson.data[i]['timezone']}),
"ends_at": (new Date(end_time*1000)).toLocaleString("en-US", {timeZone: newJson.data[i]['timezone']}),
"is_accessible": true,
"status":"active",
"address1": address1,
"address2": address2,
"city": city,
"state": region,
"is_private":false,
"venue":"Private",
"starts_at_utc":(new Date(start_time*1000)).toUTCString(),
"ends_at_utc":(new Date(end_time*1000)).toUTCString(),
"zip": postal_code
},
"geometry": {
"type": "Point",
"coordinates": [
newJson.data[i]['location']['location']['longitude'],
newJson.data[i]['location']['location']['latitude']
]
},
};
oldJson["features"].push(features);
}
}
self.data.events = oldJson;
L.geoJson(self.data.events, {
pointToLayer: function(feature, latlng) {
if (['town-hall', 'rally-campaign'].indexOf(feature.properties.campaign_name) !== -1) {
return self.config.Marker(latlng, feature);
} else {
return self.config.circleMarker(latlng, feature);
}
},
onEachFeature: function(feature, layer) {
var tpl = document.getElementById('popup-template').innerHTML;
var event = feature.properties;
layer.bindPopup(eval("`" + tpl + "`"), {
className: 'event',
maxWidth: 260
});
layer.addTo(self.map);
}
}).addTo(self.map);
});
},
load_zip_codes: function() {
self.xhr('GET', zipcodes_url, function(xhr) {
self.data.zipcodes = JSON.parse(xhr.responseText);
});
},
clear_events_list: function() {
var events_list = document.getElementById('events-list');
while (events_list.firstChild) {
events_list.removeChild(events_list.firstChild);
}
},
populate_events_list: function() {
self.clear_events_list();
var tpl = document.getElementById('event-template').innerHTML;
var events_list_frag = document.createDocumentFragment();
for (var i = 0; i < self.data.filtered_events.length; i++) {
var event = self.data.filtered_events[i].properties;
var item = document.createElement('li');
item.setAttribute('class', 'event campaign-' + event.campaign_name + " event-accessible-" + (event.is_accessible ? "y" : "n"));
item.innerHTML = eval("`" + tpl + "`");
item.setAttribute('data-id', event.id);
item.setAttribute('data-date', moment(event.starts_at_utc).format("X"));
var coords = self.data.filtered_events[i]['geometry']['coordinates'];
item.setAttribute('data-point', JSON.stringify(coords));
events_list_frag.appendChild(item);
}
var events_list = document.getElementById('events-list');
events_list.appendChild(events_list_frag);
},
xhr: function(method, url, callback, data) {
if (typeof data == "undefined") {
data = null;
}
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.send(data);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
callback(xhr);
}
}
},
signup_url: function(event) {
var base = "https://www.mobilize.us/";
return base + event.id;
}
};
return self.init();
}();
我曾尝试在大量意大利面代码的最底层向上面添加代码,但出现了错误:
spoolet.js:2295未捕获类型错误:无法读取未定义的属性“addLayer”
第二次尝试:
我也试过:
init: function() {
self.init_map();
self.lc = L.control.locate({
strings: {
title: "Locate me"
}
}).addTo(self.yangmap);
},
但仍然是相同的错误,它在传单.js
代码中强调了这一点:
addTo: function(t) {
return t.addLayer(this), this
},
TL;DR:您的第二次尝试应该是:
init:function(){
self.init_map();
self.lc=L.control.locate({
字符串:{
标题:“找到我”
}
}).addTo(self.map);//为什么使用yangmap?
},
如果用“self.yangmap”替换“self.map”的所有引用,“self.yangmap”将起作用
这叫什么?这是推荐的做法吗
- 整个包装器是一个立即调用的函数表达式(IIFE)。在JavaScript中使用它是为了避免污染作用域,同时在IIFE主体中有一个“私有”作用域
- 正如JaromandaX所指出的,由于“self.init”实际上不返回任何内容,IIFE返回语句具有误导性。不幸的是,顶部的“var map=”毫无意义
- “var self=”赋值是一种JavaScript变通方法,用于在将函数引用作为回调传递(通常作为事件侦听器)时避免“this”上下文的歧义。它在这里也被用作具有整个逻辑的对象(下一点)
- 总体代码组织是在JavaScript中坚持OOP的尝试,显然有一些与其他代码一致的约定(配置、数据、init的使用)。在AngularJS等流行框架提供不同的代码结构之前,尤其是在构建引擎(如webpack和Rollup)启用代码模块化,同时自动将模块包装到自己的私有范围之前,确实存在这种趋势
- 如果您不想开始一个完整的框架或构建步骤,您可能仍然喜欢这种代码样式
- “var self=this”技巧仍然被广泛使用,即使在使用框架和构建引擎时,开发人员不确定“this”是什么
- TL;DR:您的第二次尝试应该是:
init:function(){
self.init_map();
self.lc=L.control.locate({
字符串:{
标题:“找到我”
}
}).addTo(self.map);//为什么使用yangmap?
},
如果用“self.yangmap”替换“self.map”的所有引用,“self.yangmap”将起作用
这叫什么?这是推荐的做法吗
- 整个包装器是一个立即调用的函数表达式(IIFE)。在JavaScript中使用它是为了避免污染作用域,同时在IIFE主体中有一个“私有”作用域
- 正如JaromandaX所指出的,由于“self.init”实际上不返回任何内容,IIFE返回语句具有误导性。不幸的是,顶部的“var map=”毫无意义
- “var self=”赋值是一种JavaScript变通方法,用于在将函数引用作为回调传递(通常作为事件侦听器)时避免“this”上下文的歧义。它在这里也被用作具有整个逻辑的对象(下一点)
- 总体代码组织是在JavaScript中坚持OOP的尝试,显然有一些与其他代码一致的约定(配置、数据、init的使用)。在AngularJS等流行框架提供不同的代码结构之前,尤其是在构建引擎(如webpack和Rollup)启用代码模块化,同时自动将模块包装到自己的私有范围之前,确实存在这种趋势
- 如果您不想开始一个完整的框架或构建步骤,您可能仍然喜欢这种代码样式
- “var self=this”技巧仍然被广泛使用,即使在使用框架和构建引擎时,开发人员不确定“this”是什么
self.init()的结果。
。。。i、 e.undefined
-也许您的代码需要在init:
函数的末尾进入内部,并使用self.map
而不是map
和self.lc=
而不是lc=
-尽管如此,原始代码看起来几乎没有用处我不知道为什么有人会强迫自己去处理这样一堆乱七八糟的东西..代码在我看来很好,不知道为什么返回self.init()
,而不仅仅是返回self.init()
,最后-前者让它看起来像是返回了有用的东西。我已经编写了与上面类似的代码,它有它的位置。我已经将代码放在init:
函数中,并编辑了文章底部的详细信息,但仍然是相同的错误。你为什么要“添加代码”?你知道它做什么吗?它只是一个函数,它返回self.init()的结果。。。i、 e.undefined
-也许您的代码需要在init:
函数的末尾进入内部,并使用self.map
而不是map
和self.lc=
而不是lc=
-尽管如此,原始代码看起来几乎没有用处我不知道为什么有人会强迫自己去处理这样一堆乱七八糟的东西..代码在我看来很好,不知道为什么返回self.init()
,而不仅仅是返回self.init()
,最后-前者让它看起来像是返回了有用的东西。我已经编写了与上面类似的代码,它有它的位置。我已经将代码放在init:
函数中,并编辑了文章底部的详细信息,但仍然是相同的错误。你为什么要“添加代码”?你知道它是做什么的吗?用什么方法来分解它,使它具有经典的功能?这看起来需要大量的工作来分解它。“这看起来需要大量的工作来分解它”:
addTo: function(t) {
return t.addLayer(this), this
},