ie图片上传滤镜.docx

上传人:b****8 文档编号:28482526 上传时间:2023-07-14 格式:DOCX 页数:16 大小:23.17KB
下载 相关 举报
ie图片上传滤镜.docx_第1页
第1页 / 共16页
ie图片上传滤镜.docx_第2页
第2页 / 共16页
ie图片上传滤镜.docx_第3页
第3页 / 共16页
ie图片上传滤镜.docx_第4页
第4页 / 共16页
ie图片上传滤镜.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

ie图片上传滤镜.docx

《ie图片上传滤镜.docx》由会员分享,可在线阅读,更多相关《ie图片上传滤镜.docx(16页珍藏版)》请在冰豆网上搜索。

ie图片上传滤镜.docx

ie图片上传滤镜

图片上传预览是一种在图片上传之前对图片进行本地预览的技术。

使用户选择图片后能立即查看图片,而不需上传服务器,提高用户体验。

但随着浏览器安全性的提高,要实现图片上传预览也越来越困难。

不过群众的智慧是无限的,网上已经有很多变通或先进的方法来实现。

例如ie7/ie8的滤镜预览法,firefox3的getAsDataURL方法。

但在opera、safari和chrome还是没有办法实现本地预览,只能通过后台来支持预览。

【基本原理】

图片预览主要包括两个部分:

从file表单控件获取图像数据,根据数据显示预览图像。

程序的file和img属性就是用来保存file控件和显示预览图像的容器的,而img还必须是img元素。

程序有以下几种预览方式:

simple模式:

直接从file的value获取图片路径来显示预览,适用于ie6;

filter模式:

通过selection获取file的图片路径,再用滤镜来显示预览,适用于ie7/8;

domfile模式:

调用file的getAsDataURL方法获取DataURI数据来显示预览,适用于ff3;

remote模式:

最后的办法,把file提交后台处理后返回图片数据来显示预览,全适用。

程序定义时就自动根据浏览器设置MODE属性:

如果用能力检测会比较麻烦,所以只用了浏览器检测。

由于浏览器对应的默认模式是不会变的,这个值会保存到函数属性中作为公用属性。

【获取数据】

调用preview方法,就会执行预览程序:

在通过检测后,再调用_getData获取数据,并作为_preview的参数进入下一步。

程序初始化时就会根据mode来设置_getData数据获取程序:

在_getDataFun里面,根据mode返回数据获取程序:

代码

switchcase"filter"returnthiscase"domfile"returnthiscase"remote"returnthiscase"simple"defaultreturnthis

不同的模式有不同的数据获取程序:

滤镜数据获取程序:

一般用在ie7/8,在file控件select后再通过selection对象获得文件本地路径。

此时file控件不能隐藏,否则不能被select,不过一般能选择文件就肯定能被select了。

确实要隐藏也可以在获取数据之后再隐藏。

domfile数据获取程序:

用getAsDataURL从file控件获取数据,这个方法暂时只有ff3支持。

远程数据获取程序:

用_upload上传文件对象把数据提交后台,根据返回的数据再显示。

这个方法不属于本地预览,是没有办法中的办法。

一般数据获取程序:

最原始的方法,现在只有ie6还支持从file的value直接获取本地路径。

获取数据后,作为_preview预览程序的参数,再进行处理:

首先排除空值或相同值的情况,再执行_show程序进行显示预览,其中_data属性用来保存当前的图片数据。

图片使用DataURI数据时可能会设置一个很大的src值,在ie8获取很大的src值会出现“无效指针”的错误。

使用_data属性保存这个值可以避免从src取值而触发这个错误。

远程数据获取程序没有返回值,因为它需要等待返回数据,在_preview中会自动排除。

【显示预览】

程序初始化时就会根据mode来设置_show预览显示程序:

除了filter模式,都是使用_simpleShow显示程序来显示预览图片的。

里面会先调用_simplePreload方法设置一般预载图片对象:

代码

预载图片对象保存在_preload属性中,主要用来判断图像能否加载成功并获取图片原始尺寸。

要实现这些功能使用Image对象就足够了。

在onload中执行_imgShow显示预览,在onerror中进行出错处理。

ps:

ff、chrome和safari的图片对象还有naturalHeight和naturalWidth属性可以获取图片的原始尺寸,即使图片尺寸已经修改过。

这里要注意ie6/7的gif图片载入bug,测试以下代码:

代码

一般图片执行一次onload后并不会重复执行,但ie6/7的gif每次循环播放都会执行一次onload。

ps:

ie8在非标准(怪辟)模式下也有相同的问题。

可以在onload的时候,判断complete是否为false来判断是否重复加载。

ps:

除了ie,其他浏览器在onload时complete就已经为true了。

问题是选择另一个图片时这个complete仍然是true,这样就没有意义了。

所以只好在onload里面重置onload为null,并在每次选择文件重设onload了。

然后设置_preload的src预载图片,如果成功预载就会执行_imgShow显示预览。

要注意src的设置要在onload/onerror的设置之后,否则设置之前就加载完成的话就触发不了事件了。

_imgShow需要三个参数,包括要预览图片的src值,图片原始宽度和图片原始高度。

在_imgShow里面首先设置预览图片的尺寸:

代码

这里的关键是获取ratio比例值,如果自定义的ratio大于0就直接使用自定义的比例,否则就根据参数自动计算。

自动计算首先要确保maxWidth最大宽度和maxHeight最大高度大于等于0。

然后分别跟原始宽高做“/”运算得到比例,如果比例为0表示不限制,那么比例就自动改为1。

最后取比较小的比例来计算,程序设定了比例最大值为1,这样就不会自动放大图片了。

当然比例的计算可以根据需要自行修改。

ps:

style的优先级比属性(width/height)高,所以要用style设置。

最后设置img的src就可以实现预览了。

【remote模式】

remote模式会先提交file控件到后台,通过返回的数据来显示图片。

它跟其他模式最大的区别就是获取数据的部分。

在_remoteData远程数据获取程序中,会调用_setUpload来设置上传文件对象。

如果设置了action,并存在QuickUpload函数,就会实例化一个上传文件对象保存到_upload中:

代码

这里使用的QuickUpload就是简便无刷新文件上传程序。

在onReady中设置参数,在onFinish中处理返回数据,onTimeout进行出错处理。

返回的数据可以是图片的地址或对应的DataURI数据,然后给_preview处理。

当然针对不同的后台输出,数据处理的方式也不同,可以按照需要修改。

后台最好先根据传递的参数缩小图片,尽量减少返回数据来提高预览速度。

【filter模式】

filter模式在_filterData程序中得到文件本地路径,但ie7/8都不允许直接使用本地路径显示图片。

不过还是可以通过滤镜,用本地路径来做预览图片效果。

filter模式使用_filterShow方法来显示预览图片。

里面先调用_filterPreload方法来设置滤镜预载图片对象。

跟一般预载图片对象不同,滤镜预载对象是用滤镜来显示图片,所以并不一定要图像元素。

程序就使用了div元素作为滤镜预载对象:

代码

在样式设置中隐藏元素并添加滤镜,要使滤镜生效width和height必须设置一个值。

由于要获取尺寸,只能用visibility来隐藏并插入body,关于AlphaImageLoader滤镜后面再介绍。

然后在_filterShow中预载图片:

?

成功的话,再给img载入图片:

注意,如果路径中有“)”,“%”这类字符的话,直接拼接到滤镜字符串中会出现类似sql注入的问题。

程序会先对这些敏感字符进行escape编码:

为什么要做两次escape编码呢?

测试时发现“%”只转一次的话,遇到“%40”之类的字符时还是会出问题。

所以我推测,字符在使用前会进行两次unescape解码,于是对应的做两次escape编码果然没问题了。

虽然预载对象是直接设置滤镜的src属性,但也有“%”的拼接字问题,所以也要escape编码。

ps:

虽然单引号和双引号这里并不是必要,还是一起替换掉安心点。

最后调用_imgShow设置尺寸:

【AlphaImageLoader滤镜】

sizingMethod有三种方式:

crop:

剪切图片以适应对象尺寸;

image:

默认值。

增大或减小对象的尺寸边界以适应图片的尺寸;

scale:

缩放图片以适应对象的尺寸边界。

预载图片对象_preload,需要获取图片的原始尺寸,所以要用image方式。

而预览图片对象img,则要按设定尺寸显示图片,所以要用scale方式。

而src属性设置的路径还支持本地路径,是实现filter模式的关键所在。

还好滤镜并没有像file控件那样提高安全性,否则ie7/8就没有办法实现本地预览了。

注:

语法:

属性:

enabled:

 可选项。

布尔值(Boolean)。

设置或检索滤镜是否激活。

true|falsetrue:

 默认值。

滤镜激活。

false:

 滤镜被禁止。

sizingMethod:

 可选项。

字符串(String)。

设置或检索滤镜作用的对象的图片在对象容器边界内的显示方式。

crop:

 剪切图片以适应对象尺寸。

image:

 默认值。

增大或减小对象的尺寸边界以适应图片的尺寸。

scale:

 缩放图片以适应对象的尺寸边界。

src:

 必选项。

字符串(String)。

使用绝对或相对url地址指定背景图像。

假如忽略此参数,滤镜将不会作用。

特性:

Enabled:

 可读写。

布尔值(Boolean)。

参阅enabled属性。

sizingMethod:

 可读写。

字符串(String)。

参阅sizingMethod属性。

src:

 可读写。

字符串(String)。

参阅src属性。

说明:

在对象容器边界内,在对象的背景和内容之间显示一张图片。

并提供对此图片的剪切和改变尺寸的操作。

如果载入的是PNG(PortableNetworkGraphics)格式,则0%-100%的透明度也被提供。

PNG(PortableNetworkGraphics)格式的图片的透明度不妨碍你选择文本。

也就是说,你可以选择显示在PNG(PortableNetworkGraphics)格式的图片完全透明区域后面的内容。

示例:

Example:

引用:

最后说说关于FF和IE效果调和问题。

这个滤镜效果只适用于IE,在FF下面无法显示,我想这是前辈说他很难实现的最终问题了。

以往我们用*或者_来修复IE下和FF的区别.这一次是要找方法修复FF不能实现的问题.

其实想到的话,也很简单了.就是先让FF正常显示该图片,然后,用*或_来清除IE下的显示效果,最后用*或_来做以上的滤镜效果。

大功告成!

以上是官方的说明。

事实上实际操作中需要注意:

AlphaImageLoader滤镜会导致该区域的链接和按钮无效,一般情况下的解决办法是为链接或按钮添加:

position:

relative使其相对浮动要注意的是,当加载滤镜的区域的父层有position:

absolute绝对定位的时候使用position:

relative也不能使链接复原。

建议使用浮动办法处理。

具体操作:

为AlphaImageLoader设置src属性。

--ThisDIVisthetargetcontainerfortheimage.-->

relative;height:

250px;width:

250px;


MakeNormal

【nsIDOMFile接口】

这个File对象有三个获取文件数据的方法:

getAsText:

获取文件的文本数据,可以通过参数设置编码;

getAsDataURL:

获取文件的DataURI(URL)数据;

getAsBinary:

获取文件的二进制数据。

其中getAsDataURL获得的DataURI数据可以用于显示图片,_domfileData中就是用它来获取数据的。

File对象还支持两个属性:

fileName(文件名,不包括路径)和fileSize(文件大小)。

相关具体说明参考mozilla的File和nsIDOMFile。

【DataURI和MHTML】

上面已经多次提到DataURI,详细介绍请看秦歌的“DataURI和MHTML”。

DataURI的主要作用是以字符代替数据,从而把文件“嵌”在代码里。

除了ie,其他浏览器基本都很好的支持了DataURI。

ie8也有限度地支持,详细参考msdn的dataProtocol。

由于opera,safari和chrome需要remote模式的浏览器都支持DataURI,所以程序返回的是DataURI形式的数据。

相比返回路径的方法,返回DataURI不需要创建文件,还少一次HTTP请求。

ps:

ie8只支持32k的DataURI数据,在ie8使用时要注意数据大小。

在filter模式需要一个透明图片来去掉img默认显示的小图标,一般的方法需要一个图片文件。

为了“省下”这个文件,可以使用DataURI来做一个1*1的透明图片:

data:

image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==

支持DataURI的情况下,只要把img的src设置为这个值就可以显示一个透明图片了。

代码

Content-Type:

?

multipart/related;?

boundary="_CLOUDGAMER"

----Transfer-Encoding:

base64

R0lGODlhAQABAJEAAAAAAP///////wAAACH5BAEAAAIALAAAAAABAAEAAAICVAEAOw==

其中boundary的值是分隔符标识,说明用于分隔数据段的字符。

Content-Location说明关联引用位置,可以用作数据段的标识。

Content-Transfer-Encoding就是字符编码形式。

后面的代码就是1*1的透明图片的base64编码数据。

然后在代码中这样调用(例如设置img元素的src属性):

mhtml:

文件完整路径!

blankImage

就可以链接到一个透明图片了。

接着可以利用getAttribute从src获取script的完整路径:

ie6/7的getAttribute支持第二个参数,设为4表示返回完整路径的url地址,详细参考msdn的getAttributeMethod。

结合DataURI和MHTML可以这样得到透明图片数据:

?

使用时要注意:

脚本必须单独另存为一个文件,作为mhtml需要的文件路径。

要自动获取完整路径需要用script标签链接文件。

【超空间】

程序还有一个dispose方法用于销毁程序。

包括这几个部分:

_upload上传文件对象:

它本身已经有一个dispose方法来销毁程序;

_preload预载图片对象:

先清除它的onload/onerror事件再移除元素;

file和img属性:

直接设为null,由于不是程序创建的元素,留给使用者来移除。

说到移除元素,顺便说一下超空间(DOMhyperspace),这是从“ppk谈javascript”中看到的。

大概指的是当元素不在dom里面,而js又有关联时,元素并不会消失,而是保存在一个称为“超空间”的地方。

详细参考书的DOM超空间部分。

书中还说可以根据是否有parentNode来判断元素是否在超空间,但测试以下代码:

第一次parentNode都是null,没有问题,按理第二次也应该是null,但ie却是一个object。

经测试,这个object的nodeType是11,也就是一个碎片对象(FRAGMENT)。

而且各个被removeChild移除的元素的parentNode都不相同,即会生成不同的碎片对象。

这种情况算不算在“超空间”呢,不过书中也只是说“一般来说”,也不用太考究。

那么用innerHTML清除呢?

再测试以下代码:

结果在ie也是null了,看来removeChild和innerHTML在清除元素时产生了不同的结果。

那个碎片对象貌似没什么用(难道为了保证有parentNode?

),那是不是innerHTML就一定比removeChild好呢?

再测试以下代码:

代码

当使用removeChild时,移除元素的结构并没有发生变化,各个浏览器的效果都一样。

而使用innerHTML清除时,其他浏览器的效果跟removeChild一样,但在ie被移除的元素就只剩下一个“外壳”了。

个人推测,ie在使用innerHTML时,被移除的元素会变成一个个单独的元素,失去了彼此的联系。

形象点说就是removeChild是直接掰断树枝,还能继续嫁接使用,而innerHTML是把需要的树叶节点取下来,再把树枝烧掉。

ps:

仅仅是推测,谁有官方资料请告诉我。

那么removeChild的好处是移除的元素能再次使用,兼容性好,不好的地方是ie会产生一个没用的碎片对象。

而innerHTML的好处是不会产生多余的碎片对象,方便高效,但在ie被移除的元素基本不能再用,有兼容性问题。

那就可以根据需要使用不同的方法了,至于防止内存泄漏用那个好,感觉是innerHTML,但没有更深入研究的话还说不清楚。

使用技巧

一般来preview方法都是在onchange中调用,即选择文件后立即显示预览。

在不需要程序时最好执行一次dispose方法来销毁程序,防止内存泄漏等。

第二个实例中的ResetFile是用来重置file控件的,详细参考这里file的reset。

而file控件样式设置详细参考这里的file样式。

使用说明

实例化时,有两个必要参数,分别是file控件对象和img元素的预览显示对象:

new?

ImagePreview(?

file,?

img?

);

还提供了以下方法:

preview:

执行预览操作;

dispose:

销毁程序。

程序源码

代码

兼容ie和ff的图片上传预览代码

Firefox3,IE6,IE7,IE8上传图片预览

styletype="text/css">

--

#preview_wrapper{

display:

inline-block;

width:

300px;

height:

300px;

background-color:

#CCC;

}

#preview_fake{/*该对象用户在IE下显示预览图片*/

}

#preview_size_fake{/*该对象只用来在IE下获得图片的原始尺寸,无其它用途*/

visibility:

hidden;

}

#preview{/*该对象用户在FF下显示预览图片*/

width:

300px;

height:

300px;

}

-->

style>

#preview_wrapper{

display:

inline-block;

width:

300px;

height:

300px;

background-color:

#CCC;

}

#preview_fake{/*该对象用户在IE下显示预览图片*/

}

#preview_size_fake{/*该对象只用来在IE下获得图片的原始尺寸,无其它用途*/

visibility:

hidden;

}

#preview{/*该对象用户在FF下显示预览图片*/

width:

300px;

height:

300px;

}

functiononUploadImgChange(sender){

alert('图片格式无效!

');

returnfalse;

}

//(相同环境有时能显示,有时不显示),因此只能用滤镜来解决

autoSizePreview(objPreviewFake,

}

}

functiononPreviewLoad(sender){

}

functionautoSizePreview(objPre,originalWidth,originalHeight){

varzoomParam=clacImgZoomParam(300,300,originalWidth,originalHeight);

}

functionclacImgZoomParam(maxWidth,maxHeight,width,height){

varparam={width:

width,height:

height,top:

0,left:

0};

if(width>maxWidth||height>maxHeight){

rateWidth=width/maxWidth;

rateHeight=height/maxHeight;

if(rateWidth>rateHeight){

}else{

}

}

returnparam;

}



展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 初中教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1