2012-12-04 23 views
30

私はリーフレットを作成して実行しています。マップ上に一連のポリゴン(GeoJSON経由)がオーバーレイされ、各ポリゴンにポップアップが付加されます。各ポップアップには、そのポリゴンに関する情報が表示されます。リーフレットのポップアップをクリックしてJavascriptを実行します

ポップアップの中に、クリックすると、AJAX経由でさらに小さなポリゴンを引き出し、それらを表示するJavaScript関数が実行されます。

通常のjQuery/Javascriptのクリックイベントを使用してリンク上のクリックを捕捉するスクリプトを取得できません。以下は正常であることを意味します(以下は動作しません)。

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

bindPopupの部分は次のとおりです。作成時に各ポリゴンで実行され、ポリゴンをクリックすると正しくポップアップします。リンクを表示しますが、クリックするだけで上記のコードは実行されません。

JSFiddleは例を示していますが、はるかに単純な形式です。 http://jsfiddle.net/2XfVc/4/

答えて

41

ポップアップ内のリンク要素は、ポップアップが開くたびにマークアップから動的に生成されます。これは、ハンドラをバインドしようとしているときにリンクが存在しないことを意味します。

ここで理想的なアプローチは、イベント処理をポップアップ要素またはその祖先に委譲するためにonを使用することです。残念ながら、ポップアップはイベントの伝播を防ぎます。そのため、ポップアップの外側にある静的な要素にイベント処理を委任することはできません。

できることは、リンクを事前に構築し、ハンドラを接続してからbindPopupメソッドに渡すことです。 folowingアプローチを使用し、一般的にhttp://jsfiddle.net/2XfVc/7/

、複数のイベントハンドラで複雑なマークアップの任意の並べ替えを挿入する:ここで

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

はデモンストレーションです。ここ

// 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を参照してください。

+0

どのように私はクリックできないテキストやコンテンツを追加するために、これを修正するのでしょうか?例えば。名前:xxxx、年齢:xxxx、詳細についてはリンクをクリックしてください。 「リンク」という言葉だけがクリック可能です。また、[0]部分は何をしていますか? jquery click apiで参照が見つかりません。 – Josh

+2

@Josh他の要素をクリック可能な要素とともに追加するだけです。 http://jsfiddle.net/2XfVc/8/リーフレットはjQueryコレクションではなく標準DOMノードを受け入れるので、 '[0]'部分は単にjQueryコレクションからDOMノードを取得します。 –

+0

私は '.text()'の代わりに '.html()'に変更し、いくつかのHTML書式が表示されるようにしましたが、それ以外は完璧でした。ありがとう。 – Josh

21

ポップアップコンテンツラッパーはイベントの伝播を防ぎますが、ポップアップ内部マークアップ内のイベントはうまく伝播します。ポップアップ要素がマップ上に表示されたとき(および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()が含まれます。 自己責任において使用してください。しかし、JSが含まれている部分のページをAJAXloadingとき、あなたはあなたの教化のために私が提示するように、「あなたのリーフレットのポップアップ内の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); 
+0

確かにここで最善の答え - 回避策のための必要はありません:-) –

+0

うん、ここで最高の答えが必要です。素敵な解決策! –

+0

この問題は、ポップアップが開くたびにイベントハンドラを再接続することになります。これは現在非効率的であり、複数のハンドラを使用してより複雑な構造を挿入するとすぐに実行できません。ここでの理想的なアプローチは、ポップアップ要素またはその祖先にイベント処理を委譲することです。これは私の答えで最初に提案したものです。しかし、リーフレットがイベントの伝播を妨害することを発見しました。これは、「オン」が機能しないことを意味していました。次善策は、すべてのイベント処理機能をコンテナ要素に挿入して挿入することです。 –

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

あなたは含めて、popupオブジェクトの内部プロパティを確認することができます_wrapperなど

私はmapbox公式ウェブサイト上で見つけるものだ
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); 
    } 
}` 
4

:我々は$('#map')代わりの$('#mybutton')言う理由コメントは説明Create a click event in a marker popup with Mapbox.js and jQuery.

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!');}); 
0

イベントを持っていたJavaScriptライブラリmapbox:

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

コードをダンプしないでください。提案されたソリューションがOPの問題を解決する理由を理解するには、良い説明が重要です。 –

関連する問題