最近项目中完成的需求,仿百度地图中的功能:
要求:1.底层图可以拖拽、缩放。
2.拖拽一个图标,在底层图上对应位置添加一个标注点,该标注点位置要随底层图移动。
3.添加的标注点,可以拖动,删除。
主要知识点和难点就是各个浏览器的点击、拖拽、缩放事件兼容性,对js运动属性、运动偏移位置的了解,以及js面向对象的应用。
这里跟大家分享一下完成后的代码。
html代码主要知识点就是运动元素和底层元素的相对绝对定位,css代码不再贴出:
<div id="warp" style="position: relative;width: 100%;height: 100%;background: #d7d7d7;"><img title="拖动" class="dragImg" id="dragImg" src="images/video_16px_566474.png"><div class="dragAble bgDiv" id="block1" style="zoom:1;"><img id="wheelImg" src="images/photo2FDIB963M30AI20009NOS.jpg" style="zoom:1;" title="底层图片"><p>这段文字跟着div一起运动</p></div></div>
js代码,初始化:
1 var clearSlct = "getSelection" in window ? function() { 2 ????????????????window.getSelection().removeAllRanges(); 3 ????????????} : function() { 4 ????????????????document.selection.empty(); 5 ????????????}; 6 ????????????$(window).on("mouseup keyup", function() { 7 ????????????????clearSlct(); 8 ????????????}); 9 ????????????document.getElementById(‘warp‘).oncontextmenu = function(e){10 ????????????????e.preventDefault();11 ???????????????};12 ????????????var dragDemo=new dragImg(‘block1‘,‘dragImg‘,‘wheelImg‘);
js代码,构造器+原型链进行面向对象开发:
function dragImg(bgDivId, imgId, bgImgId) { ???this.disX = 0; ???this.disY = 0; //初始点击点 ???this.xx = 0; ???this.yy = 0; //点击点相对于button的左上角的距离left,top ???this.marginX = 0; ???this.marginY = 0; //运动后底层图偏移量 ???this.isdrag = false; ???this.clicky = 0; ???this.clickx = 0; //初始点击点 ???this.oDragObj = null; //操作对象 ???this.init(bgDivId, imgId); ???this.initBgDiv(bgDivId); ???this.initMouseWheel(bgImgId);}dragImg.prototype = { ???init: function(bgDivId, imgId) { //图标拖拽 ???????dragImg.imgId = imgId; ???????dragImg.bgDivId = bgDivId; ???????var drag_Img = document.getElementById(imgId), ???????????bg_div = document.getElementById(bgDivId); ???????drag_Img.addEventListener(‘mousedown‘, dragDownEvent, false); ???????drag_Img.addEventListener(‘mouseup‘, dragUpEvent, false); ???????function dragDownEvent(e) { ???????????$(‘.dragBtnSpan‘).remove(); ???????????var oevent = e || e.event; ???????????if(oevent.button == 0) { ???????????????var layerX = oevent.offsetX || oevent.layerX, ???????????????????layerY = oevent.offsetY || oevent.layerY; ???????????????dragImg.disX = oevent.clientX - drag_Img.offsetLeft; ???????????????dragImg.disY = oevent.clientY - drag_Img.offsetTop; ???????????????dragImg.xx = oevent.clientX - drag_Img.offsetLeft; ???????????????dragImg.yy = oevent.clientY - drag_Img.offsetTop; ???????????????document.onmousemove = dragMoveEvent; ???????????} ???????} ???????function dragMoveEvent(e) { ???????????var oevent = e || e.event; ???????????var x = oevent.clientX, ???????????????y = oevent.clientY; ???????????var offsetx = x - dragImg.disX, ???????????????offsety = y - dragImg.disY; ???????????// ???????????????console.log(offsetx,offsety); ???????????if(offsetx < 0) { ???????????????offsetx = 0; ???????????} else if(offsetx > document.documentElement.clientWidth - drag_Img.offsetWidth) { ???????????????offsetx = document.documentElement.clientWidth - drag_Img.offsetWidth; ???????????} ???????????if(offsety < 0) { ???????????????offsety = 0; ???????????} else if(offsety > document.documentElement.clientHeight - drag_Img.offsetHeight) { ???????????????offsety = document.documentElement.clientHeight - drag_Img.offsetHeight; ???????????} ???????????$("#" + dragImg.imgId).css(‘left‘, offsetx); ???????????$("#" + dragImg.imgId).css(‘top‘, offsety); ???????} ???????function dragUpEvent(e) { ???????????//拖拽结束,判断是否在允许放置的范围内(当前位置是否与底层图相交) ???????????var oevent = e || e.event; ???????????if(oevent.button == 0) { ???????????????$(‘.dragBtn‘).remove(); ???????????????var x = oevent.clientX, ???????????????????y = oevent.clientY; ???????????????var zoom = bg_div.style.zoom; //缩放比例 ???????????????var btn_X = drag_Img.offsetLeft, ???????????????????btn_Y = drag_Img.offsetTop, ???????????????????btn_width = drag_Img.offsetWidth * zoom, ???????????????????btn_height = drag_Img.offsetHeight * zoom, ???????????????????//缩放后长度,位置都会发生变化,需要*缩放倍率 ???????????????????map_X = bg_div.offsetLeft * zoom, ???????????????????map_Y = bg_div.offsetTop * zoom, ???????????????????map_left = bg_div.style.left, ???????????????????map_top = bg_div.style.top, ???????????????????map_width = bg_div.offsetWidth * zoom, ???????????????????map_height = bg_div.offsetHeight * zoom; ???????????????var m = (btn_X + dragImg.xx > map_X + map_width) || (btn_X + dragImg.xx + btn_width < map_X); ???????????????var n = (btn_height + btn_Y + dragImg.yy < map_Y) || (btn_Y + dragImg.yy > map_Y + map_height); ???????????????if(m || n) { ???????????????????console.log(‘相离‘); ???????????????} else { ???????????????????//缩放后位置会偏移 ???????????????????var yesIE = IEVersion(); ???????????????????if(yesIE != -1) { ???????????????????????//ie浏览器获取的就是实际偏移量,需要清除缩放倍率 ???????????????????????if(yesIE > 8 || yesIE == ‘Edge‘) { ???????????????????????????dragImg.marginX = bg_div.offsetLeft; ???????????????????????????dragImg.marginY = bg_div.offsetTop; ???????????????????????} ???????????????????} else { ???????????????????????dragImg.marginX = map_X, ???????????????????????dragImg.marginY = map_Y; ???????????????????} ???????????????????var percentX = (x - dragImg.marginX - dragImg.xx) / zoom; ???????????????????var percentY = (y - dragImg.marginY - dragImg.yy) / zoom; ???????????????????// ???????????????console.log(‘percentXxxxx‘,percentX); ???????????????????// ???????????????console.log(‘percentYyyyy‘,percentY); ???????????????????LONG=percentX;//选定坐标点,赋值全局变量 ???????????????????LAT=percentY; ???????????????????var createImg = document.createElement(‘img‘); ???????????????????createImg.src = ‘resources/images/point_easyicon.png‘; ???????????????????createImg.style.left = percentX + ‘px‘; ???????????????????createImg.style.top = percentY + ‘px‘; ???????????????????var btnId = ‘btn_‘ + parseInt(percentX) + "_" + parseInt(percentY); ???????????????????createImg.setAttribute(‘id‘, btnId); ???????????????????createImg.setAttribute(‘class‘, ‘dragBtn‘); ???????????????????bg_div.appendChild(createImg); ???????????????????$("#" + btnId).on(‘mousedown‘, function(event) { ???????????????????????if(event.button == 2) { ???????????????????????????$(‘.dragBtnSpan‘).remove(); ???????????????????????????var dragBtnSpan = document.createElement(‘ul‘); ???????????????????????????var htm = ‘<li><a href="javascript:(0);" onclick="alert(123);">移动</a></li><li><a href="javascript:(0);" onclick="alert(456);">删除</a></li>‘; ???????????????????????????dragBtnSpan.innerHTML = htm; ???????????????????????????dragBtnSpan.setAttribute(‘id‘, btnId + ‘ul‘); ???????????????????????????dragBtnSpan.setAttribute(‘class‘, ‘dragBtnSpan‘); ???????????????????????????bg_div.appendChild(dragBtnSpan); ???????????????????????????$(‘#‘ + btnId + ‘ul‘).css(‘left‘, percentX + 10).css(‘top‘, percentY + 10).show(); ???????????????????????} ???????????????????}); ???????????????????$("#dragImg").css(‘left‘, 10); ???????????????????$("#dragImg").css(‘top‘, 10); ???????????????} ???????????????document.onmousemove = null; ???????????} ???????} ???}, ???initBgDiv: function(bgDivId) { //底层图拖拽 ???????dragImg.bgDivId = bgDivId; ???????var bg_div = document.getElementById(bgDivId); ???????bg_div.addEventListener(‘mousedown‘, initDrag, false); ???????document.onmouseup = new Function("dragImg.isdrag=false"); ???????function initDrag(e) { ???????????if(e.button == 0) { ???????????????var nn6 = document.getElementById && !document.all; ???????????????var oDragHandle = nn6 ? e.target : event.srcElement; ???????????????var topElement = "HTML"; ???????????????while(oDragHandle.tagName != topElement && oDragHandle.className.indexOf("dragAble") == -1) { ???????????????????oDragHandle = nn6 ? oDragHandle.parentNode : oDragHandle.parentElement; ???????????????} ???????????????if(oDragHandle.className.indexOf("dragAble") != -1) { ???????????????????dragImg.isdrag = true; ???????????????????dragImg.oDragObj = oDragHandle; ???????????????????nTY = parseInt(dragImg.oDragObj.style.top + 0); //当前初始位置 ???????????????????dragImg.clicky = nn6 ? e.clientY : event.clientY; //点击位置 ???????????????????nTX = parseInt(dragImg.oDragObj.style.left + 0); ???????????????????dragImg.clickx = nn6 ? e.clientX : event.clientX; ???????????????????// oDragObj.style.zIndex++; ???????????????????document.onmousemove = moveMouse; ???????????????????return false; ???????????????} ???????????} ???????} ???????function moveMouse(e) { ???????????if(dragImg.isdrag) { //初始位置+运动长度-点击时位置 ???????????????var oevent = e || window.event; ???????????????var clientX = oevent.clientX, ???????????????????clientY = oevent.clientY; ???????????????var moveX = nTX + clientX - dragImg.clickx, ???????????????????moveY = nTY + clientY - dragImg.clicky; ???????????????dragImg.oDragObj.style.top = moveY + "px"; ???????????????dragImg.oDragObj.style.left = moveX + "px"; ???????????????return false; ???????????} ???????} ???}, ???initMouseWheel: function(bgImgId) { //底层图鼠标滚轮缩放 ???????var bg_img = document.getElementById(bgImgId); ???????// ???????if (document.addEventListener) { ???????bg_img.addEventListener(‘mousewheel‘, onWheelZoom, false); //IE9, Chrome, Safari, Oper ???????// ???????????bg_img.addEventListener(‘wheel‘, onWheelZoom, false); //Firefox ???????// ???????????bg_img.addEventListener(‘DOMMouseScroll‘, onWheelZoom, false); //Old Firefox ???????// ???????} else { ???????// ???????????bg_img.attachEvent(‘onmousewheel‘, onWheelZoom); //IE 6/7/8 ???????// ???????} ???????function onWheelZoom(e) { ???????????$(‘.dragBtnSpan‘).remove(); ???????????var obj = e.srcElement ? e.srcElement : e.target; ???????????var parentNode = obj.parentNode || obj; ???????????zoom = parseFloat(parentNode.style.zoom); //操作行内样式zoom,行内必须有zoom属性,不支持firefox ???????????var wheelDelta = event.wheelDelta || event.deltaY; ???????????tZoom = zoom + (wheelDelta > 0 ? 0.1 : -0.1); ???????????if(tZoom < 0.5) { ???????????????return true; ???????????} ???????????parentNode.style.zoom = tZoom; ???????????return false; ???????} ???}, ???getPosition: function(node) { ???????var left = node.offsetLeft; //获取元素相对于其父元素的left值var left ???????var top = node.offsetTop; ???????current = node.offsetParent; // 取得元素的offsetParent ??????? // 一直循环直到根元素 ??????? ???????while(current != null) { ???????????left += current.offsetLeft; ???????????top += current.offsetTop; ???????????current = current.offsetParent; ???????} ???????return { ???????????"left": left, ???????????"top": top ???????}; ???}}
由于ie8和火狐需要更多的兼容性考虑,时间关系就没有支持ie8和火狐。
function IEVersion() { ???var version = -1; ???var userAgent = navigator.userAgent; ???var isIE = userAgent.indexOf(‘compatible‘) > -1 && userAgent.indexOf(‘MSIE‘) > -1; ???var isEdge = userAgent.indexOf(‘Edge‘) > -1 && !isIE; ???var isIE11 = userAgent.indexOf(‘Trident‘) > -1 && userAgent.indexOf(‘rv:11.0‘) > -1; ???if(isIE) { ???????if(userAgent.indexOf("MSIE 5.5") > 0) { ???????????version = 5.5; ???????} else if(userAgent.indexOf("MSIE 6.0") > 0) { ???????????version = 6; ???????} else if(userAgent.indexOf("MSIE 7.0") > 0) { ???????????version = 7; ???????} else if(userAgent.indexOf("MSIE 8.0") > 0 || (userAgent.indexOf("MSIE 9.0") > 0 && !window.innerWidth)) { ???????????version = 8; ???????} else if(userAgent.indexOf("MSIE 9.0") > 0) { ???????????version = 9; ???????} else { ???????????version = 10; ???????} ???} else if(isEdge) { ???????version = ‘Edge‘; ???} else if(isIE11) { ???????version = 11; ???} else { ???????version = -1; ???} ???return version;}
代码写的都很简单,关键位置都有注释,各位不要见笑。
js仿百度地图拖拽、缩放、添加图层功能(原创)
原文地址:https://www.cnblogs.com/cm1236/p/9640628.html