js仿百度地圖拖拽、縮放、添加圖層功能(原創)
阿新 • • 發佈:2018-09-13
ets tle clas 火狐 相對 inner tlist posit css
最近項目中完成的需求,仿百度地圖中的功能:
要求: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();View Code8 }); 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) {View Codethis.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; }View Code
代碼寫的都很簡單,關鍵位置都有註釋,各位不要見笑。
js仿百度地圖拖拽、縮放、添加圖層功能(原創)