Подтвердить что ты не робот

Нажмите ссылку внутри всплывающего окна "Листовка" и сделайте Javascript

У меня есть карта листовка вверх и вниз. Он накладывает на карту ряд полигонов (через GeoJSON) и прикрепляет всплывающие окна к каждому полигону. Каждое всплывающее окно отображает информацию об этом многоугольнике.

Я хотел бы иметь внутри всплывающего окна ссылку, которая при нажатии на нее запускает функцию javascript, которая вытягивает более мелкие полигоны через AJAX и показывает их.

Я не могу заставить script щелкнуть ссылку по нормальным событиям 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/

4b9b3361

Ответ 1

Элемент связи внутри всплывающего окна динамически генерируется из вашей разметки каждый раз, когда всплывающее окно открывается. Это означает, что ссылка не существует, когда вы пытаетесь привязать обработчик к ней.

Идеальный подход здесь - использовать 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 вопрос для получения дополнительной информации о распространении событий в всплывающих окнах листов.

Ответ 2

В то время как оболочка содержимого всплывающих окон предотвращает распространение событий, события внутри всплывающей внутренней разметки распространяются просто отлично. Вы можете добавлять события во всплывающие элементы, когда они отображаются на карте (и стали частью 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)
    }
});

demo: 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);

Ответ 3

Это то, что я нахожу на официальном сайте mapbox: Создать событие click в всплывающем окне маркера с 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 created and someone clicks on it.

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

Ответ 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');
});

Ответ 5

Вы можете использовать jQuery для выбора элемента canvas, но вам придется использовать его собственные методы в холсте. Постойное начало было бы https://developer.mozilla.org/en/canvas_tutorial.

Ответ 6

Вы можете проверить внутренние свойства объекта 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);
    }
}`