使用OpenLayers3 新增地圖滑鼠右鍵選單_javascript技巧
新增右鍵選單,首先我們要監聽滑鼠右鍵點擊的操作,我們知道滑鼠右鍵事件名稱是contextmenu,當滑鼠在html 元素之上,點擊滑鼠右鍵,便會觸發contextmenu 事件,在contextmenu 事件的回調函數中實現對應的顯示選單功能即可。
那麼在 openlayers 中,在地圖中加入這個事件,我們要從哪裡下手呢?首先我們得了解 openlayers 的初始化頁面的過程。
openlayers 初始化頁面過程
openlayers 也是前端庫,那麼它肯定離不開html 的運用,例如,我們首先需要在頁面放置一個顯示地圖的html 元素,一個div 元素(假設其id 屬性設置為“map”,後面簡稱為map div),然後在地圖初始化的時候指定這個元素,openlayers 會先在這個元素中建立一個class 為ol-viewport 的div 元素,其尺寸保持與map div 相同,然後在ol-viewport div 中建立一個canvas 元素,在這個canvas 元素中渲染要求到的地圖;其次,還會加入一個class 為ol-overlaycontainer 的div 元素,用來放置overlay;最後,增加一個class 為ol-overlaycontainer-stopevent 的div 元素,主要是放置openlayers 的控件,上一篇新增自訂擴充控制項的文章開頭有講過,這裡不是重點,我們不詳細介紹了。
最後形成的 html dom 結構如下圖:
圖1 形成的DOM結構
我們會想到在這個map div 元素中添加事件,然後右鍵彈出選單,這個想法很自然,也確實可以實現,然而我們要想到後面的事情,至少對事情有一個全局的認識再下手,我們顯示出選單後,往往是要根據對應的地圖所在位置進行一定的操作,那麼我們的contextmenu 的事件物件包含發生點擊的螢幕座標,但是如何根據螢幕座標獲得地圖中的對應座標系下的座標將會比較困難。
困難在哪裡呢?主要有以下的三點:
首先,事件物件所含的座標是相對於整個瀏覽器的視窗、頁面或整個螢幕的;
其次,而顯示地圖的元素往往又是隨性的大小和位置;
最後,螢幕的座標系和地圖的座標系又往往完全不同,如何將相對與地圖元素的座標再轉換成地圖座標系下的座標?
首先,我們需要取得事件座標相對於 map div (包含地圖的元素)的座標,然後將相對於 map div 的座標轉換為地圖中的實際座標。在第一步中,我們可以透過計算來獲得,但是第二步必須透過 openlayers 來完成,因為只有 openlayers 對地圖的座標系最清楚,這在 openlayers 中也有相關的功能。慶幸的是,openlayers 中我們可以一步完成上述操作,只需要一個函數:map.getEventCoordinate(event),在下面的具體實作中,我會詳細講到這個函數。
下面我們來看看具體如何實現吧。
滑鼠右鍵選單具體實現
為了方便,文章中的程式碼使用了 JQuery。
文章中的實例完整程式碼可以到我的 GitHub 中查看或下載,有用的話別忘了點一下 star。
下面我們一步一步地加入右鍵選單功能,我們分為三步驟:
對 html 元素新增 contextmenu 事件;
取得地圖對應的點擊座標;
地圖對應位置新增選單 。
對 html 元素加入 contextmenu 事件
html 元素的滑鼠右鍵事件名稱為 contextmenu,這個事件所有主流瀏覽器都支持,這裡不要混淆 html 新增的屬性 contextmenu,這個屬性目前只有 firefox 支持,我們只是使用 oncontextmenu 這個事件。對包含地圖的任何 html 元素綁定這個事件都可以,openlayers 會處理座標轉換這些問題。如下,map.getViewport() 會傳回 openlayers 初始化頁面時所建立的 class 為 ol-viewport 的 div 元素,也就是直接包含地圖的元素。因為瀏覽器都有預設的右鍵選單,所以我們要取消預設的選單,只要呼叫 e.preventDefault(); 即可:
$(map.getViewport()).on("contextmenu", function(event){ e.preventDefault(); // 书写事件触发后的函数 });
取得地圖對應的點擊座標
取得地圖對應的點擊座標只需要一句即可,如下,
var coordinate = map.getEventCoordinate(event);
函数参数是 oncontextmenu 对应的事件对象,该函数包含对 map.getCoordinateFromPixel() 的调用,map.getCoordinateFromPixel() 参数为 ol.pixel,是一个坐标,数组格式[x, y],其实现中又调用了 ol.vec.Mat4.multVec2(),该函数完成处理坐标转换的实际工作。
地图相应位置添加菜单
这里我们结合 overlay 添加菜单,之前的文章介绍过 overlay,这里就不再具体展开了。首先,我们在 html 页面添加一个目录,具体的 css 样式可以自己设定,想看完整源码的可以到我的 GitHub 中查看或者下载完整的代码:
<div id="contextmenu_container" class="contextmenu"> <ul> <li><a href="#">设置中心</a></li> <li><a href="#">添加地标</a></li> <li><a href="#">距离丈量</a></li> </ul> </div>
使用这个 html 元素初始化一个 overlay,并将 overlay 添加到地图中:
var menu_overlay = new ol.Overlay({ element: document.getElementById("contextmenu_container"), positioning: 'center-center' }); menu_overlay.setMap(map);
接下来,我们就可以在鼠标右键菜单的事件回调函数中,根据获取的地图坐标位置,设置 overlay 的显示位置:
menu_overlay.setPosition(coordinate);
菜单隐藏
当我们鼠标点击右键,菜单出现,但是我们不能让菜单总是显示在地图中,这时我们可以添加鼠标左键单击,菜单消失功能,或者当选择某项功能时,菜单消失。这个比较容易实现,只要一句便可以实现,放在鼠标左键事件的回调函数或者菜单功能执行函数中就行,如下:
menu_overlay.setPosition(undefined);
总结
这篇文章中,主要讲了 openlayers 初始化页面地图元素的过程,并介绍了在地图上实现“鼠标右键菜单功能”,和隐藏菜单的实现。我们并没有对菜单中的条目绑定事件,因为我们的重点在于实现右键菜单,对于菜单的条目要绑定什么功能,和普通的 javascript 事件绑定并无二致,所以没有展开。

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

JavaScript是現代Web開發的基石,它的主要功能包括事件驅動編程、動態內容生成和異步編程。 1)事件驅動編程允許網頁根據用戶操作動態變化。 2)動態內容生成使得頁面內容可以根據條件調整。 3)異步編程確保用戶界面不被阻塞。 JavaScript廣泛應用於網頁交互、單頁面應用和服務器端開發,極大地提升了用戶體驗和跨平台開發的靈活性。

JavaScript的最新趨勢包括TypeScript的崛起、現代框架和庫的流行以及WebAssembly的應用。未來前景涵蓋更強大的類型系統、服務器端JavaScript的發展、人工智能和機器學習的擴展以及物聯網和邊緣計算的潛力。

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

JavaScript是現代Web開發的核心語言,因其多樣性和靈活性而廣泛應用。 1)前端開發:通過DOM操作和現代框架(如React、Vue.js、Angular)構建動態網頁和單頁面應用。 2)服務器端開發:Node.js利用非阻塞I/O模型處理高並發和實時應用。 3)移動和桌面應用開發:通過ReactNative和Electron實現跨平台開發,提高開發效率。

本文展示了與許可證確保的後端的前端集成,並使用Next.js構建功能性Edtech SaaS應用程序。 前端獲取用戶權限以控制UI的可見性並確保API要求遵守角色庫

我使用您的日常技術工具構建了功能性的多租戶SaaS應用程序(一個Edtech應用程序),您可以做同樣的事情。 首先,什麼是多租戶SaaS應用程序? 多租戶SaaS應用程序可讓您從唱歌中為多個客戶提供服務

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。
