41

我有一张传单地图正在运行。它在地图上覆盖了一系列多边形(通过 GeoJSON)并将弹出窗口附加到每个多边形。每个弹出窗口都显示有关该多边形的信息。

我想在弹出窗口中有一个链接,单击该链接时,将运行一个 javascript 函数,该函数通过 AJAX 拉出更小的多边形并显示它们。

我无法让脚本通过普通的 jQuery/Javascript 点击事件来捕捉对链接的点击。这就是我所说的正常(以下不起作用):

$('a .smallPolygonLink').click(function(e){
  console.log("One of the many Small Polygon Links was clicked");
});

bindPopup 部分如下。它在制作时在每个多边形上运行,并在单击多边形时正确弹出。它确实显示了链接,只是不会在点击时运行上述代码。

var popupContent = "Basic Information..." + '<a class="smallPolygonLink" href="#">Click here to see the smaller polygons</a>';
layer.bindPopup(popupContent);

这是一个说明示例的 JSFiddle,虽然形式要简单得多。http://jsfiddle.net/2XfVc/4/

4

7 回答 7

60

每次打开弹出窗口时,弹出窗口内的链接元素都会从您的标记中动态生成。这意味着当您尝试将处理程序绑定到它时,该链接不存在。

这里的理想方法是使用on将事件处理委托给弹出元素或其祖先。不幸的是,弹出窗口阻止了事件传播,这就是为什么将事件处理委派给弹出窗口之外的任何静态元素都行不通的原因。

您可以做的是预先构建链接,附加处理程序,然后将其传递给bindPopup方法。

var link = $('<a href="#" class="speciallink">TestLink</a>').click(function() {
    alert("test");
})[0];
marker.bindPopup(link);

这是一个演示:http: //jsfiddle.net/2XfVc/7/

通常,要使用多个事件处理程序插入任何类型的复杂标记,请使用以下方法:

// Create an element to hold all your text and markup
var container = $('<div />');

// Delegate all event handling for the container itself and its contents to the container
container.on('click', '.smallPolygonLink', function() {
    ...
});

// Insert whatever you want into the container, using whichever approach you prefer
container.html("This is a link: <a href='#' class='smallPolygonLink'>Click me</a>.");
container.append($('<span class="bold">').text(" :)"))

// Insert the container into the popup
marker.bindPopup(container[0]);

这是一个演示:http: //jsfiddle.net/8Lnt4/

有关传单弹出窗口中事件传播的更多信息,请参阅此 Git 问题

于 2012-12-04T08:51:19.260 回答
29

虽然 Popup 内容包装器阻止了事件传播,但 popup 内部标记中的事件传播得很好。当弹出元素显示在地图上时(并且已成为 DOM 的一部分),您可以将事件添加到弹出元素。只需注意传单活动popupopen

var map = L.map('map').setView([51.505, 10], 7); //for example

//the .on() here is part of leaflet
map.on('popupopen', function() {  
  $('a .smallPolygonLink').click(function(e){
    console.log("One of the many Small Polygon Links was clicked");
  });
});

http://jsfiddle.net/tJGQ7/2/

这对我来说就像一个魅力。如果您的弹出窗口没有'a .smallPolygonLink'上述代码,则什么也不做。此代码在弹出窗口的每次启动时运行。但是,您不必担心它将多个处理程序附加到一个元素,因为当弹出窗口关闭时,DOM 节点会被丢弃。

有一种更通用的方法可以做到这一点。但是,它涉及eval(). 使用风险自负。但是,当 AJAX 加载包含 JS 的部分页面时,您会遇到相同的风险,因此为了您的启发,我提出“在您的传单弹出窗口中执行 JS”:

map.on('popupopen', function(){
    var cont = document.getElementsByClassName('leaflet-popup-content')[0];    
    var lst = cont.getElementsByTagName('script');
    for (var i=0; i<lst.length;i++) {
       eval(lst[i].innerText)
    }
});

演示:http: //jsfiddle.net/tJGQ7/4/

现在你可以写:

var popup_content = 'Testing the Link: <a href="#" class="speciallink">TestLink</a><script> $(".speciallink").on("click", function(){alert("hello from inside the popup")});</script>';

marker.bindPopup(popup_content);
于 2013-02-28T11:57:50.197 回答
5

这就是我在 mapbox 官方网站上找到的内容:使用 Mapbox.js 和 jQuery 在标记弹出窗口中创建点击事件。该评论解释了为什么我们说$('#map')而不是$('#mybutton').

var marker = L.marker([43.6475, -79.3838], {
  icon: L.mapbox.marker.icon({
    'marker-color': '#9c89cc'
  })
})
.bindPopup('<button class="trigger">Say hi</button>')
.addTo(map);
//The HTML we put in bindPopup doesn't exist yet, so we can't just say
//$('#mybutton'). Instead, we listen for click events on the map element which will bubble up from the tooltip, once it's created and someone clicks on it.

$('#map').on('click', '.trigger', function() {
alert('Hello from Toronto!');});
于 2016-08-10T08:44:27.593 回答
4

我遇到了这个问题,尝试了上面的解决方案。但这对我没有用。找到了以下非常基本的 jquery 解决方案。

// add your marker to the map
var my_marker = new L.marker([51.2323, 4.1231], {icon: my_icon});
var popup = L.popup().setContent('<a class="click" href="#">click</a>');
my_marker.addTo(map).bindPopup(popup);

// later on
jQuery("body").on('click','a.click', function(e){
  e.preventDefault();
  alert('clicked');
});
于 2013-10-02T09:18:07.847 回答
3

您可以检查popup对象的内部属性,包括_wrapper等。

map.on('popupopen', _bindPopupClick);
map.on('popupclose', _unbindPopupClick);

var _bindPopupClick = function (e) {
    if (e.popup) {
        e.popup._wrapper.addEventListener('click', _bindPopupClickHandler);
    }
};
var _unbindPopupClick = function (e) {
    if (e.popup) {
        e.popup._wrapper.removeEventListener('click', _bindPopupClickHandler);
    }
}`
于 2016-06-14T22:34:02.643 回答
1

您可以使用 jQuery 来选择canvas元素,但您必须在画布中使用它自己的方法。一个不错的开始将是https://developer.mozilla.org/en/canvas_tutorial

于 2012-12-04T08:53:04.343 回答
0

mapbox JavaScript 库有一个事件:

bindPopup('<button class="trigger">Say hi</button>');
addTo(map);

$('#map').on('click', '.trigger', function() {
    alert('Hello from Toronto!');
});

https://www.mapbox.com/mapbox.js/example/v1.0.0/clicks-in-popups/

于 2016-12-25T23:42:22.367 回答