我已经建立了一个显示geojson的Leaflet.js地图,其中显示了一组附近的街道,并在下面提供了一个演示的链接。在任何街道段上单击都会打开一个弹出式窗体,该窗体具有包含多个输入元素和提交按钮的表单,并被编码为第一个输入元素具有焦点。如果在没有打开任何弹出窗口的情况下单击街道段,则一切正常-第一个元素会聚焦并且提交按钮是可操作的。
但是,如果在弹出窗口已经打开的情况下单击街道部分,代码似乎会中断-焦点功能和提交按钮不起作用。
我已经努力了一段时间才弄清楚为什么会发生这种情况,并且还无法缩小范围。我认为这可能与DOM中某处或某个时间的冲突有关,但我还无法解决-希望有人在此会注意到问题。
演示:https://spotcheck.s3.amazonaws.com/leaflet_popup_bug.html
相关代码部分:
var map = L.map('map', {zoomControl: false, almostOnMouseMove: false, zoomSnap: 0.25});
map.setView([41.485, -81.705], 17);
var myStyle = {
"weight": 1
};
var myStyle_clicked = {
"weight": 4
};
function layerClickHandler (e) {
var marker = e.target,
properties = e.target.feature.properties;
function findMinMax(arr) {
let maxLat = arr[0][1];
let maxLng = arr[0][0];
for (let i = 1, len=arr.length; i < len; i++) {
let v = arr[i][1];
if (v > maxLat) { maxLat = v; maxLng = arr[i][0];}
}
return [maxLng,maxLat];
}
var coordArray = marker.feature.geometry.coordinates[0];
maxLatPt = findMinMax(coordArray);
var latlng1 = new L.LatLng(maxLatPt[1], maxLatPt[0]);
var popup1 = new L.Popup({keepInView:true, offset: new L.Point(0, -3)}).setLatLng(latlng1);
popupContent = "<strong>segment_id: "+properties.segment_id+'<br>'+properties.description+'</strong><br><form id="test-form"><input name="parked" placeholder="Parked spaces" type="number" id="parked"><br><input name="open" placeholder="Open spaces" type="number" id="open"><br><input name="bad" placeholder="Bad park" type="number" id="bad"><br><input name="illegal" placeholder="Illegal park" type="number" id="illegal"><input type="hidden" id="street_name" name="street_name" value="'+properties.description+'"><input type="hidden" id="street_id" name="street_id" value="'+properties.segment_id+'"><input type="hidden" id="timestamp" name="timestamp"><input type="hidden" id="timestamp_time" name="timestamp_time"><input type="hidden" id="timestamp_day" name="timestamp_day"><input type="hidden" id="timestamp_month" name="timestamp_month"><input type="hidden" id="timestamp_date" name="timestamp_date"><button type="button" id="submit-form">Submit</button></form>'
popup1.setContent(popupContent);
function openPopupFeature(callback) {
popup1.openOn(map);
callback();
}
function focusFirstInput() {
document.getElementById( 'parked' ).focus();
}
openPopupFeature(focusFirstInput);
// does this function need to be in the L.DomUtil class?
var buttonSubmit = document.getElementById('submit-form');
L.DomEvent.addListener(buttonSubmit, 'click', function (e) {
e.preventDefault();
buttonSubmit.innerHTML="Wait";
alert('OK success!');
popup1.remove();
});
}
var streets = L.layerGroup();
var streetsJSON = L.geoJson(ohiocity_streets_network, {
interactive: false,
onEachFeature: function (feature, layer) {
layer.on('click', layerClickHandler);
}
});
streets.addLayer(streetsJSON);
map.addLayer(streets);
streetsJSON.setStyle({color:"#3388ff", weight:1});
map.almostOver.addLayer(streets);
map.on('almost:click', function(e) {
streets.eachLayer(function(layer) {
layer.setStyle({color:"#3388ff", weight:1});
});
var layer = e.layer;
layer.setStyle({color:"red", weight:5});
if (layer.openPopup) {
layer.fire('click', e);
}
});
[当我试图集中输入元素时,似乎DOM尚未准备就绪,这正在导致代码中断(但不会在控制台中引发错误)。
我以setTimeout间隔将Listener移到.focus函数中。我在回调中苦苦挣扎,所以如果有人可以提出一种更简洁的编写此逻辑的方法,我将不胜感激!
popup1.setContent(popupContent);
function openPopupFeature(callback) {
popup1.openOn(map);
callback();
}
function focusFirstInput() {
//document.getElementById( 'parked' ).focus();
setTimeout(function(){
document.getElementById("parked").focus();
var buttonSubmit = document.getElementById('submit-form');
L.DomEvent.addListener(buttonSubmit, 'click', function (e) {
e.preventDefault();
buttonSubmit.innerHTML="Wait";
alert('OK success!');
popup1.remove();
});
}, 500);
}
openPopupFeature(focusFirstInput);