* 2008年09月的日志

Maxthon引发的系列问题

Maxthon,一个大家熟得不能再熟的软件。我某位同事甚至这样的赞许它:“对我来说,Maxthon就是浏览器,浏览器就是Maxthon”。我这里不想讨论Maxthon是好是坏,只是如实的记录工作中由Maxthon带来的一些问题。我的Maxthon是官方的2.1.4,采用默认配置。由于Maxthon是一个IE Shell,我在测试中用系统自带的IE作为参考。

一、Maxthon会错误的处理某些JS事件。试着在IE地址栏中输入下列代码:

javascript:window.onbeforeunload = function(){return "你真的要关闭?"};void(0);

然后关闭浏览器当前Tab(IE7、IE8),或当前窗口(IE6),你会发现系统会给出“确实要离开页面…”之内的提示,选择“确定”才会执行关闭。但Maxthon不会这么做,弹出关闭提示时,当前tab/窗口已经关闭,无论选什么都无济于事。另外一个问题是Maxthon里鼠标右键点击,得到的返回键值不对。在地址栏输入以下代码:

javascript:document.onmousedown = function(){alert(event.button)};void(0);

在IE里右键单击返回的是2,而Maxthon返回0。这个就很让人费解了,都是IE内核,不应该有不同呐。

Continue Reading »

如何使用Flash来实现本地存储

我在5月份的一篇文章里列举了一些本地存储解决方案,包括常见的Cookie、UserData和不是那么常见的globalStorage、Database Storage。文章最后提到了另外两种解决方案:Google Gear和Flash,当时因为觉得用不上就没仔细研究。但实际应用中,那篇文章列出的方案还是不能满足项目的需求。这篇文章就讲一下如何使用Flash来实现本地存储,以及该方案使用的场合。

拿IE6来说,如果要在本地大量存放数据,Cookie因为存放内容太少、浪费用户带宽首先就应该被淘汰掉。UserData在大多数情况下能满足需求,但是它也有一个致命的弱点:只能读取同目录存储,也就是a目录下一个文件不能读取b目录下两一个文件存放的数据。MSDN说明如下:

Security Alert For security reasons, a UserData store is available only in the same directory and with the same protocol used to persist the store. 全文>>

也就是说如果项目中要跨文件夹操作本地存储,UserData也必须被淘汰了。IE不支持Database Storage,IE8才增加了对globalStorage的支持,这个时候Flash就派上用场了。

Continue Reading »

一种很帅的JS代码书写方式

最近在Dron的UCRen网站看到一种很帅的JS写法,记录一下。

UCRen是下面这样引入widget的(摘自这个页面):

<script type="text/javascript" src="../../ucren-engine/cache-boot.js?skin=qq">
  import webui.FileInput;
  import renderfactory.FormRenderer;
</script>

第一眼看到这段代码,我还在想这样写JS语法分析器不报错才怪,难道是让window.onerror返回true干掉了浏览器的错误提示?这样也太不和谐了吧!今天仔细看了看才明白了,这个script标签是有src属性的,这样写标签里的内容会被忽略掉,不会执行也不会报错。在src链入的cache-boot.js里可以用:

var scripts = document.getElementsByTagName("script");
var code = scripts[scripts.length-1].innerHTML;

来得到那些神奇的代码,然后用正则解析成正常的script标签就OK了。原理不复杂,不过很有用。可以用它写出一些很有趣的代码来。

如何控制浏览器的历史记录

上次一位网友在我blog留言问到如何修正Ajax后退失效,这是在开发Ajax应用时很常见的需求。这篇文章就简单的介绍一下怎么解决这个问题。

首先我们要清楚后退按钮会失效的原因:使用Ajax时,页面通过XMLHttpRequest来更新内容,并没有Redirect,所以浏览器不会出现前进后退。这也是Ajax刚出来时遭到很多人批判的一个原因,其中细节可以参考这两篇文章《Ajax: 99% Bad》、《AJAX的七宗罪》。这个问题其实跟Ajax无关,不过Ajax的出现使得一个页面实现无刷新更新更容易,这个时候人们开始意识到,一个页面发生巨大改变而不能后退是一件很痛苦的事情。

要解决这个问题,就要控制浏览器的history,在页面发生改变时往浏览器历史里插入一条记录。但是出于安全的目的,JS是不能直接操作history的。我们必须采用其他方法:IE中,在页面中插入一个隐藏的iframe,通过改变iframe的location或者DOM,都可以在主窗口的history中产生新记录,详细研究可以参考这篇文章;在其他浏览器(Firefox、Opera、Safari)中没有这么复杂,只需改变url就可以产生一条新的history记录,当然url不能乱改,要不页面就跳转走了,通常我们改变的是location.hash,也就是url“#”以后的部分。下面是具体实现:

Continue Reading »

不同浏览器处理后退的一些异同

以前在测试自己写的webim时发现firefox有一个很人性化的特性:在页面上跟别人聊天的时候如果不小心点到了本页打开的链接,只要点一下Firefox的后退按钮,就会退后到之前的页面,可以接着聊。也就是说在firefox中点击后退,原来页面的状态会还原,包括JS改变的DOM结构也会保持。

我们用下面的代码来测试一些常见的浏览器是怎么处理后退的。测试的浏览器有IE8beta2、Firefox3.0.1、Flock1.2.4(Firefox2.0.0.16内核)、Safari3.1(window版)、Opera9.60。

<a href="http://www.baidu.com">百度</a>
<div id="a1"></div>
<script type="text/javascript">
  window.onload = function(){
    alert("load");
    var i = 1;
    setInterval(function(){
      document.getElementById("a1").innerHTML = i++;
    },500);
  };
</script>

Continue Reading »

IE与Firefox处理Attribute的几点差异

前端开发中,经常需要动态的添加、移除或者获取元素的Attribute。也就是说经常会用到setAttribute、removeAttribute和getAttribute。今天要讨论的是开发中遇到的几处IE与Firefox对Attribute操作的差异。

属性名大小写

在Firefox中,属性没有小写的概念,就算属性名全用大写,Firefox也会解析成小写,用Firebug看就能看到。所以下面的代码在Firefox与IE中运行结果会不一样。

<div altStr="sss"></div>
<script type="text/javascript">
 var div = document.getElementsByTagName("div")[0];
 div.removeAttribute("altstr");
 alert(div.getAttribute("altstr"));//IE中返回sss,FF中返回null
</script>

不过在IE中,removeAttribute有第二个参数,设置为true表示不忽略大小写,为false时忽略大小写,默认值是true;Firefox中因为解析时就不存在大写属性了,所以就没有第二个参数。也就是说IE中removeAttribute(”test”,false)等同于Firefox中的removeAttribute(”test”),IE中removeAttribute(”test”,true)在Firefox中无法实现。

Continue Reading »