Category Archives: JavaScript

HTML JavaScript 前端

本地图片预览及大小获取

内容涉及范围:使用input file选择图片后,在不提交至服务器的情况下,预览选择的图片,获取图片文件的大小。

先说一些结论,在默认设置的情况下,ie6和firefox6可以预览和获取大小;ie7-9只能预览;chrome13只能获取大小。只能预览或只能获取大小的,很大程度上都是由浏览器的安全策略造成的。

接下来是一些详情,

html代码:

<input id=”file” type=”file”" />
<div id=”div”>
<img id=”img” />
</div>

各浏览器图片预览及大小获得:

浏览器(版本) 图片预览 大小获得
ie6 设置img.src=file.value 通过img.fileSize获得
ie7-9
  1. 通过file.select()和document.selection.createRangeCollection().item(0).text获取上传文件本地路径filepath
  2. 为div添加filter,即div.style.filter = ‘progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=\’scale\’,src=\” + filepath + ‘\’)';
无法获得,需结合后台功能
firefox6 设置img.src=file.files.item(0).getAsDataURL() file.files.item(0).fileSize或者file.files.item(0).size
chrome13 无法通过前端方法本地预览,需结合后台功能,即上传文件后展示 file.files.item(0).fileSize或者file.files.item(0).size

在ie7-9、firefox6及chrome13下,浏览器出于安全考虑,无法通过file.value获得选择图片的本地路径,其中ie7-9和chrome13获得的是经过处理的本地路径,而firefox6下获得的是图片的名称。

HTML JavaScript 前端

form.action’s bug in ie6、ie7

这样一个表单

1
2
3
<form id="myForm" action="">
  <input type="hidden" name="action" id="hiddenAction" />
</form>

当你是用javascript修改form的action时,你会考虑哪种方式呢?
第一种:myForm.action = ”
第二种:myForm.getAttribute(‘action’) = ”
第三种:myForm.attributes['action'].value = ”

在这种情况下,推荐使用第三种,因为第一种和第二种在ie6和ie7下会导致你的表单不能提交到正确的地址。

深究的话,myForm.action == myForm.getAttribute(‘action’) == hiddenAction。

现代浏览器为了兼容旧浏览器,支持使用节点的name值来直接访问form中的节点,也就是说,你使用myForm['action']或myForm.action访问到的是name值为action的input。而ie6和ie7中的bug就是,你使用getAttribute访问form的属性时,被误认为是访问form的节点。这一点在ie8以上已经修复了。

最后不得不呼吁一下,赶紧升级浏览器吧,还不知道有多少bug呢。

JavaScript YUI

javascript札记

YUI获取未指定width、height元素的宽和高。offset,screen,client。

ie6下,div遮罩select。

节点插入,appendChild和insertBefore。

YUI

YUI in memory

YUI第一次使用,因为有了使用jQuery的基础,相对来说,上手可能比较容易,当然也会在使用过程中觉得YUI的使用没有jQuery方便。这也是为什么jQuery能够迅速的发展的原因之一,write less, do more。

其实,应该这样理解,YUI是类似于jQuery、jQueryUI及一些jQuery插件的集合,所以相对于jQuery来说,肯定是要复杂一些了。另外,jQuery从某种程度上开说是一个工具箱,有些功能有,有些功能需要第三方扩展。而YUI是一种解决方案,几乎什么都有。

言归正传,初步来看,YUI提供的onDomReady方法,与jQuery中的ready方法相当。

YUI中获得页面标签元素返回的是HTML Element。对获得的元素,你可以使用原始的JavaScript的Dom方法。获取元素的方法有好几个,这一点上没有jQuery简洁。这些方法包括:get,getElementBy,getElementsByClassName。详细的可以参考YUI官方文档

YUI使用了大量的命名控件,跟.NET差不多,所以使用时,你需要考虑尽可能只引用需要的库。毕竟所有的东西都在YAHOO这个根命名控件下,有时候真为它担忧啊。

YUI中为元素绑定方法使用的是YAHOO.util.Event.on,老长一段。需要注意的是,推荐你在使用YUI前,为你要使用的元素定义ID。从目前来看,还是使用ID获取元素比较方便。

jQuery Linux

Fix:fancybox.cancel, installing arch

上一篇讲到取消显示fancybox时,使用$.fancybox.cancel()。后来仔细看了一下官方API,以及官方的示例,得出的结论是我错了。先看官方示例的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$("#various7").fancybox({
	onStart	:	function() {
		return window.confirm('Continue?');
	},
	onCancel	:	function() {
		alert('Canceled!');
	},
	onComplete	:	function() {
              alert('Completed!');
	},
	onCleanup	:	function() {
              return window.confirm('Close?');
	},
	onClosed	:	function() {
              alert('Closed!');
	}
});

在显示fancybox前,做一些判断,只需要将该判断放在fancybox的自定义方法onStart中,通过return的值来确定是否继续显示fancybox。

那么,$.fancybox.cancel是做什么用的呢?官方API中是这样说的“Cancels loading content”。

———————————————————————————————————–

上一次折腾的arch,安装的是gnome桌面环境,这一次安装了lxde和xfce。从安装文件大小、界面美观、使用方便等多方面考量的话,xfce确实是个不错的桌面环境。

比起gnome、kde安装文件就有200兆左右,xfce只需要60兆左右,至少对于我这种迫不及待的人来说,可以接受。

另外,xfce相对于lxde除了美观之外,也预装了一些软件,对于新手来说,避免自行安装软件的纠结。首先不知道装什么软件,其次不知道装哪款软件。

当然,xfce也不是没有不足的地方,例如自动挂载u盘就给我找了麻烦。结合官方文档LXDEXFCE,大致操作如下:

【xfce自动挂载u盘】
pacman -S hal。
nano /etc/rc.conf,在DAEMON的dbus后添加hal。/etc/rc.d/hal start。
pacman -S pmount。
重启。

除此之外,你可能还需要安装一下软件

pacman -S gvfs
pacman -S thunar-volman

PS 本来想说firefox虽好,也有让我不满意的地方,然而我错了,因为不满意的是我尚未发觉的改进。

Asp.NET jQuery

fancybox.cancel

常在调用fancybox显示表单前要判断用户是否做了先决的操作,如果没有操作就中止弹出fancybox。在以前的博文中,提到$.fancybox.cancel()。

最近注意了一下代码,才发现方法名写成了cancle,这样会引起脚本报错。代码如下:

$(‘a[name="info"]‘).click(function(){
if(true){
}
else{
$.fancybox.cancle();
}
}).fancybox();

虽然方法名写错了,但是也实现了中止fancybox显示的效果,而且再做了先决操作后,fancybox可以正常工作。而改为正确的cancel方法后,反而导致整个页面中的脚本都不能工作,脚本报错显示是fancybox中的e.onCancel()方法未定义。具体是什么问题还需研究研究。

先撇开上面的问题不说,在保证不出现脚本报错的前提下,我们还可以使用另一个全局方法$.fancybox.close()来实现,代码如下:

$(‘a[name="info"]‘).fancybox().click(function(){
if(true){
}
else{
$.fancybox.close();
}
});

注意比对两段代码,你会发现fancybox和click方法的顺序不同。fancybox是绑定在click事件上的。前一段代码中cancle导致fancybox方法失效;后一段代码实际上就是关闭fancybox,也就是说你得让fancybox打开了才能关闭它,所以它们出现的顺序就这么决定了。

PS Firefox 4发布了,太不错了,你值得拥有!

Asp.NET jQuery

fancybox in asp.net

在Asp.Net中使用fancybox通常遇到的问题,主要是在fancybox中的服务器端控件无法正常工作了,一些网友提出给fancybox中的控件绑定事件,并使用__doPostback(”,”)触发该控件的服务器端实践。当然这是一种解决的办法,但是每一次都要额外写一些代码,确实也挺烦的。

一种较为行之有效的方法就是修改fancybox的主JS文件,搜索其中的body并将其替换为form。因为fancybox的弹出窗口是通过在页面中添加多个层来实现的,默认情况下这些层都使用append方法添加在body的最后,也就是form的外边,当显示fancybox是服务器端控件会被移出form。而添加的服务器端控件是必须包含在form中的,否则无法正常工作。

另外,如果你在项目中使用了updatepanel,可能在updatepanel中的链接无法使用fancybox正常显示。例如,在updatepanel中有一个GridView,其中的一列上添加了链接,用来弹出fancybox显示详细信息,第一次进入页面后,点击链接可以弹出fancybox,当点击查询按钮后,再点击链接fancybox就失效,转而变为页面跳转。

大致分析的原因是,查询使得GridView中链接列的链接上绑定的fancybox丢失了。直接的想法就是,在查询结束后,列表绑定完成后,重新为链接列的每一个链接重新绑定fancybox。这样,我们在调用GridView的绑定方法之后,向页面中写入一段脚本,页面上脚本如下:

jQuery.showInfo = function(){
jQuery(‘a[name="linkInfo"]‘).fancybox();
}

服务器端代码,ScriptManager.RegisterStartupScript(Page,Page.GetType(),”",”jQuery.showInfo();”,true);

目前,在我的试验中,你需要为fancybox指定一些参数,否则可能仍然会出现原来的问题。

PS Firefox 4即将正式发布,等不及了,赶快尝试吧!

jQuery

jQuery.fancybox.PublicMethods

jQuery的弹出窗口插件fancybox提供了9个公共方法,从某种程度来说,也可以称之为全局方法。

常使用fancybox使用iframe载入外部页面(’type’:'iframe’),操作完成后需要刷新父页面上的查询列表的内容,同时有些操作完成后需要关闭fancybox。后者,可以调用parent.$.fancybox.close()方法。前者,可以仿造该方法的写法,例如parent.$.triggerSelect()。这里需要注意的一点就是,需要在父窗口中以$.triggerSelect的方式定义方法。否则将导致无法找到triggerSelect方法。也就是说,你需要将triggerSelect方法注册到全局。

另外,可能有的时候遇到某些条件,并不希望弹出fancybox窗口。这种情况下,可能你是通过给控件增加click事件来完成这一判断的,而fancybox也是通过click事件激活的,简单的在click中使用return是于事无补的。幸得fancybox提供了相应的公共方法:$.fancybox.cancel()。

还有一个较为关注的$.fancybox.resize()方法,即自动根据内容的高度调整fancybox的高度。我很希望在使用iframe的时候也能自适应,尚需想个万全之策。更多的方法,参见fancybox API

PS 尝鲜吧!Firefox 4.0,更快速,更简洁,更绚丽!

jQuery

jQuery:使用click和mouseover移动table的行

上周跟tearnon讨论对table中的行进行移动,以达到手工排序的效果。

谈论的结果为,使用click事件以指定要移动的行(移动行)和最终要移至的行(移至行)。查看示例

在该示例中,需要注意的是,table中需要有一列的值是作为主键使用,不可重复。否则$.sltedRow.children(‘td’).eq(0).text() !== destRow.children(‘td’).eq(0).text()的比较结果不可靠,从而无法正确实现移动行的功能。

另外,为判断是向上移动还是向下移动,使用position()方法,并比较移动行和移至行的top,如$.sltedRow.position().top < destRow.position().top,以确定调用的方法是after还是before。当然,这种判断也存在不正确的地方,例如我们将向上移动都定义为将移动行都放置在移至行的前面。可能最好的办法是询问用户放置的位置。

接下来,在上面示例的基础上,做进一步的调整,以实现手工排序的功能。查看示例

首先选择移动行,再将移动行移至目标行,最后单击确定。这期间,table的排序(第一列的值)始终保持不变。示例中的关键点在于保持排序行的值不变。我的做法是,在每次移动前,记录下移动行和移至行的排序列的值,并进行交换赋值。但是,mouseout的处理逻辑存在问题,导致会出现排序列错乱的情况。

导致排序错乱的问题,是由排序列的值交换引起的,因为只考虑了相邻两行的值的交换,而未考虑跨行的交换。现在,将table排序设计为:当选中某行并移动时,将改行插入指定行的前面或后面(由移动行和移至行的top大小决定),当决定移至行(在移至行上click)后,重新计算排序列的值。

PS 微软想杀死自己的孩子IE6,我泪流满面的说杀得好,老早就该这样了。

jQuery

jQuery.selector

jQuery可以使用css、xml的选择器。

一篇css选择器的文章http://net.tutsplus.com/tutorials/html-css-techniques/the-30-css-selectors-you-must-memorize/

xml文档查找信息语言XPathhttp://www.w3school.com.cn/xpath/index.asp

PS 微软想杀死自己的孩子IE6,我泪流满面的说杀得好,老早就该这样了。

第 1 页,共 2 页12