JS自定义地图标注

翅膀的初衷

发表于2014-08-20 22:28:38

前面写过一个在百度地图上面做标记的文章,今天再来讲讲怎么在自定义地图(也不一定是地图)上做标记。

比如像一人员定位系统之类的软件,就需要用到类似的功能,不过以前大多都是在桌面软件上实现,今天我在这里演示如何在web平台实本功能。

首先我们需要用到一张地图素材,我在这里随便在网上搜了一张某某矿井的地图:

原理其实很简单,我们只要监视容器的click事件,然后计算出点击位置的相对坐标保存即可:

$("#allmap").click(function (e) { if (e.target == document.getElementById("allmap")) { addMarker(0, '', e.offsetX, e.offsetY); return false; } });

完整代码如下:

<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>地图标记</title> <script src="http://www.jiniannet.com/Scripts/json2.js"></script> <script src="http://www.jiniannet.com/Resources/Script/JQuery.js"></script> <style type="text/css"> body, html, #allmap { margin: 0; padding: 0; width: 100%; height: 100%; overflow: hidden; } .hidden { display: none; } #allmap { background: #ffffff no-repeat center center; position: relative; overflow: hidden; *zoom: 1; -moz-user-select: none; /*火狐*/ -webkit-user-select: none; /*webkit浏览器*/ -ms-user-select: none; /*IE10*/ -khtml-user-select: none; /*早期浏览器*/ user-select: none; } #box { height: 100%; position: relative; overflow: auto; *zoom: 1; border: solid 1px #ccc; } #bar { width: 220px; position: absolute; background: #000000; right: 5px; border: solid 1px #808080; top: 20px; background: #f5f5f5; padding: 10px; font-size: 12px; } #bar .row { padding: 5px 0; } #bar ul { margin: 0; padding: 0; overflow: auto; } #bar ul li { margin: 0; padding: 0; list-style: none; } #bar ul li input { width: 80px; } .marker, .marker-hover { height: 36px; overflow: hidden; position: absolute; vertical-align: middle; font-size: 12px; width: 100px; overflow: hidden; z-index: 9999; } .marker i { display: block; overflow: hidden; border-radius: 5px; vertical-align: middle; border: solid 1px #46a47e; background-color: #8df5cb; margin: auto; height: 14px; width: 50px; filter: alpha(Opacity=80); -moz-opacity: 0.5; opacity: 0.5; } .marker em { display: block; background-color: #46a47e; width: 10px; height: 10px; overflow: hidden; border-radius: 100%; vertical-align: middle; position: absolute; top: 3px; left: 45px; } .marker span, .marker-hover span { color: #000; font-size: 12px; line-height: 20px; display: block; vertical-align: middle; width: 100%; height: 20px; text-align: center; overflow: hidden; text-shadow: 1px 1px 5px #fff; color: #10896b; } .marker-hover i { display: block; overflow: hidden; border-radius: 5px; vertical-align: middle; border: solid 1px #980808; background-color: #f7987e; margin: auto; height: 14px; width: 50px; filter: alpha(Opacity=80); -moz-opacity: 0.5; opacity: 0.5; } .marker-hover em { display: block; background-color: #f00; width: 10px; height: 10px; overflow: hidden; border-radius: 100%; vertical-align: middle; position: absolute; top: 3px; left: 45px; } </style> <script type="text/javascript"> var config = { index: 0 }; function load(callback) { var src = $("#url").val(); if (!src) { alert('请填写图片地址'); return; } $("#allmap").css({ backgroundImage: '' }).html('加载中……'); var img = new Image(); img.onerror = function () { alert("图片加载失败"); }; img.onload = function () { $("#allmap").css({ width: img.width + "px", height: img.height + "px", backgroundImage: 'url(' + src + ')' }).html(''); if (callback) { callback(); } }; img.src = src; $("#items li").remove(); config.index = 0; } function addMarker(id, name, x, y) { if (!name) { name = "未命名 " + (config.index + 1); } $('<div class="marker" onclick="return false" id="marker' + config.index + '" data-id="' + config.index + '" title="' + name + '" style="left:' + (x - 50) + 'px;top:' + (y - 8) + 'px"><i></i><span>' + name + '</span><em></em></div>').appendTo($("#allmap")); $("#items").append('<li id="li' + config.index + '" data-option="x:' + x + ',y:' + y + ',id:' + id + '"><input type="text" onchange="setMarkerValue(' + config.index + ',this.value)" id="markername' + config.index + '" value="' + name + '" /> <span id="sp' + config.index + '">X:' + x + ' Y: ' + y + '</span> <a href="javascript:del(' + config.index + ')">删除</a></li>'); config.index++; } //onchange function del(i) { var j = eval("({" + $('#li' + i).attr("data-option") + "})"); if (parseInt(j.id) > 0) { $.ajax({ url: 'DEMMARKER.aspx', type: "post", data: "id=" + j.id, success: function (r) { if (r == "ok") { $('#li' + i + ',#marker' + i).remove(); } else { alert(r); } } }); } else { $('#li' + i + ',#marker' + i).remove(); } } function setMarkerValue(i, value) { $("#marker" + i).attr("title", value); $("#marker" + i + " span").html(value); } function save() { var data = []; var html = ''; var list = $("#items li"); for (var i = 0; i < list.length; i++) { var j = eval("({" + $(list[i]).attr("data-option") + "})"); j.title = list[i].getElementsByTagName("input").item(0).value; data.push(j); } alert('此处进行AJAX保存:' + JSON.stringify(data)); alert('保存成功'); } $(function () { var id = ''; $("#allmap").click(function (e) { if (e.target == document.getElementById("allmap")) { addMarker(0, '', e.offsetX, e.offsetY); return false; } }); var h = $(window).height(); var w = $(window).width(); $("#bar").height(h - 70); $("#items").height(h - 150); $("#box").width(w - 260) $(".marker").live("mousemove", function (e) { $(this).css("cursor", "move"); }); $(".marker").live("mouseout", function (e) { $(this).css("cursor", "normal"); }); $(".marker").live("mousedown", function (e) { var s = $(this)[0]; var d = document; var x = e.clientX + d.body.scrollLeft - s.offsetLeft;//offsetX var y = e.clientY + d.body.scrollTop - s.offsetTop; var l = 0, t = 0; d.ondragstart = "return false;"; d.onselectstart = "return false;"; d.onselect = "document.selection.empty();"; if (s.setCapture) { s.setCapture(); } else if (window.captureEvents) { window.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP); } else { } d.onmousemove = function (e1) { if (!e1) { e1 = window.event; } l = e1.clientX + document.body.scrollLeft - x; t = e1.clientY + document.body.scrollTop - y; s.style.left = l + "px"; s.style.top = t + "px"; var dataId = $(s).attr("data-id"); $("#li" + dataId).attr("data-option", 'x:' + (l + 50) + ',y:' + (t + 8) + ',id:' + dataId); $("#sp" + dataId).html('X:' + (l + 50) + ' Y: ' + (t + 8)); //$('<div class="marker" onclick="return false" id="marker' + config.index + '" title="' + name + '" style="left:' + (x - 50) + 'px;top:' + (y - 8) + 'px"><i></i><span>' + name + '</span><em></em></div>').appendTo($("#allmap")); //$("#items").append('<li id="li' + config.index + '" data-option="x:' + x + ',y:' + y + ',id:' + id + '"><input type="text" onchange="setMarkerValue(' + config.index + ',this.value)" id="markername' + config.index + '" value="' + name + '" /> <span>X:' + x + ' Y: ' + y + ' <a href="javascript:del(' + config.index + ')">删除</a></li>'); }; d.onmouseup = function () { if (s.releaseCapture) { s.releaseCapture(); } else if (window.captureEvents) { window.captureEvents(Event.MOUSEMOVE | Event.MOUSEUP); } else { } d.onmousemove = null; d.onmouseup = null; d.ondragstart = null; d.onselectstart = null; d.onselect = null; }; }); if (id) { $.ajax({ url: 'Marker.json?id=' + id, dataType: "jsonp", jsonp: "callback", success: function (json) { $("#url").val(json.url); if (json.url) { load(function () { for (var i = 0; i < json.list.length; i++) { addMarker(json.list[i].id, json.list[i].title, json.list[i].x, json.list[i].y); } }); } }, error: function (a, b) { alert(a.responseText); alert(b) } }); } else { if ($("#url").val()) { load(); } } }); function uploadfile() { $("#btnUpload").click(); } </script> </head> <body> <div id="box"> <div id="allmap"> </div> </div> <div id="bar"> <form id="form1" runat="server"> <div class="row">图片地址:<input type="text" id="url" runat="server" value="http://www.jiniannet.com/Attachment/20191" /> </div> <div class="row"> <asp:FileUpload ID="files" onchange="uploadfile()" runat="server" CssClass="hidden" /> <input type="button" onclick="$('#files').click()" value="浏览" /> <asp:Button ID="btnUpload" runat="server" CssClass="hidden" Text="上传" OnClick="btnUpload_Click" /> <input type="button" onclick="load()" value="加载" /> <input type="button" value="保存" onclick="save()" /> </div> <div class="item"> <ul id="items"></ul> </div> </form> </div> </body> </html>

实现效果