Fare clic sul collegamento all’interno del Volantino a Comparsa e fare Javascript

Ho un foglio mappa fino e in esecuzione. Si sovrappongono una serie di poligoni (via GeoJSON) sulla mappa e si attacca popup per ogni poligono. Ciascuno dei popup di visualizzazione di informazioni su quel poligono.

Mi piacerebbe avere all’interno del popup un link che, se cliccato, viene eseguita una funzione javascript che tira ulteriore piccolo poligoni tramite AJAX e li mostra.

Non posso ottenere lo script per la cattura di fare clic sul link via normale di jQuery/Javascript eventi click. Ecco cosa intendo per normale (il seguito non funziona):

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

Il bindPopup parte è come indicato di seguito. Funziona su ogni poligono, quando sono fatte e si apre correttamente facendo clic su un poligono. Mostra i link, basta non correre il codice di cui sopra, con un clic.

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

Ecco un JSFiddle illustrare l’esempio, anche se nella forma più semplice. http://jsfiddle.net/2XfVc/4/

InformationsquelleAutor Josh | 2012-12-04

 

7 Replies
  1. 47

    L’elemento link all’interno del popup viene generato dinamicamente dal tuo markup ogni volta che il popup si apre. Ciò significa che il link non esiste quando si sta cercando di associare il gestore di.

    L’approccio ideale sarebbe di utilizzare on di delegare la gestione degli eventi per la comparsa di elemento o di un antenato di esso. Purtroppo, la comparsa impedisce la propagazione dell’evento, che è il motivo per cui delegare la gestione degli eventi di eventuali elementi statici fuori il popup non funziona.

    Cosa si può fare è preconstruct il collegamento, collegare il conduttore, e quindi passare l’ bindPopup metodo.

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

    Qui è una dimostrazione: http://jsfiddle.net/2XfVc/7/

    In generale, per inserire qualsiasi tipo di complesso di markup con i gestori di eventi multipli, utilizzare il seguente approccio:

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

    Qui è una demo: http://jsfiddle.net/8Lnt4/

    Vedere questo Git problema per di più nel caso di propagazione in foglio popup.

    • Come faccio a modificare questa opzione per aggiungere testo o il contenuto che NON è cliccabile? E. g. Nome: xxxx, Età: xxxx, fare Clic su Link per ulteriori dettagli. Con solo la parola “Link” essere cliccabile. Inoltre, cosa significa la [0] parte fare? Io non riesco a trovare alcun riferimento a jquery fare clic su api.
    • Basta aggiungere altri elementi lungo con la cliccabile uno. Qui è una dimostrazione: jsfiddle.net/2XfVc/8 Il [0] parte ottiene semplicemente il nodo DOM dal jQuery collezione, dal volantino accetta standard DOM nodi ma non jQuery collezioni.
    • Impressionante. Ho cambiato .html() invece di .text() in modo che la formattazione html show, ma per il resto era perfetto. Grazie.
  2. 25

    Mentre il contenuto del Popup wrapper impedisce la propagazione dell’evento, eventi all’interno della popup interno di Markup propagare bene. È possibile aggiungere eventi popup elementi quando vengono visualizzati sulla mappa (e sono diventati parte del DOM). Basta guardare per il depliant dell’evento 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/

    Questo funziona come un fascino per me. Se la popup non hanno un 'a .smallPolygonLink' il codice di cui sopra non fa nulla.
    Questo codice viene eseguito ad ogni avvio di una finestra popup. Comunque non devi preoccuparti che non si attacca più di un gestore di un elemento, dal momento che quando il popup si chiude, il DOM nodi si buttano via.

    C’è un più generale modo di fare questo. Tuttavia, essa comporta eval(). Di utilizzare a proprio rischio. Ma quando AJAXloading parziale delle pagine che contengono JS si esegue gli stessi rischi, quindi, per la vostra edificazione vi presento “l’esecuzione di JS all’interno del vostro foglio popup”:

    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/

    Ora si può scrivere:

    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);
    • Sicuramente la migliore risposta qui – senza bisogno di un work-around 🙂
    • sì, dovrebbe essere la migliore risposta qui. bella soluzione!
    • Il problema con questo è che si sta ri-fissare il gestore di eventi ogni volta che il popup è aperto, che è inefficiente ora, inapplicabile non appena si guarda l’inserimento di strutture più complesse con più gestori. L’approccio ideale sarebbe di delegare la gestione degli eventi per la comparsa di elemento o di un antenato di esso, che è quello che inizialmente avevo suggerito nella mia risposta. Ho scoperto però che il volantino sconvolge la propagazione dell’evento, il che significava on non avrebbe funzionato. Il secondo approccio migliore è quello di associare qualsiasi e tutte le funzionalità di gestione esattamente dopo di un elemento contenitore e inserire.
    • Ho a che fare con molto complesso ajax-caricato popup contenuti, nella mia esperienza non c’è nessun calcolo ciclo o collo di bottiglia della memoria che possa giustificare il fatto di parlare di inefficienza qui. In contrasto, con il mio metodo ho separato il contenuto e le funzionalità che appartiene insieme in una sola unità. La tua soluzione jquery trucco rende l’oggetto contenitore, un grosso sacco di funzionalità per salvare alcuni millisecondi di tempo di esecuzione. Cito: “L’ottimizzazione è la radice di ogni male”.
    • Questa risposta funziona… ma sarà il collegamento di vari gestori, per il popup.. vedi risposta da @AsadSaeeduddin per una più accurata soluzione.
    • stai dicendo “da quando il popup si chiude, il DOM nodi si buttano via.” non è più vero? Quando ho lavorato su questo anni fa, ho controllato per più di attaccamento e questo non accade per il motivo citato.

  3. 4

    Che è quello che trovo sul mapbox sito ufficiale: Creare un evento click in un marcatore a comparsa con Mapbox.js e jQuery. Il commento che spiega il motivo per cui diciamo $('#map') invece di $('#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. 3

    Mi sono imbattuto in questo problema, provato la soluzione di cui sopra. Ma non ha funzionato per me. Trovati i seguenti abbastanza di base di jquery soluzione.

    //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. 3

    Si può controllare interiore proprietà di popup oggetto, tra _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);
        }
    }`
    • Questo vaniglia soluzione funziona come un fascino quando si utilizza Vue2 e non si desidera utilizzare jquery. Grazie!

Lascia un commento