因爲3月可能要結束實習,因此應該不會有特別固定的主題,另外我會在月初陸續補上上個月的番外篇Projection和TMS,做爲介紹性的內容對矢量切片部分進行補充,剩下時間不按期寫一些雜燴。html
最近兩天在作一個地圖上popup浮動層的功能,由於以前一直沿用OpenLayers2中自帶的popup組件,但OL2中實在是難以控制浮動層的樣式,遠不及直接在地圖上覆蓋div佈局來的快,因此我決定暫時放棄使用popup,本身編寫一個浮動層。數據庫
一 問題的來源服務器
設計草圖以下(樣式主要參照了百度地圖的彈出層),主要講這個彈出層分爲了三級:1)location:地理位置信息和定位;2)images:圖片集;3)indexs:指數計算;網絡
那麼,這篇題外講的就是在實現功能的過程當中遇到的一個小問題——圖片的縮略圖,在這裏先簡單介紹一下背景和思路:利用OL2中的popup的被選中觸發的事件,填充已經隱藏在頁面中的POI彈出層,而數據庫中存儲的是圖片的URL,圖片存儲在服務器上,在填充POI彈出層的圖片部分時,直接插入<img>元素,再利用JS部分的功能代碼對圖片進行重定義大小,最終實現將縮略圖顯示在咱們的頁面上。dom
PS:其實這算不上是真正意義上的縮略圖,由於頁面在加載的時候,仍是會加載完整的圖片,只是顯示的時候是以縮略的形式,並不會對頁面的加載速度有提高,在此只是爲了實現這樣一個效果。函數
好了,那麼問題在哪呢?咱們先來看如何實現。佈局
二 實現過程spa
2-1)利用HTML和CSS,構建一個demo,並按照設計實現佈局設計
效果如上,接下來是將圖片插入到image欄中,我這裏使用的圖片都是未通過處理的,因此寬和高比例幾乎都不相同,因此須要通過處理才能妥善的放到image欄中。3d
2-2)處理圖片的尺寸(Resize)
下面這段代碼是網絡上很常見的代碼,當你搜索"JS"、"縮略圖"等關鍵字的時候,十有八九會出現這樣一段代碼:
//從新定義img的寬和高
//參數:orginalImage<目標圖片的DOM元素>、newWidth<圖片元素的容器寬度>、newHeight<圖片元素的容器高度>
function reSizeImage(orginalImage, newWidth, newHeight){
var image = new Image(); image.src = orginalImage.src if(image.width > 0 && image.height > 0){
//判斷圖片的縱橫比 if(image.width/image.height >= newWidth/newHeight){ //當源圖的寬度大於重定義尺寸的寬度時,應壓縮高度 if(image.width > newWidth){ orginalImage.width = newWidth; orginalImage.height = (image.height*newWidth)/image.width; }else{
//當寬度小於或等於重定義寬度時,圖片徹底顯示 orginalImage.width =image.width ; orginalImage.height = image.height; } }else{
//同理 if(image.height > newHeight){ orginalImage.height = newHeight; orginalImage.width = (image.width*newHeight)/image.height; }else{ orginalImage.width = image.width; orginalImage.height = image.height; } } } }
固然,可能細節上會有出入,可是大致思路是一致的,既然有人造好了輪子,那還能有什麼問題呢?
在實現過程當中,將這個功能函數應用到某個場景中(以我剛纔上文提到的彈出層爲例):
function createPOIDetail(monitSiteName,monitLon,monitlat,locationStr,imageURL,Species,Yvalue){ //填充個人彈出層HTML模板 $("#poi_monitsitename").text(monitSiteName); $("#poi_monitsitelonandlat").text(monitLon +"° E,"+ monitlat+"° N"); $("#poi_location").html("<img src='images/markList_smallsize_opacity0.png' style='width:15px;height:12px;'>"+ "<a class='a_text' href='' style='font-size:11px; color:#FFFFF'>"+locationStr+"</a>"); $("#poi_images").html(imageURL); $("#poi_dominacespecie").text(Species); $("#poi_dominaceYValue").text(Yvalue); $("#poi_detail_panel").fadeIn(800); //對彈出層模板中已經插入的圖片進行resize var orginalIMG = document.getElementById("imageFrame"); var newWidth = $("#poi_images").width(); var newHeight = $("#poi_images").height() reSizeImage(orginalIMG,newWidth,newHeight); }
每次觸發這個函數的時候,咱們預期的效果是,在Image欄裏出現一個大小適應的縮略圖,但奇怪的是,當第一次進入頁面,觸發該函數時,reSizeImage方法都沒有執行,直接插入了真實大小的圖片,致使整個彈出層變形(以下圖所示)。
彈出層變形 彈出層正常
但每每在第二次,第三次觸發該函數的時候,彈出層又正常了,真的很奇怪!
三 問題定位
從邏輯上看,代碼應該沒有明顯的錯誤,利用Firebug中的斷點跟蹤以後發現,第一次觸發函數,並無進入reSizeImage的if(image.width > 0 && image.height > 0)這個分支裏,咱們可使用console.log去查看當時插入的<img>元素的寬和高,你會發現,第一次觸發的時候插入的<img>元素的寬高都是0,可是<img>元素也都插入成功了,而且能看到src等屬性都是有值的。那爲何一個有src的<img>元素會不存在寬高呢?
其實問題很簡單,在網頁的加載過程當中,圖片的加載是最後才進行的,因此,雖然此時<img>不空,且已經有了src的屬性值,可是圖片自己尚未加載進來,因此致使了你的代碼沒法順利的進入resize的過程。
四 解決
知道了問題在哪,那解決方案也很簡單,只要咱們將reSizeImage函數放到目標圖片加載完成以後再執行就能夠了,也就是說:
var orginalIMG = document.getElementById("imageFrame");
var newWidth = $("#poi_images").width();
var newHeight = $("#poi_images").height()
orginalIMG.onload = function(){ reSizeImage(orginalIMG,newWidth,newHeight); }
這樣一來,你就能保證每次頁面加載完成後,觸發相應的函數就可以獲得一個通過resize後的圖片了!
參考博客:《img.width一直是0》:http://www.cnblogs.com/zqzjs/p/4512988.html