单击Leaflet Popup中的链接并执行Javascript

时间:2012-12-04 08:45:38

标签: javascript jquery leaflet

我有一张传单和地图。它在地图上叠加了一系列多边形(通过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/

7 个答案:

答案 0 :(得分:46)

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

这里理想的方法是使用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/

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

答案 1 :(得分:25)

虽然弹出内容包装器阻止了事件传播,但弹出内部标记内的事件传播正常。您可以在弹出元素显示在地图上时添加事件(并且已成为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);

答案 2 :(得分:4)

我在mapbox官方网站上找到的内容:Create a click event in a marker popup with Mapbox.js and 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!');});

答案 3 :(得分:3)

我遇到了这个问题,尝试了上面的解决方案。但它对我没有用。找到了以下非常基本的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');
});

答案 4 :(得分: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);
    }
}`

答案 5 :(得分:1)

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

答案 6 :(得分: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/