由于3月可能要结束实习,所以应该不会有特别固定的主题,另外我会在月初陆续补上上个月的番外篇Projection和TMS,作为介绍性的内容对矢量切片部分进行补充,剩下时间不定期写一些杂烩。

  最近两天在做一个地图上popup浮动层的功能,因为之前一直沿用OpenLayers2中自带的popup组件,但OL2中实在是难以控制浮动层的样式,远不及直接在地图上覆盖div布局来的快,所以我决定暂时放弃使用popup,自己编写一个浮动层。

一 问题的来源

  设计草图如下(样式主要参照了百度地图的弹出层),主要讲这个弹出层分为了三级:1)location:地理位置信息和定位;2)images:图片集;3)indexs:指数计算;

  那么,这篇题外讲的就是在实现功能的过程中遇到的一个小问题——图片的缩略图,在这里先简单介绍一下背景和思路:利用OL2中的popup的被选中触发的事件,填充已经隐藏在页面中的POI弹出层,而数据库中存储的是图片的URL,图片存储在服务器上,在填充POI弹出层的图片部分时,直接插入<img>元素,再利用JS部分的功能代码对图片进行重定义大小,最终实现将缩略图显示在我们的页面上。

  PS:其实这算不上是真正意义上的缩略图,因为页面在加载的时候,还是会加载完整的图片,只是显示的时候是以缩略的形式,并不会对页面的加载速度有提升,在此只是为了实现这样一个效果。

  好了,那么问题在哪呢?我们先来看如何实现。

二 实现过程

  2-1)利用HTML和CSS,构建一个demo,并按照设计实现布局

  效果如上,接下来是将图片插入到image栏中,我这里使用的图片都是未经过处理的,所以宽和高比例几乎都不相同,所以需要经过处理才能妥善的放到image栏中。

  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

3月题外:关于JS实现图片缩略图效果的一些小问题的更多相关文章

  1. 3月题外:关于JS实现图片缩略图效果的一个小问题

    由于3月可能要结束实习,所以应该不会有特别固定的主题,另外我会在月初陆续补上上个月的番外篇Projection和TMS,作为介绍性的内容对矢量切片部分进行补充,剩下时间不定期写一些杂烩. 最近两天在做 ...

  2. JS实现图片''推拉门''效果

    JS实现图片''推拉门''效果   ''推拉门''动效也可以称作"手风琴"效果,大多数效果实现的思路基本是一样的,下面介绍两种方法,一种是通过改变图片的偏移位置实现移动,另一种是通 ...

  3. js实现图片局部放大效果

    图片局部放大效果结合的知识点主要是DOM的操作,以及事件的应用,所以首先要对DOM的操作有一定了解,其次能对事件的应用有一定的累积. 如上图,可以看到,这是放大镜的基本效果,主要分成左右两个部分.左边 ...

  4. 3月题外:关于GeoServer和OpenLayers3实用开源插件或组件的总结

    Geoserver篇 注意: 1)用法 GeoServer-Extension的使用方法:将jar包直接放入部署在tomcat上的geoserver/WEB-INF/lib文件夹中 2)在安装插件时, ...

  5. JS中图片飞飞效果

    当鼠标在界面上移动的时候,后面有一连串的图片跟随者一起飘动,效果如下: 实现的基本思想:准备五个img标签,为了方便控制都放在一个div里面,设置div的定位方式为 fixed,设置成这中定位方式主要 ...

  6. js实现图片幻灯片效果

    其效果是点击图片切换到下一张图片 首先准备五张图片 <ul class="imge"> <li><img src="images/1.jpg ...

  7. 使用纯生js实现图片轮换

    效果图预览. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www. ...

  8. lazyload.js实现图片异步载入

    所谓图片异步加载,意思是不用一次把图片全部加载完,你可以叫它延迟加载,缓冲加载都行. 看看你有没有这种需求:某篇文章图片很多,如果在载入文章时就载入所有图片,无疑会延缓载入速度,让用户等更久,所以,我 ...

  9. JS实现有点炫的图片展示效果-图片解体和组合

    经过4个月的努力学习,迎来了进入市场的最后一个学习项目.自己模仿了一个图片展示效果,用在了项目中,感觉挺炫的.在这里分享一下,希望大家喜欢~! bomb-showImg : 在线演示http://ru ...

随机推荐

  1. windows(win10)下的mysql解压版安装

    1. 到mysql官网 下载mysql : http://dev.mysql.com/downloads/mysql/   ,会提示登陆,注册一个就行了,公司名什么的随便填. 注意区分32,64位.我 ...

  2. iOS 专题 之 界面开发 之 控件

    iOS 之 UIViewController iOS 之 Navagation Button iOS 之 UIButton iOS 之 UITextField iOS 之 UIStackView iO ...

  3. OD提示 "为了执行系统不支持的动作, OllyICE 在这个被调试的程序中注入了一点代码, 但是经过5秒仍未收到响应..." 解决办法

    别的OD就可以,我自己整合过的一个很顺手的OD就是不行,最后找到了解决办法: 转自:http://bbs.pediy.com/showthread.PHP?t=97629 -------------- ...

  4. iOS 之 NSString 去除前后空格和回车键

    NSString *string = @" spaces in front and at the end "; NSString *trimmedString = [string ...

  5. 淘宝的数据库拆分(TDDL)(转)

    淘宝的数据拆分历程 系 统刚开始的时候,因为系统刚上线,用户不多,那个时候,所有的数据都放在了同一个数据库中,这个时候因为用户少压力小,一个数据库完全可以应付的了,但是 随着运营那些哥们辛苦的呐喊和拼 ...

  6. CNTV视频回看下载地址

    这其实不是新方法了,这个方法早在五六年前大家就在用,至今也没失效.但是五六年前那时候这个方法可以下载到过去三个月内CNTV直播过的视频,而现在只能下到一个星期的.之所以要下载回看版本,是因为比栏目版本 ...

  7. 用JS的数组缓存一些东西

    var cache_index = new Array(); //首页的ajax缓存 //ajax 推荐的游戏和软件 function change_tuijian(sid,div_class){ i ...

  8. 编写快速、高效的JavaScript代码

    许多Javascript引擎都是为了快速运行大型的JavaScript程序而特别设 计的,例如Google的V8引擎(Chrome浏览器,Node均使用该引擎).在开发过程中,如果你关心你程序的内存和 ...

  9. iOS 之 alcatraz (插件管理器)

    1. 安装 1.1. 打开命令行 curl -fsSL https://raw.githubusercontent.com/supermarin/Alcatraz/deploy/Scripts/ins ...

  10. Android事件处理概述

    不管是桌面应用还是手机应用程序,面对最多的就是用户,经常需要处理的就是用户的动作——也就是需要为用户动作提供响应,这种为用户动作提供响应的机制就是事件处理. Android提供了强大的事件处理机制,包 ...