2012-12-04 28 views
30

Tôi có một bản đồ tờ rơi và chạy. Nó chồng lên một loạt các đa giác (qua GeoJSON) trên bản đồ và đính kèm các cửa sổ bật lên cho mỗi đa giác. Mỗi cửa sổ bật lên hiển thị thông tin về đa giác đó.Nhấp vào liên kết bên trong Leaflet Popup và làm Javascript

Tôi muốn có trong cửa sổ bật lên một liên kết, khi được nhấp, chạy một hàm javascript kéo các đa giác nhỏ hơn nữa thông qua AJAX và hiển thị chúng.

Tôi không thể lấy tập lệnh để nắm bắt nhấp chuột vào liên kết thông qua các sự kiện nhấp chuột jQuery/Javascript bình thường. Dưới đây là ý tôi là bình thường (sau đây không hoạt động):

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

Phần bindPopup như sau. Nó chạy trên mỗi đa giác khi thực hiện và nó bật lên một cách chính xác khi nhấp vào một đa giác. Nó hiển thị liên kết, sẽ không chạy mã trên khi nhấp chuột.

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

Dưới đây là một ví dụ minh họa, mặc dù ở dạng đơn giản hơn nhiều. http://jsfiddle.net/2XfVc/4/

Trả lời

41

Phần tử liên kết bên trong cửa sổ bật lên đang được tạo động từ đánh dấu của bạn mỗi khi cửa sổ bật lên được mở. Điều đó có nghĩa là liên kết không tồn tại khi bạn đang cố gắng ràng buộc trình xử lý với nó.

Cách tiếp cận lý tưởng ở đây sẽ là sử dụng on để ủy quyền xử lý sự kiện cho phần tử bật lên hoặc tổ tiên của nó. Thật không may, cửa sổ bật lên ngăn sự kiện tuyên truyền, đó là lý do tại sao ủy quyền xử lý sự kiện cho bất kỳ phần tử tĩnh nào bên ngoài cửa sổ bật lên sẽ không hoạt động.

Việc bạn có thể làm là tạo cấu trúc liên kết, đính kèm trình xử lý và sau đó chuyển nó đến phương thức bindPopup.

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

Dưới đây là một minh chứng: http://jsfiddle.net/2XfVc/7/

Nói chung, để chèn thêm bất kỳ loại đánh dấu phức tạp với nhiều xử lý sự kiện, sử dụng phương pháp folowing:

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

Đây là một bản demo: http://jsfiddle.net/8Lnt4/

Xem this Git issue để biết thêm về tuyên truyền sự kiện trong cửa sổ bật lên tờ rơi.

+0

Làm thế nào tôi sẽ sửa đổi này để thêm văn bản hoặc nội dung đó là không thể nhấp? Ví dụ. Tên: xxxx, Tuổi: xxxx, Nhấp vào Liên kết để biết thêm chi tiết. Chỉ với từ "Liên kết" có thể nhấp được. Ngoài ra, phần [0] làm gì? Tôi không thể tìm thấy bất kỳ tài liệu tham khảo trong api jquery nhấp chuột. – Josh

+2

@Josh Chỉ cần thêm các phần tử khác cùng với phần tử có thể nhấp. Đây là phần trình diễn: http://jsfiddle.net/2XfVc/8/ Phần '[0]' đơn giản lấy nút DOM từ bộ sưu tập jQuery, vì tờ rơi chấp nhận các nút DOM chuẩn nhưng không chấp nhận các bộ sưu tập jQuery. –

+0

Tuyệt vời. Tôi đã thay đổi nó thành '.html()' thay vì '.text()' để một số định dạng html sẽ hiển thị, nhưng nếu không thì nó hoàn hảo. Cảm ơn. – Josh

21

Trong khi trình bao bọc nội dung Popup ngăn sự kiện tuyên truyền, các sự kiện trong cửa sổ bật lên bên trong Đánh dấu truyền đạt tốt. Bạn có thể thêm sự kiện vào các yếu tố bật lên khi chúng được hiển thị trên bản đồ (và đã trở thành một phần của DOM). Chỉ cần theo dõi sự kiện tờ rơi 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/

này hoạt động như một nét duyên dáng cho tôi. Nếu cửa sổ bật lên của bạn không có mã số 'a .smallPolygonLink' thì mã trên không làm gì cả. Mã này chạy trên mọi lần khởi động của cửa sổ bật lên. Tuy nhiên bạn không phải lo lắng rằng nó gắn nhiều hơn một trình xử lý cho một phần tử, vì khi cửa sổ bật lên đóng lại, các nút DOM bị vứt đi.

Có một cách tổng quát hơn để thực hiện việc này. Tuy nhiên, nó liên quan đến eval(). Sử dụng rủi ro của riêng bạn. Nhưng khi AJAXloading trang một phần có chứa JS bạn chạy các nguy cơ tương tự, vì vậy đối với sự soi sáng của bạn tôi trình bày "thi JS bên trong popup tờ rơi của bạn":

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/

Bây giờ bạn có thể viết:

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

Chắc chắn câu trả lời hay nhất ở đây - không cần phải làm việc xung quanh :-) –

+0

yep, nên là câu trả lời hay nhất ở đây. giải pháp tốt đẹp! –

+0

Vấn đề với việc này là bạn đang gắn lại trình xử lý sự kiện mỗi khi cửa sổ bật lên được mở, hiện không hiệu quả và không thể thực hiện được ngay khi bạn nhìn vào các cấu trúc phức tạp hơn với nhiều trình xử lý. Cách tiếp cận lý tưởng ở đây là phân quyền xử lý sự kiện cho phần tử bật lên hoặc tổ tiên của chúng, đó là những gì tôi đã đề xuất ban đầu trong câu trả lời của tôi. Tuy nhiên, tôi phát hiện ra rằng tờ rơi phá vỡ sự kiện tuyên truyền, có nghĩa là 'on' sẽ không hoạt động. Cách tiếp cận tốt nhất thứ hai là liên kết bất kỳ và tất cả chức năng xử lý sự kiện một cách chính xác * một lần * với phần tử vùng chứa và chèn. –

3

Tôi đã gặp phải vấn đề này, đã thử giải pháp ở trên. Nhưng nó không hiệu quả với tôi. Tìm thấy giải pháp jquery khá cơ bản sau đây.

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

Bạn có thể kiểm tra tính chất bên trong của popup đối tượng, bao gồm _wrapper, vv

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

Đó là những gì tôi tìm thấy trên trang web chính thức mapbox: Create a click event in a marker popup with Mapbox.js and jQuery. Các bình luận giải thích lý do tại sao chúng ta nói $('#map') thay vì $('#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!');}); 
0

mapbox thư viện JavaScript có một sự kiện:

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

không đổ mã, giải thích nó. một lời giải thích tốt là quan trọng để hiểu tại sao giải pháp đề xuất của bạn sẽ giải quyết vấn đề của OP. –

Các vấn đề liên quan