1. 程式人生 > >js仿百度地圖拖拽、縮放、添加圖層功能(原創)

js仿百度地圖拖拽、縮放、添加圖層功能(原創)

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();
8 }); 9 document.getElementById(‘warp‘).oncontextmenu = function(e){ 10 e.preventDefault(); 11 }; 12 var dragDemo=new dragImg(‘block1‘,‘dragImg‘,‘wheelImg‘);
View Code

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 }; } }
View Code

由於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仿百度地圖拖拽、縮放、添加圖層功能(原創)