地图全屏
leaflet
你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。
地图的制作
leaflet官方网址:https://leafletjs.com/examples/quick-start/
需求:用leaflet制作地图,地图上要有标记,点击标记,要展示模态框(运用lazyUI写的),模态框是表格,点击模态框的按钮,又要弹出一个模态框,在第二个模态框中要运用echarts进行展示图形。所制作的这个地图是一个iframe,要嵌入react中。最后新增加了一个全屏的功能,全屏时,marker标记也是可以点击的。
创建地图的步骤:
引入文件:
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" integrity="sha512-07I2e+7D8p6he1SIM+1twR5TIrhUQn9+I6yjqD53JQjFiMf8EtC93ty0/5vJTZGF8aAocvHYNEDJajGdNx1IsQ==" crossorigin="" />
<script src="https://unpkg.com/[email protected]/dist/leaflet-src.js" integrity="sha512-WXoSHqw/t26DszhdMhOXOkI7qCiv5QWXhH9R7CgvgZMHz1ImlkVQ3uNsiQKu5wwbbxtPzFXd1hK4tzno2VqhpA==" crossorigin=""></script>
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.js "></script>
<script src="leaflet.ChineseTmsProviders.js"></script>
<script src="./layui/layui.all.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<link rel="stylesheet" href="screen.css" />
<link rel="stylesheet" href="MarkerCluster.css" />
<link rel="stylesheet" href="MarkerCluster.Default.css" />
<link rel="stylesheet" href="./layui/css/layui.css" media="all">
<script src="leaflet.markercluster-src.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/4.2.1/echarts-en.common.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.20.1/moment.min.js"></script>
<script src='https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/Leaflet.fullscreen.min.js'></script>
<link href='https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/leaflet.fullscreen.css' rel='stylesheet' />
<script src="leaflet.spin.min.js" charset="utf-8"></script>
<script src="spin.min.js" charset="utf-8"></script>
因为所制作的地图的双层的展示,所以要利用分层的概念
//初始化站点信息
var site_name = "";//站点名称
var site_code = "";//站点编号:
var map = L.map("map",{
center:[20.04194,110.34136],
zoom:8,
layers:[normal],
zoomControl:false,
// fullscreenControl: true,//这个就是全屏的插件
});
L.control.layers(baseLayers,overlayLayers).addTo(map);
L.control.zoom({zoomInTitle:'放大', zoomOutTitle:'缩小'}).addTo(map);
var markers = new L.MarkerClusterGroup();
async function populate(a) {
map.spin(true);//这个是加载的插件,当数据还没请求过来的时候,进行loading
this.axios.get(`${Path}/device/findAllDevice`, //这里是请求marker标记的数据,
})
.then(function (response) {
map.spin(false);
var lists = [];
lists = response.data.list;
var i = 0;
setInterval(
()=>{
i++;
if(((i-1)*100)<lists.length){
loadmaker(lists,(i-1)*100,i*100);//这里运用了懒加载,数据太过庞大,所以运用懒加载加载出来
}
}
,10)
})
.catch(function (error) {
map.spin(false);
console.log(error,'失败');
});
return false;
}
function loadmaker(lists,start,end){
for (var i = start; i < end; ++i) {
if(i<lists.length){
var m = new L.Marker(L.latLng(lists[i].lat,lists[i].lng),//(纬度,经度)
{ icon: L.icon({
iconUrl: lists[i].type == 1 ? 'helicopter.png' : 'airplane.png',//这里是自定义marker标记的图标
iconSize: [32, 32]
})},
);
m.markMessage = lists[i];
markers.addLayer(m);
}
}
}
function getSiteByid(siteId,a) {//这里是点击的时候获取的站点信息
this.axios.post(`${Path}/pub/dict/value/deailByCode`, {
siteCode:siteId
})
.then(function (response) {
console.log(response,'成功');
site_name = response.data.list.name;
site_code = response.data.list.code;
load_dialog(a);//这里就调出了弹框,弹框都是运用lazyUI写的
_thisA = a;
})
.catch(function (error) {
console.log(error,'失败');
});
return false;
}
//加载弹窗
function load_dialog(a){
var zname = a.layer.markMessage.dveCode;
var state_name = ""; //状态显示值
if(a.layer.markMessage.status == 0){
state_name = "启用";
}else{
state_name = "禁用";
}
var hname = ''
if(a.layer.markMessage.hname === undefined){
hname = ''
}else{
hname = a.layer.markMessage.hname
}
var code = document.getElementById("code");
var name = document.getElementById("name");
var Adress = document.getElementById("Adress");
var staffName = document.getElementById("staffName");
var TIME = document.getElementById("TIME");
var HuZhu = document.getElementById("HuZhu");
var Status = document.getElementById("Status");
code.innerHTML = site_code?site_code:''
name.innerHTML = site_name?site_name:''
Adress.innerHTML = a.layer.markMessage.installAddress?a.layer.markMessage.installAddress:''
staffName.innerHTML = a.layer.markMessage.staffName?a.layer.markMessage.staffName:''
TIME.innerHTML = a.layer.markMessage.instaffTime?moment(a.layer.markMessage.instaffTime).format('YYYY-MM-DD HH:mm:ss'):''
HuZhu.innerHTML = a.layer.markMessage.hname?a.layer.markMessage.hname:''
Status.innerHTML = state_name?state_name:''
openModal1 = layer.open({//lazyUI表格的定义
type: 1,
title: zname,
id:'ae',
closeBtn: 1,
zIndex:layer.zIndex,
area: ['500px', '400px'],
skin: 'layui-layer-molv' ,
icon: 6,
content: $('#modal'),
cancel: function(index, layero){
var modal = document.getElementById("modal");
modal.style.display = "none";
var layModal = document.getElementById("layModal");
layModal.style.display = "none";
layer.closeAll();
},
});
}
markers.on('click', function (a) {//表达点击事件
var siteId = a.layer.markMessage.siteNm;//获取站点id
getSiteByid(siteId,a);
});
populate(); //地图初始化
map.addLayer(markers);
这里是弹出的模态框。
这是在react中嵌入iframe.
全屏插件
https://leafletjs.com/plugins.html#fullscreen-controls 这个是讲述leaflet全屏插件的网址
具体应用:
因为是iframe嵌入的,而且我要显示的模态框并不是像其他地图一样,是自带的模态框,所以当我用leaflet中自带的全屏插件时,当我点击的时候,模态框虽然出来了,但是被地图覆盖了,不管怎么调z-index都没有用。(但是有个大佬告诉了我一个方法,他说叫我把模态框也放在全屏的节点中,这样就能实现,但是。。。我不会)最后我只能自己写一个全屏的功能,把整个iframe进行全屏。这样就能展示了。这里多亏了这篇文章https://blog.csdn.net/qq_38122518/article/details/81035253
全屏的实现
一个大佬的文章
https://www.itsvse.com/misc.php?mod=tag&id=2726
iframe.html中自己设置一个按钮
raect中也要进行设置:
当点击按钮是时,进行showFullScreen()方法的触发
// 全屏,
launchFullscreen=(element)=> {
if (element.requestFullscreen) {
element.requestFullscreen();
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen();
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen();//ie浏览器
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullScreen();//谷歌浏览器
}
}
exitFullscreen=()=> {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (
document.msExitFullscreen){
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
}
}
//全屏按钮上调用的方法
showFullScreen=()=>{
var elm = document.getElementById("map");
var iframe = document.getElementById("iframe");
if (document.fullscreenEnabled) {
var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement;
if (fullscreenElement) {
iframe.style.height = '91%'
this.exitFullscreen();
} else {
iframe.style.height = '100%'//全屏的时候设置高度
this.launchFullscreen(elm);
}
}
}
我以为这样就实现了,可是发现当用户按键盘esc键时,其实是没有触发方法的,虽然按esc键退出了全屏,但是它的高度没用变化。这就需要有个方法进行判断,当时找了很多方法,全局监听键盘事件,监听窗口的大小等,最后终于找到了一个方法。
var isFullscreen = true//用这个变量进行判断
componentDidMount(){
this.props.dispatch({
type:'home/fetch',
payload:{}
})
var elm = document.getElementById("map");
var iframe = document.getElementById("iframe");
document.addEventListener("fullscreenchange", function(e) {
if (isFullscreen) {
iframe.style.height = '100%'
isFullscreen=false
} else {
iframe.style.height = '91%'
isFullscreen=true
}
});
document.addEventListener("mozfullscreenchange", function(e) {
if (isFullscreen) {
iframe.style.height = '100%'
isFullscreen=false
} else {
iframe.style.height = '91%'
isFullscreen=true
}
});
document.addEventListener("webkitfullscreenchange", function(e) {
if (isFullscreen) {
iframe.style.height = '100%'
isFullscreen=false
} else {
iframe.style.height = '91%'
isFullscreen=true
}
});
document.addEventListener("msfullscreenchange", function(e) {
if (isFullscreen) {
iframe.style.height = '100%'
isFullscreen=false
} else {
iframe.style.height = '91%'
isFullscreen=true
}
});
}
到这里就把所有的功能都实现了。在这一系列进行摸索的过程中,我学会了很多知识。
react添加监听事件监听键盘事件
componentDidMount(){
window.addEventListener('keypress', function(e){
console.log(e,e.which,88)
}
}
监听退出全屏事件
window.onresize = function() {
if (!checkFull()) {
//要执行的动作
$("#dashboard_id").removeClass('expand').addClass('contract');//这里捡个懒,直接用JQ来改className
}
}
function checkFull() {
var isFull = document.fullscreenEnabled || window.fullScreen || document.webkitIsFullScreen || document.msFullscreenEnabled;
//to fix : false || undefined == undefined
if (isFull === undefined) {isFull = false;}
return isFull;
}
//方法二
window.onresize = function(){
if(!checkFull()){
//要执行的动作
}
}
function checkFull(){
//判断浏览器是全屏的,但是对我这一点用也没得,一直是true,判断不出来
var isFull = document.fullscreenEnabled || window.fullScreen || document.webkitIsFullScreen || document.msFullscreenEnabled;
//to fix : false || undefined == undefined
if(isFull === undefined) isFull = false;
return isFull;
}
react中 怎么在componentDidmount中使用addEventListener和componentWillUnmount中使用removeEventListener
export default class A extends React.Component {
constructor(props) {
super(props);
this.keyPress = this.keyPress.bind(this);
}
keyPress(e) {
console.log(e,e.which,'c触发')
}
componentDidMount() {
window.addEventListener("keypress", this.keyPress);
}
componentWillUnmount(){
window.removeEventListener("keypress", this.keyPress, false);
}
render() {
};
}
总结
- iframe的运用,第一次知道可以直接嵌入一个heml页面
- 地图上显示的标记太多,刚开始总是卡死,后来用了懒加载,数据快了一点,最后发现get请求比post请求获取数据更快
- iframe嵌入到react中要使用一个组件及逆行搭桥