[英]Leaflet open popup on mouse hover over list
我的應用程序的一個視圖是,一側是所有引腳的列表,另一側是帶有實際引腳的地圖。
當我用鼠標懸停在列表中時,我希望彈出窗口打開。 假設我的鼠標位於列表中的 #1 我希望相應引腳的彈出窗口打開。
這是列表組件中的 html:
<table class="table-striped">
<thead>
<!-- <th>id</th> -->
<th>Kunstwerkname</th>
<th>Strasse</th>
<th>PLZ</th>
<th>
<button class="button-list" (click)="addArtwork()">
<img src="assets/icons/add.svg">
</button>
</th>
</thead>
<tbody>
<tr *ngFor="let artwork of artworkList;" class="artworkList" (mouseover)="previewPopup(artwork)">
<td>{{artwork.name}}</td>
<td>{{artwork.streetname}}</td>
<td>{{artwork.zipcode}}</td>
<td>
<button class="button-list" (click)="editArtwork(artwork)">
<img src="assets/icons/edit.svg">
</button>
<button class="button-list" (click)="deleteArtwork(artwork)">
<img src="assets/icons/delete.svg">
</button>
</td>
</tr>
</tbody>
</table>
列表組件的 ts:
import { Artwork, ArtworkService } from './../_services/artwork.service';
import { Component, OnInit, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-artwork-list',
templateUrl: './artwork-list.component.html',
styleUrls: ['./artwork-list.component.css']
})
export class ArtworkListComponent implements OnInit {
@Output() private add = new EventEmitter();
@Output() private edit = new EventEmitter<number>();
@Output() private preview = new EventEmitter<number>();
artworkList: Artwork[];
constructor(
private artworkService: ArtworkService,
) { }
ngOnInit() {
this.refresh();
}
refresh() {
this.artworkService.retrieveAll().then(
artworkList => this.artworkList = artworkList
);
}
addArtwork() {
console.log('add artwork');
this.add.emit();
}
editArtwork(artwork: Artwork) {
console.log('edit artwork ' + artwork.name + ' ' + artwork.id );
this.edit.emit(artwork.id);
}
deleteArtwork(artwork: Artwork) {
console.log('delete artwork ' + artwork.name + ' ' + artwork.id );
this.artworkService.delete(artwork.id).then(
() => this.refresh()
);
}
previewPopup(artwork: Artwork) {
console.log("hovering mouse");
console.log(artwork.id);
this.preview.emit(artwork.id);
}
}
和地圖組件的 ts :
import { Component, OnInit, Output, EventEmitter, ElementRef, Input } from '@angular/core';
/*When you include the leaflet script inside the Angular project, it gets
loaded and exported into a L variable.*/
declare let L; //this is the leaflet variable!
import { MapButtonsComponent } from './map-buttons/map-buttons';
import { Artwork, ArtworkService } from '../_services/artwork.service';
import { FilterMapComponent } from './filter-map/filter-map.component';
@Component({
selector: 'app-open-street-map',
templateUrl: './open-street-map.component.html',
styleUrls: ['./open-street-map.component.css']
})
export class OpenStreetMapComponent implements OnInit {
@Output() private add = new EventEmitter();
@Output() private edit = new EventEmitter<number>();
artworkList: Artwork[];
map;
// markerIcon
markerIcon = {
icon: L.icon({
iconSize: [25, 41],
iconAnchor: [13, 16],
iconUrl: 'assets/icons/marker.svg',
shadowUrl: 'assets/icons/marker-shadow.png'
})
};
constructor(
private artworkService: ArtworkService,
private elementRef: ElementRef
) { }
ngOnInit() {
this.map = L.map('map', {
center: [48.208, 16.373],
zoom: 13,
zoomControl: false,
});
this.refresh();
// base layer
L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="https://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
minZoom: 13,
id: 'mapbox.streets',
accessToken: 'pk.eyJ1IjoicHcxN2wwMDgiLCJhIjoiY2pua2c2OWxuMGVkOTNxbWh5MWNqajEwdyJ9.X_SuGwNGs12TwCsrsUvBxw'
}).addTo(this.map);
MapButtonsComponent.renderZoom(this.map);
MapButtonsComponent.renderCompass(this.map);
MapButtonsComponent.renderLocation(this.map);
}
previewArtwork() {
this.map.eachLayer(layer => {
if (layer instanceof L.Marker) {
this.map.removeLayer(layer);
}
});
let previewedMarker = L.marker([artwork.latitude, artwork.longitude], this.markerIcon)
.addTo(this.map)
.on('mouseover', () => {
openPopup();
});
}
}
}
可以考慮以下方法。 讓我們假設標記的初始數據以以下格式表示:
locations = [
{
name: "Oslo",
lat: 59.923043,
lng: 10.752839
},
{
name: "Stockholm",
lat: 59.339025,
lng: 18.065818
},
//..
];
然后對於地圖上的給定數據標記可以像這樣初始化:
this.markers = this.locations.map(loc => {
const marker = new L.marker({ lat: loc.lat, lng: loc.lng });
marker.bindPopup(loc.name);
marker.addTo(map);
return marker;
});
現在輪到選擇器組件和地圖本身之間的通信,讓我們假設以下選擇器:
<ul>
<li (mouseenter) ="mouseEnter(idx) " (mouseleave) ="mouseLeave(idx)" *ngFor="let loc of locations; let idx = index">{{ loc.name }}</li>
</ul>
那么彈出可見性可以這樣控制:
mouseEnter(selectedIndex) {
const selectedMarker = this.markers[selectedIndex];
selectedMarker.openPopup();
}
mouseLeave(selectedIndex) {
const selectedMarker = this.markers[selectedIndex];
selectedMarker.closePopup();
}
而不是使用mouseover
你必須聽mouseenter
和mouseleave
在mouseenter
您將創建一個彈出窗口並將其放置在地圖上,在mouseleave
您將關閉彈出窗口
jQuery 示例代碼(我的 postContent 相當於你的作品)
$("div.postContent").on("mouseenter", function(e) {
var postId = $(this).attr("data-postId");
tooltipPopup = L.popup();
var title = postlistByGlobalId[postId].title;
tooltipPopup.setContent(title);
tooltipPopup.setLatLng(markersByGlobalId[postId].getLatLng());
tooltipPopup.openOn(map);
$(this).addClass('hover');
});
$("div.postContent").on("mouseleave", function(e) {
$(this).removeClass('hover');
map.closePopup(tooltipPopup);
});
為了實現這一點,您需要為您的所有作品(在我的示例中為 postId)提供一個唯一的 id,並將您的標記放在一個關聯數組markersByGlobalId
這可能很有用: http : //franceimage.github.io/map和http://franceimage.github.io/map-v1
我的例子是單一的(1 個 html,1 個 js 文件)。 你需要做一些額外的工作才能在你的 Angular 應用程序中使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.