重新打开弹出窗口后,标记弹出窗口jQuery事件不再触发。

3
我有一个与标记相关联的Leaflet弹出窗口,向用户提供了两个按钮,可以使用jQuery取消或转到另一页。按钮最初运行良好,但是如果您单击标记上的位置使弹出窗口消失,然后再次单击标记以使弹出窗口重新显示,则按钮突然无法工作。我没有在浏览器控制台中收到任何错误消息。可能是什么问题呢?
var marker;

var addPopup = function(e, marker) {
    var popup = L.popup({closeButton:false})
    .setContent('<button type="submit" class="btn btn-primary" id="ok">Ok</button><button type="submit" class="btn btn-primary" id="nok">Cancel</button>');
    marker.bindPopup(popup).openPopup();
    var Coordinates= JSON.stringify(e.latlng);
    popupAction(Coordinates, marker);
};

var popupAction= function(Coordinates, marker){
    $('#ok').on('click', function (){
      console.log('do something');  
    });
    $('#nok').on('click', function (){
        mymap.removeLayer(marker);
    });
};

mymap.on('click', function (e) {
    if (marker) {
        mymap.removeLayer(marker);
    }
    marker = new L.Marker(e.latlng).addTo(mymap);
    addPopup(e, marker);            
});
1个回答

4
很可能您的事件侦听器在下一个弹出窗口打开时会丢失。Leaflet 可能会重新创建弹出窗口内容,因此您的事件侦听器不再附加到这个新内容上。
因此,一个解决方法是在标记的 "popupopen" 事件中重新执行您的 popupAction 函数(该函数在弹出窗口按钮上附加事件侦听器)。

当绑定到此图层的弹出窗口被打开时触发

不幸的是,这样做会创建另一个错误,因为当用户在地图上的其他位置单击时,您已经打开了一个带有其弹出窗口的标记,您将删除标记并创建一个新标记,具有新的弹出窗口内容但具有相同的按钮 ID。因此,当 jQuery 尝试附加您的侦听器时,它找到的是先前的按钮而不是新的按钮。一个新的解决方法是使用选择器中的其他内容而不是 id,以便 jQuery 也可以找到新的按钮,例如类。
一个正确的解决方案是使用 事件委托,这在 jQuery 中很容易实现:

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

var marker;

var addPopup = function(e, marker) {
  var popup = L.popup({
      closeButton: false
    })
    .setContent('<button type="submit" class="btn btn-primary" id="ok">Ok</button><button type="submit" class="btn btn-primary" id="nok">Cancel</button>');
  marker.bindPopup(popup).openPopup();
};

// Use event delegation, so that buttons may be removed from DOM but event listeners will persist on parent container.
// http://api.jquery.com/on/
// https://learn.jquery.com/events/event-delegation/
$('#map').on('click', '#ok', function() {
  console.log('do something');
}).on('click', '#nok', function() {
  mymap.removeLayer(marker);
});

mymap.on('click', function(e) {
  if (marker) {
    mymap.removeLayer(marker);
  }
  marker = new L.Marker(e.latlng).addTo(mymap);
  addPopup(e, marker);
});

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

mymap.setView([48.85, 2.35], 12);
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.3.1/dist/leaflet.css" integrity="sha512-Rksm5RenBEKSKFjgI3a41vrjkw4EVPlJ3+OiI65vTjIdo9brlAacEuKOiQ5OFh7cOI1bkDwLqdLw3Zg0cRJAAQ==" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.3.1/dist/leaflet-src.js" integrity="sha512-IkGU/uDhB9u9F8k+2OsA6XXoowIhOuQL1NTgNZHY1nkURnqEGlDZq3GsfmdJdKFe1k1zOc6YU2K7qY+hF9AodA==" crossorigin=""></script>
<script src="pr5848.js"></script>

<script src="https://code.jquery.com/jquery-1.12.4.js"></script>

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


太棒了,非常感谢这个详细的解释,问题已解决! - Sebs030

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接