web-dev-qa-db-fra.com

Cliquez sur le lien à l'intérieur du dépliant et faites Javascript

J'ai une carte de dépliant en place. Il superpose une série de polygones (via GeoJSON) sur la carte et attache des popups à chaque polygone. Chacune des fenêtres contextuelles affiche des informations sur ce polygone.

Je voudrais avoir à l'intérieur de la fenêtre contextuelle un lien qui, lorsque vous cliquez dessus, exécute une fonction javascript qui tire d'autres polygones plus petits via AJAX et les affiche.

Je ne peux pas obtenir le script pour attraper un clic sur le lien via les événements de clic jQuery/Javascript normaux. Voici ce que je veux dire par normal (ce qui suit ne fonctionne pas):

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

La partie bindPopup est la suivante. Il s'exécute sur chaque polygone une fois créé et s'affiche correctement en cliquant sur un polygone. Il montre le lien, mais n'exécutera pas le code ci-dessus en un clic.

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

Voici un JSFiddle illustrant l'exemple, bien que sous une forme beaucoup plus simple. http://jsfiddle.net/2XfVc/4/

33
Josh

L'élément de lien à l'intérieur de la fenêtre contextuelle est généré dynamiquement à partir de votre balisage chaque fois que la fenêtre contextuelle est ouverte. Cela signifie que le lien n'existe pas lorsque vous essayez de lui associer le gestionnaire.

L'approche idéale ici serait d'utiliser on pour déléguer la gestion des événements à l'élément popup ou à un ancêtre de celui-ci. Malheureusement, le popup empêche la propagation des événements, c'est pourquoi la délégation de la gestion des événements à des éléments statiques en dehors du popup ne fonctionnera pas.

Vous pouvez préconstruire le lien, attacher le gestionnaire, puis le transmettre à la méthode bindPopup.

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

Voici une démonstration: http://jsfiddle.net/2XfVc/7/

En général, pour insérer toute sorte de balisage complexe avec plusieurs gestionnaires d'événements, utilisez l'approche suivante:

// 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]);

Voici une démo: http://jsfiddle.net/8Lnt4/

Voir ce problème Git pour en savoir plus sur la propagation des événements dans les popups des dépliants.

47
Asad Saeeduddin

Alors que l'encapsuleur de contenu Popup empêche la propagation des événements, les événements au sein du balisage interne popup se propagent très bien. Vous pouvez ajouter des événements aux éléments contextuels lorsqu'ils sont affichés sur la carte (et font désormais partie du DOM). Surveillez simplement l'événement dépliant 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/

Cela fonctionne comme un charme pour moi. Si votre popup n'a pas de 'a .smallPolygonLink' Le code ci-dessus ne fait rien. Ce code s'exécute à chaque démarrage d'une popup. Cependant, vous n'avez pas à vous soucier qu'il attache plus d'un gestionnaire à un élément, car lorsque la fenêtre contextuelle se ferme, les nœuds DOM sont jetés.

Il existe une manière beaucoup plus générale de procéder. Cependant, cela implique eval(). Utilisez à vos risques et périls . Mais lorsque AJAXloading des pages partielles qui contiennent JS vous courez les mêmes risques, donc pour votre édification je présente "exécuter JS à l'intérieur de vos popups de dépliant":

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)
    }
});

démo: http://jsfiddle.net/tJGQ7/4/

Vous pouvez maintenant écrire:

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);
25
semiomant

C'est ce que je trouve sur le site officiel de mapbox: Créer un événement click dans une popup de marqueur avec Mapbox.js et jQuery. Le commentaire explique pourquoi nous disons $('#map') au lieu de $('#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!');});
4
Kiki Yang

Je suis tombé sur ce problème, j'ai essayé la solution ci-dessus. Mais ça n'a pas marché pour moi. Trouvé la solution jquery assez basique suivante.

// 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');
});
3
jivanrij

Vous pouvez vérifier les propriétés internes de l'objet popup, y compris _wrapper etc.

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);
    }
}`
3
SerzN1

Vous pouvez utiliser jQuery pour sélectionner l'élément canvas, mais vous devrez utiliser ses propres méthodes dans le canevas. Un début décent serait https://developer.mozilla.org/en/canvas_tutorial .

1
wandarkaf

la bibliothèque JavaScript de mapbox a un événement:

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/

0
Dilip Kumar