<span style="font-family: 'Microsoft YaHei'; background-color: rgb(255, 255, 255);">
</span>
<span style="font-family: 'Microsoft YaHei'; background-color: rgb(255, 255, 255);">这一篇主要谈谈浏览器端实现过程中的一些知识点:</span>
这是本人才开始写博客,只是想把学到的东西做个记录以及和有兴趣的朋友一起交流,所以有什么不对的地方,还望指正O(∩_∩)O~
根据用户提出的要求,对代码进行更新,这个就比较有难度,实际上来本来的代码就有1300+行,看起来比较吃力,到最后完成时的代码1700+,这已经是精简到不能在精简的地步了,除了地图初始化和初始加载数据以外基本都是重新写的,按要求还得继续沿用之前的逻辑,以前的代码是学校的一个老师写的,我从中学到了很多书写以及逻辑上的规范,这也是这一次项目我认为最大的收获了。
谈谈关于浏览器端实现地图吧,要求使用Google地图,以及实现离线地图,网点页面合理展示,右边列表展示,列表和地图相关联,也就是说列表更新,地图上也要更新,点击列表项和地图中对应的marker都能使地图移动到相对应的位置,并且打开infowindow展示信息,要实现新增网点功能,根据权限对数据进行操作(删除修改查看),以及其他小功能。网上开放的Google地图API不好找,但是也有敬业的程序猿已经帮咱们翻译转载了 Google地图API参考
下面谈谈过程中相关的知识点吧,
1,如何加载地图以及地图相关的实现
这一点,其实和百度地图是相同的,无非是加载官方给的js,然后按照API根据自己的需求进行操作罢了,直接贴代码吧
function loadMap() {
if (GBrowserIsCompatible()) {
var copyright = new GCopyright(1, new GLatLngBounds(new GLatLng(-90, -180), new GLatLng(90, 180)), 0, "2010 @local");
var copyrightCollection = new GCopyrightCollection("NewCopyright");
copyrightCollection.addCopyright(copyright);
omap = new GMap2(document.getElementById('map'));
// 给地图添加内置的控件,分别为:
// 平移及缩放控件(左上角)、比例尺控件(左下角)、缩略图控件(右下角)
omap.addControl(new GLargeMapControl());
omap.addControl((new GScaleControl()), (new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize(10,10))));
//omap.addControl(new GOverviewMapControl());
//omap.addControl(new GMapTypeControl(), (new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(40, 10))));
//omap.addControl(copyrightCollection);
omap.enableDoubleClickZoom();
omap.enableContinuousZoom();
omap.enableScrollWheelZoom();
// 添加自定义的控件
//omap.addControl(new GRulerControl());
// 将视图移到重庆
omap.setCenter(new GLatLng(29.5, 106.5), 11);
GAddCopyright("m", "12828912669336610694", 19.5806, 76.2383, 54.4194, 137.7617, 4, "@demodemo @local", 18, false);
var divmap = document.getElementById('map');
divmap.childNodes[1].style.display = 'none';
// 设置放大和缩小级别范围为4-18
// GEvent.addListener(omap,'zoomend',function(oldLevel,newLevel){
// if(newLevel>=18 || newLevel<=0)
// {
// omap.setZoom(oldLevel);
// }
// });
var mapTypes = omap.getMapTypes();
//对所有地图类型限制缩放级别
for(var i=0; i<mapTypes.length; i++)
{
mapTypes[i].getMinimumResolution = function() { return 4; };
mapTypes[i].getMaximumResulution = function() { return 18; };
}
}
}
2,新增网点操作
①这里不得不提一下关于代码整体的规范化了,这对后期修改,更新都是有很大帮助的,
就比如在代码有一些频繁调用的变量都是必须写在前面并且做好注释的,
var strInitString = '';
var strKeywordError = '关键字有误,请确认!';
var strNewBranch = '请在地图上点击新网点的位置。';
var strNullAlert = '某些字段不允许提交空值,请检查!\r\n提交已被取消';
var strCommError = '没有获得任何信息!请与客服联系!';
var strNoBranch = '对不起,没有匹配的网点记录!';
var strDeleteConfirm = '删除操作不可恢复,是否继续?';
// 地图上branch的ID的个性化前缀
var prefixOfBranchMarker = 'yx_branch';
// 【系统设置】
// 分页单页记录数设置
var gintRecordCount = 10;
// 分页窗口大小设置
var gintPageWindowCount = 5;
// 【全局变量】
// javascirpt地图对象omap
var omap = null;
// 当前用户对象。值为null表示用户没登录
var curUser = null;
// 搜索返回结果对象。存储和操作查询获得的结果
var oSearchResultList = null;
// 当前网点分类对象。值为-1表示“全部”,即未对“分类”进行过滤,否则为过滤所用的“分类”编号
var oCatID=-1;
// 当前地图所包含的全部Marker的数组。用于地图上标记的显示和操作
var allmarkers=[];
// 当前编辑的branch所对应的marker在allmarkers中的索引值。
var oEditIndex = null;
②新增实现原理:点击新增按钮,页面给一个初始化的marker,拖动指定的位置,点击marker打开infowindow添加信息,在打开是就确定marker的坐标,添加网点信息完成后提交ajax完成操作.涉及到的几个问题和代码如下:
//激活地图对于click事件的响应,设置Listener
GEvent.addListener(omap, 'click', function (your param) {
//code
}
//根据用户点击位置,构造新的GPoint
var oGPoint = new GPoint(evt.x, evt.y);
var oGMarkerOptions = {
title: "新增网点", // 设置Marker标题
clickable: true, // 设置Marker是否可以被点击
draggable: true // 设置Marker是否可以被拖动
};
var oGMarker = new GMarker(oGPoint, oGMarkerOptions);
GEvent.addListener(oGMarker, 'click', function (evt) {
// 在Marker上打开InfoWindow,并设置内容
oGMarker.openInfoWindow('<div id="divAddBranch" style="width: 600px; height: 360px;"><div style="position: relative; top: 120px; width:100%;"><div style="text-align: center; width: 100%;">界面初始化中,请等待...<br /><img src="images/ajax-loader.gif" /></div></div></div>', {
noCloseOnClick: false
});
//Ajax动态加载添加项:
$.post("../admin/BranchEditByMap.asmx/GetCatDistrictUnitList", null, function (param) {
//code
})
// 构造图片上传对象
贴代码index-develop178-195
// 激活Marker对于dragstart事件的响应,设置Listener
GEvent.addListener(oGMarker, 'dragstart', function (evt) {
// 开始拖动时,关闭Marker上的信息框
oGMarker.closeInfoWindow();
});
// 注销地图的click事件
GEvent.clearListeners(omap, 'click');
地图显示部分①②③④⑤
①新建或修改Branch时选中某输入项所进行的操作。高亮显示选中的输入项
function getInputFocus(obj){
var parentJObj = $(obj).parent();
parentJObj.css({'background':'#FFFF66'});
parentJObj.prev().css({
'background':'#FFFF66'
});
}
②新建或修改Branch时取消选中某输入项所进行的操作。高亮显示不正确的输入项
function lostInputFocus(obj){
var parentJObj = $(obj).parent();
$(obj).css({'border':'#000000 1px solid;'});
parentJObj.css({'background':'transparent'});
parentJObj.prev().css({
'color':'#000000',
'background':'transparent'
});
// 高亮显示输入不正确的项目
if(trim($(obj).val())==''){
$(obj).css({'border':'#FF0000 1px solid;'});
parentJObj.prev().css({'color':'#FF0000'});
}
}
③ajax提交表单,在这里必须说一下为什么每一次都需要传递一个pageindex进去,这是因为在设计时右边的列表是动态生成的,每一次翻页都是进行了一次查询,而不是将所有的数据都返回到浏览器中等待需要显示的时候才显示出来,一方面是为了安全,另外一方怎么出于对加载速度的考虑,后面证明这个给我们带来了不小的麻烦
var sData = {
keyword : trim($('#textBranchKeyword').val()),
districtID : $('#searchDTID').val(),
unitID : $('#searchUnitID').val(),
catID : $("#searchCatID").val(),
pageIndex : intPageIndex+1,
itemCountPerPage : intRecordCount
};
$.post("../admin/BranchEditByMapdd.jsp/GetBranchListByAdvanced",
sData,
lFuncAdvancedSearchCallback
);
④实现右侧列表分页显示:
for(var i=startBranchIndex;i<endBranchIndex;i++){
var oBranchDiv = $('<div>')
.attr({'id':'divBranch_'+i})
.addClass('branchItem')
// 绑定mouseover事件
.bind('mouseover',lFuncFocusBranch)
// 绑定mouseout事件
.bind('mouseout',lFuncLostFocusBranch)
// 存储branch的经纬度坐标
.append('<input type="hidden" id="' + prefixOfBranchMarker + '_' + i + '" value="'+oBranchList[i].longitude+','+ oBranchList[i].latitude +'" />')
.append($('<div>')
.attr({'id':'divBranchDetail_'+i})
// 绑定branchItem的click事件
.bind('click',function(evt){
// 获得产生当前事件的branchIndex
var oBranchIndex = evt.currentTarget.id.split('_')[1];
if($('#'+prefixOfBranchMarker + '_' + oBranchIndex).length >0){
var oGMarker = allmarkers[oBranchIndex];
var oBranch = oBranchList[oBranchIndex];
var oDiv = $('<div>');
oDiv.append($('<div>').html(oBranch.branchName).css({'font-size':'16px','font-weight':'bold','margin':'2px 0px 2px 0px'}))
.append($('<div>').html('<span style="font-size:11px;">'+ oBranch.unitLongName+'</span>').css('margin-bottom','5px'));
if(transNull(oBranch.address)!=''){
oDiv.append($('<div>').html('地址:<span style="font-size:15px;">'+ oBranch.address+'</span>').css('margin-bottom','5px'));
}
if(transNull(oBranch.telephone)!=''){
oDiv.append($('<div>').html('电话:<span style="font-size:15px;">'+oBranch.telephone+'</span>').css('margin-bottom','5px'));
}
if(transNull(oBranch.openingHours)!=''){
oDiv.append($('<div>').html('营业时间:<br /><span style="font-size:15px;">'+oBranch.openingHours+'</span>').css('margin-bottom','5px'));
}
if(transNull(oBranch.paymethod)!=''){
oDiv.append($('<div>').html('支付方式:<br /><span style="font-size:15px;">'+oBranch.paymethod+'</span>').css('margin-bottom','5px'));
}
if(transNull(oBranch.services)!=''){
oDiv.append($('<div>').html('服务内容:<br /><span style="font-size:15px;">'+oBranch.services+'</span>').css('margin-bottom','5px'));
}
if(transNull(oBranch.addressMarker)!=''){
oDiv.append($('<div>').html('标志建筑:<br /><span style="font-size:15px;">'+oBranch.addressMarker+'</span>').css('margin-bottom','5px'));
}
if(transNull(oBranch.vistorContent)!=''){
oDiv.append($('<div>').html('当前人流量:<br /><span style="font-size:15px;">'+oBranch.vistorContent+'</span> 人').css('margin-bottom','5px'));
}
if(transNull(oBranch.billContent)!=''){
oDiv.append($('<div>').html('业务量:<br /><span style="font-size:15px;">'+oBranch.billContent+'</span> 元').css('margin-bottom','5px'));
}
oGMarker.openInfoWindow(oDiv.html(),{});
}
js中提供一些基本的数学函数,就比如这里使用到的Math.ceil()和Math.floor()向上取整合向下取整
⑤这里不得不得说一下规范,所有的属性只要能循环都是循环生成的,就比如下面这些代码if($('#'+oContainer).length != 0){
// 清除oContainer中的内容
$('#'+oContainer).html('');
}
ar oBranchDiv = $('<div>')
.attr({'id':'divBranch_'+i})
var oBranchDivEdit = $('<div>')
.attr('id','divBranchEdit_'+i)
.css({
'text-align':'right',
'display':'none'
});
⑥根据权限判断是否能修改删除数据,最开始的设计时通过session的参数来实现判断用户是否登陆,如果登陆了则对数据进行赋值,代码:
if(oBranchList[i].isEdit.toLowerCase()=='true'){
oBranchDivEdit.append('<input type="image" οnclick="return lFuncEditBranchClick('+i+');" src="images/map_edit.gif" title="编辑" />');
}
if(oBranchList[i].isDel.toLowerCase()=='true'){
oBranchDivEdit.append('<input type="image" οnclick="return lFuncDeleteBranchClick('+i+');" src="images/remove.gif" title="删除" />');
}
⑦给右侧列表添加修改删除按键的方法实现:
修改实现:
function lFuncEditBranchClick(oIndex){
omap.clearOverlays();
/
oEditIndex = oIndex;
var oBranch = oSearchResultList.branches[oIndex];
var oGPoint = new GPoint(oBranch.longitude,oBranch.latitude);
var oGMarkerOptions = {
title: oBranch.branchName,
clickable: true,
draggable: true
};
var oGMarker = new GMarker(oGPoint, oGMarkerOptions);
omap.setCenter(new GLatLng(oBranch.latitude, oBranch.longitude));
GEvent.addListener(oGMarker, 'click', function (evt) {
lFuncOpenModifyPanel(oGMarker,evt);
});
GEvent.addListener(oGMarker, 'dragstart', function (evt) {
oGMarker.closeInfoWindow();
});
GEvent.addListener(oGMarker, 'dragend', function(evt) {
lFuncOpenModifyPanel(oGMarker,evt);
});
omap.addOverlay(oGMarker);
}
然后就是打开infowindow填写数据,直接调用新增网点时的方法就可以辣,只不过这里的一些地方需要改一下,比如在选择catID时给出下拉列表,要设置当前的catID为已选择,这是提高友好度的一个小细节
删除实现很简单
function lFuncDeleteBranchClick(oIndex){
var oAnswer = confirm(strDeleteConfirm);
if(oAnswer){
var sData = {
branchID : oSearchResultList.branches[oIndex].branchID
};
$.post('../admin/BranchEditByMap.asmx/DeleteBranch', sData,function(resData){
resData = eval('('+$(resData).text()+')');
if(resData.message=='success' && resData.deleteResult == '1'){
lFuncAdvancedSearch();
} else {
alert('删除失败!');
}
});
⑧Googlemap使用自定义的marker图标和注册事件
var gIcon = new GIcon(G_DEFAULT_ICON);
gIcon.image = 'images/gbranch_' + i + '.png';
gIcon.iconSize = new GSize(20,32);
var oGMarker = new GMarker(new GLatLng(branches[i].latitude,branches[i].longitude),{
icon : gIcon,
title:branches[i].branchName
});
⑨代码中多次用到的trim函数,这个在java和c#中本身是定义了的,但是在js中是没有的,这是一个去掉内容左右两边的空格的,具体代码
function trim(str){
return str.replace(/^\ +|\ +$/ig,"");
}
这是js正则表达式写的,具体正则的内容,我将在以后写新的文章,希望一起学习进步
⑩js加载下拉列表,虽然很简单,但是我觉得还写一下比较好,万一忘了呢?
哈哈
$("#searchDTID").html('').append('<option value="-1">--选择区域--</option>');
var districtList = param.districtList;
for (var i = 0; i < param.districtList.length; i++) {
$("#searchDTID").append('<option value="' + districtList[i].districtID + '">' + districtList[i].districtName + '</option>');
}