天天看點

OpenLayers 3 之 使用 AJAX 通信0. 摘要1. 什麼是AJAX ,什麼作用2. 添加查詢元件3. 整合 AJAX 和查詢元件4. 總結5. 附錄代碼下載下傳

0. 摘要

地圖應用是大流量應用,如果頻繁重新整理頁面,造成的資料傳輸也必然是很大的,這在你的網絡不是很好的時候,你就醉了,這時候便是 AJAX 顯現優勢的時候了。這裡我們把 AJAX 應用在地圖搜尋中,下面看看怎麼做到的吧!

當然,AJAX 在執行的時候,如果網絡不好,同樣會讓使用者感到點選了觸發 AJAX 的按鈕,卻沒有反應!是以可以在處理過程中,添加一個進度條。現實項目中,要根據情況選擇最合适項目的技術,是業務驅動技術,而不是反過來!

1. 什麼是AJAX ,什麼作用

AJAX,全稱是Asynchronous JavaScript + XML,它可以向伺服器請求額外的資料而無需解除安裝頁面,帶來更好的使用者體驗。雖然名字中包含XML,但是AJAX的通信實際上與資料格式無關,這種技術就是無需重新整理頁面即可從伺服器取得資料,但不一定是XML資料。

使用AJAX不僅要處理浏覽器的相容問題,還要處理與伺服器通信過程中的狀态變化問題。為了避免這些繁雜的與事務無關的事情,使用一種架構來處理這些繁雜的事情,很有必要,JQuery等很多架構都可以做到。

2. 添加查詢元件

我們可能想給系統加上查詢地理事物的功能,而前面我們提到最好是在不重新整理的情況下進行查詢和結果展示,這裡便是一個AJAX技術很好的應用點!首先我們要在HTML檔案中添加搜尋框,然後在JS檔案中編寫點選按鈕的事件,事件進行中便包含一些AJAX技術,用來查詢資料庫。

2.1 在 map.html 添加搜尋框

<div id="search_group" class="search_group">
    <input id="search_input" class="search_input">
    <button id="search_button" class="search_button" type="button">搜尋!</button>
</div>
           

這段代碼加入到 id 為”map”的 div 裡邊,讓其為第一個子元素。這裡每個元素都有兩個屬性:id 和 class ,id 是為了使用 JavaScript 取用使用者輸入文字的(getElementById), class 是 css 類,定義了相應元素的外觀。

2.2 在 map_style.css 添加搜尋框樣式

我們不在元素内部直接寫 style ,是為了代碼容易維護,如果元素外觀顯示不正确或者需要修改,可以直接在 css 檔案直接修改,不用在 HTML中查找,這樣有利于内容(HTML)、外觀(CSS)和行為(JavaScript)的解耦,最終提高代碼的可維護性。

在 map_style.css 中添加的内容如下:

/**
   * search group css
   */
  .search_group, .search_input, .search_button{
    position:absolute;
    z-index: ;
    top: px;
  }  
  .search_input{
    width:px;
    height:px;
    left:px;
  }  
  .search_button{
    width:px;
    height:px;
    left:px;
  }
           

這裡我們使用了絕對定位: position: absolute; ,這是相對于第一個父元素的定位,這裡是 body 元素,這種定位方式使用 left、right、top 和 bottom來進行定位。這種定位方式的元素是浮動的,不影響其它元素的位置,這樣我們才能将搜尋框覆寫在地圖之上,而不會擠掉地圖的一行位置。

我們可以比較一下注釋掉 position: absolute; 這句,比對一下結果:

OpenLayers 3 之 使用 AJAX 通信0. 摘要1. 什麼是AJAX ,什麼作用2. 添加查詢元件3. 整合 AJAX 和查詢元件4. 總結5. 附錄代碼下載下傳

– 圖1 注釋之前

OpenLayers 3 之 使用 AJAX 通信0. 摘要1. 什麼是AJAX ,什麼作用2. 添加查詢元件3. 整合 AJAX 和查詢元件4. 總結5. 附錄代碼下載下傳

– 圖2 注釋之後

一個是浮動,一個是并排!

3. 整合 AJAX 和查詢元件

為了避免處理浏覽器間的相容問題,也為了簡化代碼,我們使用 JQuery 提供的 AJAX 元件。

3.1 在map_utils.js 中添加處理事件

首先擷取 button,然後注冊 button 的 click 事件,click 事件是發送 AJAX 請求。添加的代碼如下:

/**
 * 處理使用者點選搜尋按鈕的事件
 * 擷取輸入,如果為空,什麼都不做;如果不為空,首先檢查輸入,然後發送AJAX請求(使用JQuery)
 */
 function sendQuery(){
     var search_input = document.getElementById("search_input").value;
     $.ajax({
         url: "http://127.0.0.1/csdn_blog_about/getQueryData.php?search_input=" + search_input,
         success: function(result){
             var jsonResult = JSON.parse(result);
             //do something 
         }
     });
 }

 var search_button = document.getElementById("search_button");
 search_button.onclick = sendQuery;
           

這時候,當點選按鈕時候,就會發送 AJAX 請求,并将傳回的資料解析成 JavaScript 的對象,然後進行操作!

這裡特别指出一點,AJAX 是不能跨域的,也就是說, AJAX 接受請求的檔案位址必須和 送出請求的位址是同一個域名下的!這一點非常重要,即使是本地的檔案系統,如:“D://map.html”請求本機如 “127.0.0.1/getQueryData.php” 也是不能請求成功的。必須将 map.html 和 getQueryData 放于一個 web 目錄下,但并一定在一個子檔案夾内。

例如,我讓 getQueryData.php 傳回的是一個 GeoJSON 字元串,其中包含 name、content 和坐标等屬性,這樣我們可以首先獲得搜尋的結果的坐标值,然後平移到相應的位置,然後再在相應位置彈出一個 Popup,顯示搜尋結果的 name 等屬性。

/**
 * 根據傳來的參數,平移到相應坐标,然後展示相應内容
 * 參數為 name(搜尋結果的名稱),content(搜尋結果的内容),coordinates(搜尋結果的坐标)
 */
 function zoomAndDisplay(name, content2, coordinates){
     try{
        //zoomTo(coordinates);
        var view = new ol.View({
          center: ol.proj.transform(coordinates, 'EPSG:4326', 'EPSG:3857'),
          zoom: 
        });
        map.setView(view);
        //display [name, content]
        content.innerHTML = '<p>名稱:<code>' + name + '</code></p><p>内容:'+ content2 + '</p>';
        var crd = ol.proj.transform(coordinates, 'EPSG:4326', 'EPSG:3857');
        overlay.setPosition(crd);
        map.addOverlay(overlay);
     }
     catch(ex){
         console.log(ex.message);
     }
 }
           

将這段函數定義放于 map_utils.js 中,然後再在 sendQuery 函數中調用此函數。此處要注意,我刻意将兩個函數分開,其實是可以寫在一起的,why? 其實是為了“解耦應用邏輯 / 事件處理程式”,這麼做首先,可以讓你更容易更改觸發特定過程的事件,如将原來滑鼠觸發的事件,現在添加鍵盤觸發;其次,可以在不附加到事件的情況下測試代碼,使其更容易建立單元測試或者是自動化應用流程!

最後,結果是這樣的!

OpenLayers 3 之 使用 AJAX 通信0. 摘要1. 什麼是AJAX ,什麼作用2. 添加查詢元件3. 整合 AJAX 和查詢元件4. 總結5. 附錄代碼下載下傳

圖3 點選之前

OpenLayers 3 之 使用 AJAX 通信0. 摘要1. 什麼是AJAX ,什麼作用2. 添加查詢元件3. 整合 AJAX 和查詢元件4. 總結5. 附錄代碼下載下傳

圖4 輸入并點選之後

3.2 關于投影坐标系

注意 OpenLayers 的

new ol.source.MapQuest({layer: 'sat'})

這個圖層的預設投影坐标系是

'EPSG:3857'

, 而一般我們用的比較廣泛的是

'EPSG:4326'

,也就是傳說中的

WGS84

坐标系。

是以當使用

map.setView(view)

overlay.setPosition(coordinate)

時候,要注意将我們使用的坐标轉換到相應的參考系之下:

ol.proj.transform(coordinates, 'EPSG:4326', 'EPSG:3857');

4. 總結

前面提到,AJAX 相對于傳統的表單送出,省去了重新整理網頁,但是在發送和接受結果時候,頁面沒有任何變化,如果網速很慢或者處理事件很長,很容易造成使用者誤解,以為 AJAX 請求并沒有發生。是以,實際項目中,我們應該添加一些動畫等效果,提示使用者正在進行中,無需重複點按等。

将 HTML、CSS 和 JavaScript 解耦,不僅有利于錯誤發生時,錯誤的快速定位;而且有利于項目日後的維護。是以應該注意程式的可維護性和可擴充性,同時良好的注釋和變量命名,更增加了代碼的可讀性,變量命名沒有必要擔心長度,因為長度問題可以通過後處理和壓縮來緩解。

AJAX 用在地圖等重新整理代價很大,或者 web 應用程式模拟桌面應用程式時非常優雅。

5. 附錄代碼下載下傳

5.1 下載下傳連結

點選源碼下載下傳連結進行下載下傳, 我把代碼放在百度雲盤裡邊了。

5.2 說明

代碼正常運作必須有的先決條件:

1、php 檔案必須和 js 檔案放于一個域名下面,也就是伺服器指定的 web 路徑下面,不要求一個子檔案夾。主要是 AJAX 的安全性限制,不能跨域通路;

2、要求伺服器是 Apache httpd 或者 IIS 附加 php 擴充,也就是說要支援 php;

3、考慮簡化樣式代碼,處理浏覽器樣式相容問題,我們以後可能使用 bootstrap 來開發,這篇文章肯能沒有用到,但是以後可能會用到;

4、文中用到了 JQuery 庫,是以檔案中要引用該庫;

5、代碼連結中以上的 bootstrap 和 JQuery 都已經包含!

繼續閱讀