RSS
people

JS的IE和Firefox兼容性小结

JS的IE和Firefox兼容性汇编(原作:hotman_x)
以下以 IE 代替 Internet Explorer,以 MF 代替 Mozzila Firefox
1. document.form.item 问题
? (1)现有问题:
? 现有代码中存在许多 document.formName.item(“itemName”) 这样的语句,不能在 MF 下运行
? (2)解决方法:
? 改用 document.formName.elements["elementName"]
? (3)其它
? 参见 2
2. 集合类对象问题
? (1)现有问题:
? 现有代码中许多集合类对象取用时使用 (),IE 能接受,MF 不能。
? (2)解决方法:
? 改用 [] 作为下标运算。如:document.forms(“formName”) 改为 document.forms["formName"]。
? 又如:document.getElementsByName(“inputName”)(1) 改为 document.getElementsByName(“inputName”)[1]
? (3)其它
3. window.event
? (1)现有问题:
? 使用 window.event 无法在 MF 上运行
? (2)解决方法:
? MF 的 event 只能在事件发生的现场使用,此问题暂无法解决。可以这样变通:
? 原代码(可在IE中运行):
?
<input name=”someButton” type=”button” onclick=”javascript:gotoSubmit()” />?? …
?<script language=”javascript”>
?????????????????????

function gotoSubmit() {????????????????????? …?
????????????????????
alert(window.event);??? // use window.event???
?????????????????? …????????????????? }????????????? </script>
? 新代码(可在IE和MF中运行):
?
<input name=”someButton” type=”button” onclick=”javascript:gotoSubmit(event)” />?? …
?<script language=”javascript”>???
??????????????????
function gotoSubmit(evt) {????????
?????????????
evt = evt ? evt : (window.event ? window.event : null);????
???
?????????????? …????????????????????? alert(evt);???????????? // use evt???
?????????????????? …????????????????? }????????????? </script>

? ?
? 此外,如果新代码中第一行不改,与老代码一样的话(即 gotoSubmit 调用没有给参数),则仍然只能在IE中运行,但不会出错。所以,这种方案 tpl 部分仍与老代码兼容。
4. HTML 对象的 id 作为对象名的问题
? (1)现有问题
? 在 IE 中,HTML 对象的 ID 可以作为 document 的下属对象变量名直接使用。在 MF 中不能。
? (2)解决方法
? 用 getElementById(“idName”) 代替 idName 作为对象变量使用。
5. 用idName字符串取得对象的问题
? (1)现有问题
? 在IE中,利用 eval(idName) 可以取得 id 为 idName 的 HTML 对象,在MF 中不能。
? (2)解决方法
? 用 getElementById(idName) 代替 eval(idName)。
6. 变量名与某 HTML 对象 id 相同的问题
? (1)现有问题
? 在 MF 中,因为对象 id 不作为 HTML 对象的名称,所以可以使用与 HTML 对象 id 相同的变量名,IE 中不能。
? (2)解决方法
? 在声明变量时,一律加上 var ,以避免歧义,这样在 IE 中亦可正常运行。
? 此外,最好不要取与 HTML 对象 id 相同的变量名,以减少错误。
? (3)其它
? 参见 问题4
7. event.x 与 event.y 问题
? (1)现有问题
? 在IE 中,event 对象有 x, y 属性,MF中没有。
? (2)解决方法
? 在MF中,与event.x 等效的是 event.pageX。但event.pageX IE中没有。
? 故采用 event.clientX 代替 event.x。在IE 中也有这个变量。
? event.clientX 与 event.pageX 有微妙的差别(当整个页面有滚动条的时候),不过大多数时候是等效的。
? 如果要完全一样,可以稍麻烦些:
? mX = event.x ? event.x : event.pageX;
? 然后用 mX 代替 event.x
? (3)其它
? event.layerX 在 IE 与 MF 中都有,具体意义有无差别尚未试验。

8. 关于frame
? (1)现有问题
? 在 IE中 可以用window.testFrame取得该frame,mf中不行
? (2)解决方法
? 在frame的使用方面mf和ie的最主要的区别是:
如果在frame标签中书写了以下属性:

那么ie可以通过id或者name访问这个frame对应的window对象
而mf只可以通过name来访问这个frame对应的window对象
例如如果上述frame标签写在最上层的window里面的htm里面,那么可以这样访问
ie: window.top.frameId或者window.top.frameName来访问这个window对象
mf: 只能这样window.top.frameName来访问这个window对象
另外,在mf和ie中都可以使用window.top.document.getElementById(“frameId”)来访问frame标签
并且可以通过window.top.document.getElementById(“testFrame”).src = ‘xx.htm’来切换frame的内容
也都可以通过window.top.frameName.location = ‘xx.htm’来切换frame的内容
关于frame和window的描述可以参见bbs的‘window与frame’文章
以及/test/js/test_frame/目录下面的测试
—-adun 2004.12.09修改
9. 在mf中,自己定义的属性必须getAttribute()取得
10.在mf中没有 parentElement parement.children 而用
? parentNode parentNode.childNodes
? childNodes的下标的含义在IE和MF中不同,MF使用DOM规范,childNodes中会插入空白文本节点。
? 一般可以通过node.getElementsByTagName()来回避这个问题。
? 当html中节点缺失时,IE和MF对parentNode的解释不同,例如

<form>
<table><>><>><><>>
<input />?? </><tbody></tbody></table>
</form>

MF中input.parentNode的值为form, 而IE中input.parentNode的值为空节点
? MF中节点没有removeNode方法,必须使用如下方法 node.parentNode.removeChild(node)
11.const 问题
? (1)现有问题:
? 在 IE 中不能使用 const 关键字。如 const constVar = 32; 在IE中这是语法错误。
? (2)解决方法:
? 不使用 const ,以 var 代替。
12. body 对象
? MF的body在body标签没有被浏览器完全读入之前就存在,而IE则必须在body完全被读入之后才存在
13. url encoding
在js中如果书写url就直接写&不要写&例如var url = ‘xx.jsp?objectName=xx&objectEvent=xxx’;
frm.action = url那么很有可能url不会被正常显示以至于参数没有正确的传到服务器
一般会服务器报错参数没有找到
当然如果是在tpl中例外,因为tpl中符合xml规范,要求&书写为&
一般MF无法识别js中的&

14. nodeName 和 tagName 问题
? (1)现有问题:
? 在MF中,所有节点均有 nodeName 值,但 textNode 没有 tagName 值。在 IE 中,nodeName 的使用好象
? 有问题(具体情况没有测试,但我的IE已经死了好几次)。
? (2)解决方法:
? 使用 tagName,但应检测其是否为空。
15. 元素属性
? IE下 input.type属性为只读,但是MF下可以修改

16. document.getElementsByName() 和 document.all[name] 的问题
? (1)现有问题:
? 在 IE 中,getElementsByName()、document.all[name] 均不能用来取得 div 元素(是否还有其它不能取的元素还不知道)。
firefox与IE浏览器在web开发上面的一些区别
开发准备工作
相关有价值的网站
? 中文firefox开发论坛地址 http://www.firefox.net.cn/newforum
? 讨论IE与Netscape区别的 http://www-128.ibm.com/developerworks/web/library/wa-ie2mozgd/
? http://www.w3schools.com/
firefox开发工具
? javascript 控制台(firefox工具中)
? dom inspector (forefox工具中,需要安装的时候选择自定义安装-开发工具)
? http://www.hacksrus.com/~ginda/venkman/
以下所有IE指IE6.0
验证是否是IE浏览器(来之于google js)
var agt=navigator.userAgent.toLowerCase();
var is_ie=(agt.indexOf(“msie”)!=-1 && document.all);
正式开始
事件委托方法
IE
document.body.onload = inject; //Function inject()在这之前已被实现
firefox
document.body.onload = inject();
有人说标准是:
document.body.onload=new Function(‘inject()’);
在firefox无法取得event.srcElement
通过其他方式传递对象
if(isIE)
thistable.attachEvent(“onmousedown”,OnClickChangeTdBackColor);
//thistable.onmousedown=OnClickChangeTdBackColor;
else//deal firefox
{

for(var i=0;i

{
var rowObj = thistable.rows[i];
for( var j=0;j {
var cellObj = rowObj.cells[j];
cellObj.setAttribute(“onmousedown”,”OnClickChangeTdBackColor(this)”);
}
//alert(rowObj.cells[0].tagName);
}
}
这是来之 http://blog.joycode.com/lostinet/archive/2005/02/27/44999.aspx
在FireFox下编写事件处理函数是很麻烦的事.
因为FireFox并没有 window.event . 如果要得到 event 对象,就必须要声明时间处理函数的第一个参数为event.所以为了兼容IE与FireFox,一般的事件处理方法为:
btn.onclick=handle_btn_click;
function handle_btn_click(evt)
{
if(evt==null)evt=window.event;//IE
//处理事件.
}
对于简单的程序,这不算麻烦.但对于一些复杂的程序,某写函数根本就不是直接与事件挂钩的.如果要把event传进该参数,那么所有的方法都要把event传来传去..这简直就是噩梦.下面介绍一个解决这个麻烦事的方法,与原理.

JScript中,函数的调用是有一个 func.caller 这个属性的.
例如
function A()
{
B();
}
function B()
{
alert(B.caller);
}
如果B被A调用,那么B.caller就是A

另外,函数有一个arguments属性. 这个属性可以遍历函数当前执行的参数:
function myalert()
{
var arr=[];
for(var i=0;i
arr[i]=myalert.arguments[i];
alert(arr.join(“-”));
}
alert(“hello”,”world”,1,2,3)
就能显示 hello-world-1-2-3
(arguments的个数与调用方有关,而与函数的参数定义没有任何关系)

根据这两个属性,我们可以得到第一个函数的event对象:
btn.onclick=handle_click;
function handle_click()
{
showcontent();
}
function showcontent()
{
var evt=SearchEvent();
if(evt&&evt.shiftKey)//如果是基于事件的调用,并且shift被按下
window.open(global_helpurl);
else
location.href=global_helpurl;
}
function SearchEvent()
{
func=SearchEvent.caller;
while(func!=null)
{
var arg0=func.arguments[0];
if(arg0)
{
if(arg0.constructor==Event) // 如果就是event 对象
return arg0;
}
func=func.caller;
}
return null;
}
这个例子使用了SearchEvent来搜索event对象. 其中 ‘Event’ 是 FireFox 的 event.constructor .
在该例子运行时,
SearchEvent.caller就是showcontent,但是showcontent.arguments[0]是空.所以 func=func.caller 时,func变为handle_click .
handle_click 被 FireFox 调用, 虽然没有定义参数,但是被调用时,第一个参数就是event,所以handle_click.arguments[0]就是event !
针对上面的知识,我们可以结合 prototype.__defineGetter__ 来实现 window.event 在 FireFox 下的实现:

下面给出一个简单的代码.. 有兴趣的可以补充
if(window.addEventListener)
{
FixPrototypeForGecko();
}
function FixPrototypeForGecko()
{
HTMLElement.prototype.__defineGetter__(“runtimeStyle”,element_prototype_get_runtimeStyle);
window.constructor.prototype.__defineGetter__(“event”,window_prototype_get_event);
Event.prototype.__defineGetter__(“srcElement”,event_prototype_get_srcElement);
}
function element_prototype_get_runtimeStyle()
{
//return style instead…
return this.style;
}
function window_prototype_get_event()
{
return SearchEvent();
}
function event_prototype_get_srcElement()
{
return this.target;
}
function SearchEvent()
{
//IE
if(document.all)
return window.event;

func=SearchEvent.caller;
while(func!=null)
{
var arg0=func.arguments[0];
if(arg0)
{
if(arg0.constructor==Event)
return arg0;
}
func=func.caller;
}
return null;
}

firefox与IE(parentElement)的父元素的区别
因为firefox与IE都支持DOM,因此使用obj.parentNode是不错选择.
IE
obj.parentElement
firefox
obj.parentNode

asp.net中UniqueID和clientID的区别
要使用document.getElementById 方法,则使用控件的时候要这样来作
“javascript:OnSelectSubCatalog(\”"+subCatalog_drp.ClientID+”\”,”+catalogIDX+”,”+catID.ToString()+”)”;

调用Select元素的区别
移出一个选择项
________________________________________

IE :sel.options.remove(sel.selectedIndex);
firefox :
增加选择项:
________________________________________
IE: subCatalog.add(new Option(text,value));
firefox:
var opnObj = document.createElement(“OPTION”);
//opnObj.id = optionID;
opnObj.value = value;
opnObj.text = text;
subCatalog.appendChild(opnObj);
cursor:hand VS cursor:pointer
firefox不支持hand,但ie支持pointer,所以建议统一使用pointer。

No Comments | Tags: , , , , , , ,

HTML5中引入新的元素

新千年以来,超文本标记语言(HTML)5 第一次向 HTML 中引入新的元素。新的结构元素包括 asidefiguresection。新的内联元素包括 timemeterprogress。新的内嵌元素有 videoaudio。新的交互元素有 detailsdatagridcommand

超文本标记语言(HTML)的开发到 1999 年 HTML 4 就停止了。万维网联盟(W3C)把重点转向将 HTML 的底层语法从标准通用标记语言(SGML)改为可扩展标记语言(XML),以及可缩放向量图型(SVG)、XForms 和 MathML 这些全新的标记语言。浏览器厂商则把精力放到选项卡和富站点摘要(RSS)阅读器这类浏览器特性上。Web 设计人员开始学习使用异步 JavaScript + XML(Ajax),在现有的框架下通过层叠样式表(CSS)和 JavaScript? 语言建立自己的应用程序。但是在接下来的八年中,HTML 本身没有任何变化。

最近,它又复活了。三家重要的浏览器厂商 — Apple、Opera 和 Mozilla Foundation — 成立了 Web Hypertext Application Technology Working Group(WhatWG)来开发传统 HTML 的新版本。最近,W3C 也注意到了这些活动,也启动了自己的新一代 HTML 项目,双方的成员有很多是相同的。这两个项目最终很可能合并。虽然很多细节还在争论之中,但下一版本 HTML 的大体轮廓已经清楚了。

Web 开发人员从 1999 年就一直期待 HTML 的新版本(通常称为 HTML 5,但是也称为 Web Applications 1.0),现在它终于发布了。它保持了 HTML 原来的特色:没有名称空间或模式。元素不必结束。浏览器会宽容地对待错误。p 仍然是 ptable 仍然是 table

如果在 1999 年将一位 Web 开发人员冷冻起来,现在再解冻,那么他会遇到一些新的让人迷惑的元素。是的,他熟悉的元素(比如 div)仍然保留了;但是,HTML 现在还包含 sectionheaderfooternav 等新元素。emcodestrong 仍然存在,但是增加了 metertimemimgembed 仍然可用,但是还增加了 videoaudio。但是,他仔细观察一下就会发现,这些元素实际上没什么区别。其中许多元素可能在 1999 年是开发人员需要而没有得到的。通过与他已经掌握的元素进行简单的类比,这些新元素都很容易理解。实际上,与 Ajax 或 CSS 相比,它们非常容易掌握。

最后,当他打开 300MHz 的笔记本(运行的是 Windows 98,也是在 1999 年冷冻起来的)时,他可能对 Netscape 4 和 Windows? Internet Explorer? 5 中显示的新页面效果很吃惊。当然,这些老式浏览器不认识新元素,会完全忽略它们,但是页面仍然会显示,内容仍然是完整的。

这并不是什么虚构的故事。HTML 5 的设计原则就是在不支持它的浏览器中能够平稳地退化。原因很简单:我们都是这样的 “原始人”。浏览器现在有选项卡、CSS 和 XmlHttpRequest,但是它们的 HTML 显示引擎仍然停留在 1999 年的水平。除了用户量大大增加之外,Web 其实在本质上没什么进步。HTML 5 考虑到了这一点。它目前为 Web 开发人员一些真正的好处,随着浏览器的缓慢升级,页面浏览者会逐渐享受到这些好处。我们来看看 HTML 5 提供了什么。

结构

由于缺少结构,即使是形式良好的 HTML 页面也比较难以处理。必须分析标题的级别,才能看出各个部分的划分方式。边栏、页脚、页眉、导航条、主内容区和各篇文章都由通用的 div 元素来表示。HTML 5 添加了一些新元素,专门用来标识这些常见的结构:

  • section:这可以是书中的一章或一节,实际上可以是在 HTML 4 中有自己的标题的任何东西
  • header:页面上显示的页眉;与 head 元素不一样
  • footer:页脚;可以显示电子邮件中的签名
  • nav:指向其他页面的一组链接
  • article:blog、杂志、文章汇编等中的一篇文章

我们来考虑一个典型的 blog 主页,它的顶部有页眉,底部有页脚,还有几篇文章、一个导航区和一个边栏,见清单 1。
清单 1. 典型的 blog 页面

     <html>
    <head>
    <title>Mokka mit Schlag </title>
    </head>
    <body>
    <div id="page">
    <div id="header">
    <h1><a href="http://www.elharo.com/blog" mce_href="http://www.elharo.com/blog">Mokka mit Schlag</a></h1>
    </div>
    <div id="container">
    <div id="center" class="column">
    <div class="post" id="post-1000572">
    <h2><a href="/blog/birding/2007/04/23/spring-comes-and-goes-in-sussex-county/"
    mce_href="/blog/birding/2007/04/23/spring-comes-and-goes-in-sussex-county/">
    Spring Comes (and Goes) in Sussex County</a></h2>
   <div class="entry">
   <p>Yesterday I joined the Brooklyn Bird Club for our
   annual trip to Western New Jersey, specifically Hyper Humus, a relatively recently discovered hot spot.
   It started out as a nice winter morning when we arrived at the site at 7:30 A.M.
   , progressed to Spring around 10:00 A.M., and reached early summer by 10:15. </p>
   </div>
   </div>
   <div class="post" id="post-1000571">
   <h2><a href="/blog/birding/2007/04/23/but-does-it-count-for-your-life-list/"
   mce_href="/blog/birding/2007/04/23/but-does-it-count-for-your-life-list/">
   But does it count for your life list?</a></h2>
   <div class="entry">
   <p>Seems you can now go <a href="http://www.wired.com/science/discoveries/news/2007/04/cone_sf">
   bird watching via the Internet</a>.
   I haven't been able to test it out yet (20 user limit apparently) but this is certainly cool.Personally,
   I can't imagine it replacing
    actually being out in the field by any small amount. On the other hand, I've always found it quite
    sad to meet senior birders who are no longer able to hold binoculars steady or get to the park.
    I can imagine this might be of some interest to them. At least one elderly birder did a big year on TV,
    after he could no longer get out so much. This certainly tops that.</p>
   </div>
   </div>
   </div>
   <div class="navigation">
   <div class="alignleft">
   <a href="/blog/page/2/" mce_href="/blog/page/2/">? Previous Entries</a>
   </div>
   <div class="alignright"></div>
   </div>
   </div>
   <div id="right" class="column">
   <ul id="sidebar">
   <li><h2>Info</h2>
   <ul>
  <li><a href="/blog/comment-policy/" mce_href="/blog/comment-policy/">Comment Policy</a></li>
  <li><a href="/blog/todo-list/" mce_href="/blog/todo-list/">Todo List</a></li>
  </ul></li>
  <li><h2>Archives</h2>
  <ul>
  <li><a href='/blog/2007/04/'>April 2007</a></li>
  <li><a href='/blog/2007/03/'>March 2007</a></li>
  <li><a href='/blog/2007/02/'>February 2007</a></li>
  <li><a href='/blog/2007/01/'>January 2007</a></li>
  </ul> </li>
  </ul>
  </div>
  <div id="footer">
  <p>Copyright 2007 Elliotte Rusty Harold</p>   </div> </div>
  </body> </html>

即使有正确的缩进,这些嵌套的 div 仍然让人觉得非常混乱。在 HTML 5 中,可以将这些元素替换为语义性的元素,见清单 2。
清单 2. 用 HTML 5 编写的典型 blog 页面

   <html>
  <head>
  <title>Mokka mit Schlag </title>
  </head>
  <body>
  <header>
  <h1><a href="http://www.elharo.com/blog" mce_href="http://www.elharo.com/blog">Mokka mit Schlag</a></h1>
  </header>
  <section>
  <article>
  <h2><a href="/blog/birding/2007/04/23/spring-comes-and-goes-in-sussex-county/"
  mce_href="/blog/birding/2007/04/23/spring-comes-and-goes-in-sussex-county/">
  Spring Comes (and Goes) in Sussex County</a></h2>
  <p>Yesterday I joined the Brooklyn Bird Club for our annual trip to Western New Jersey, specifically Hyper Humus,
  a relatively recently discovered hot spot. It started out as a nice winter morning when we arrived
   at the site at 7:30 A.M. , progressed to Spring around 10:00 A.M., and reached early summer by 10:15. </p>
   </article>
  <article>
  <h2><a href="/blog/birding/2007/04/23/but-does-it-count-for-your-life-list/"
  mce_href="/blog/birding/2007/04/23/but-does-it-count-for-your-life-list/">
  But does it count for your life list?</a></h2>
  <p>Seems you can now go <a href="http://www.wired.com/science/discoveries/news/ 2007/04/cone_sf">
  bird watching via the Internet</a>.I haven't been able to test it out yet (20 user limit apparently)
  but this is certainly cool.Personally, I can't imagine it replacing actually being out in the field by
  any small amount.On the other hand, I've always found it quite sad to meet senior birders who are no
  longer able to hold binoculars steady or get to the park. I can imagine this might be of some interest
  to them. At least one elderly birder did a big year on TV, after he could no longer get out so much.
  This certainly tops that.</p> </article>
  <nav> <a href="/blog/page/2/" mce_href="/blog/page/2/">? Previous Entries</a> </nav>
  </section>
  <nav>
  <ul>
  <li>
  <h2>Info</h2>
  <ul>
  <li><a href="/blog/comment-policy/" mce_href="/blog/comment-policy/">Comment Policy</a></li>
  <li><a href="/blog/todo-list/" mce_href="/blog/todo-list/">Todo List</a></li>
  </ul>
  </li>
  <li>
  <h2>Archives</h2>
  <ul>
  <li><a href='/blog/2007/04/'>April 2007</a></li>
  <li><a href='/blog/2007/03/'>March 2007</a></li>
  <li><a href='/blog/2007/02/'>February 2007</a></li>
  <li><a href='/blog/2007/01/'>January 2007</a></li>
  </ul>
  </li>
  </ul>
  </nav>
  <footer>
  <p>Copyright 2007 Elliotte Rusty Harold</p>
  </footer>
  </body>
  </html>

现在不再需要 div 了。不再需要自己设置 class 属性,从标准的元素名就可以推断出各个部分的意义。这对于音频浏览器、手机浏览器和其他非标准浏览器尤其重要。


回页首

语义性的块元素

除了结构性元素之外,HTML 5 还增加了一些纯语义性的块级元素:

  • aside
  • figure
  • dialog

我在文章和书中一直使用前两个元素。第三个元素我不经常用,它主要用于书面文本。

aside

aside 元素代表说明、提示、边栏、引用、附加注释等,也就是叙述主线之外的内容。例如,在 developerWorks 文章中,常常会看到用表格形式编写的边栏,见清单 3。
清单 3. 用 HTML 4 编写的 developerWorks 边栏

   <table align="right" border="0" cellpadding="0" cellspacing="0" width="40%">
  <tbody><tr><td width="10">
  <img alt="" src="//www.ibm.com/i/c.gif" mce_src="//www.ibm.com/i/c.gif" height="1" width="10">
  </td>
  <td>
  <table border="1" cellpadding="5" cellspacing="0" width="100%">
  <tbody>
  <tr>
  <td bgcolor="#eeeeee">
  <p><a name="xf-value"><span class="smalltitle">.xf-value</span></a></p>
  <p> The <code type="inline">.xf-value</code>
  selector used here styles the input field value but not its label. This is actually inconsistent
  with the current CSS3 draft. The example really should use the <code type="inline">::value</code>
  pseudo-class instead like so: </p> <table border="0" cellpadding="0" cellspacing="0" width="100%">
  <tbody><tr><td class="code-outline"> <pre class="displaycode">
  input::value { width: 20em; } #ccnumber::value { width: 18em } #zip::value { width: 12em }
  #state::value { width: 3em  }</pre> </td></tr></tbody></table><br>  <p> However, Firefox doesn't yet
  support this syntax.
  </p> </td></tr></table>

在 HTML 5 中,可以按照更有意义的方式编写这个边栏,见清单 4。
清单 4. 用 HTML 5 编写的 developerWorks 边栏

    <aside>
   <h3>.xf-value</h3>
   <p> The <code type="inline">.xf-value</code>
   selector used here styles the input field value but not its label. This is actually inconsistent
   with the current CSS3 draft. The example really should use the <code type="inline">::value</code>
   pseudo-class instead like so: </p>    <pre class="displaycode">input::value { width: 20em; }
   #ccnumber::value { width: 18em } #zip::value { width: 12em } #state::value { width: 3em  }</pre>
   <p> However, Firefox doesn't yet support this syntax.  </p>
   </aside>

浏览器可以决定把这个边栏放在哪里(可能需要用一点儿 CSS 代码)。

figure

figure 元素代表一个块级图像,还可以包含说明。例如,在许多 developerWorks 文章中,可以看到清单 5 这样的标记;其结果见图 1。
清单 5. 用 HTML 4 编写的 developerWorks 图

   <a name="fig2"><b>Figure 2. Install Mozilla XForms dialog</b></a><br />
  <img alt="A Web site is requesting permission to install the following item:
  Mozilla XForms 0.7 Unsigned" src="installdialog.jpg" mce_src="installdialog.jpg"
   border="0" height="317" hspace="5" vspace="5" width="331" /> <br />

图 1. Install Mozilla XForms dialog
A Web site is requesting permission to install the following item: Mozilla XForms 0.7 Unsigned
在 HTML 5 中,可以按照更有语义性的方式编写这个图,见清单 6。
清单 6. 用 HTML 5 编写的 developerWorks 图

   <figure id="fig2">
  <legend>Figure 2. Install Mozilla XForms dialog</legend>
  <img alt="A Web site is requesting permission to install the following item:
  Mozilla XForms 0.7 Unsigned" src="installdialog.jpg" mce_src="installdialog.jpg"
   border="0" height="317" hspace="5" vspace="5" width="331" />
  </figure>

最重要的是,浏览器(尤其是屏幕阅读器)可以明确地将图和说明联系在一起。

figure 元素不只可以显示图片。还可以使用它给 audiovideoiframeobjectembed 元素加说明。

dialog

dialog 元素表示几个人之间的对话。HTML 5 dt 元素可以表示讲话者,HTML 5 dd 元素可以表示讲话内容。所以,在老式浏览器中也可以以合理的方式显示对话。清单 7 显示在 Galileo 的 “Dialogue Concerning the Two Chief World Systems” 上的一段著名对话。
清单 7. 用 HTML 5 编写的 Galilean 对话

  <dialog>
  <dt>Simplicius </dt>
  <dd>According to the straight line AF, and not according to the curve, such being already excluded
  for such a use.</dd>
  <dt>Sagredo </dt>
  <dd>But I should take neither of them, seeing that the straight line AF runs obliquely.
  I should draw a line perpendicular to CD, for this would seem to me to be the shortest,
  as well as being unique among the 	infinite number of longer and unequal ones which may be
  drawn from the point A to every other point of the opposite 	line CD. </dd>
  <dt>Salviati </dt>
  <dd><p> Your choice and the reason you adduce for it seem to me most excellent. So now we have
  it that the first dimension is determined by a straight line; the second (namely, breadth) by
  another straight line, and not only straight, but at right angles to that which 	determines the length.
  Thus we have defined the two dimensions of a surface; that is, length and breadth. </p>
  <p> But suppose you had to determine a height—for example, how high this platform is from the pavement down
  below there. Seeing that from any point in the platform we may draw infinite lines, curved or straight,
  and all of different lengths, to the infinite points of the pavement below, which of all these lines would
  you make use of? </p>
  </dd>
  </dialog>

对于这个元素的准确语法还有争议。一些人希望在 dialog 元素中嵌入非对话文本(比如剧本中的舞台说明),还有人不喜欢扩展 dtdd 元素的作用。尽管在具体语法方面有争议,但是大多数人都认为以这样的语义性方式表达对话是好事情。


回页首

语义性内联元素

HTML 4 用 5 个不同的内联元素表示略有差异的计算机代码:varcodekbdttsamp。但是,它无法表示时间、数字等基本数值。HTML 5 提供了几个新的内联元素来满足非技术作者的需求。

m

m 元素表示文本被 “加上标志”,但是不一定要强调。可以把它想像成书中突出显示的一节。Google 的缓存页面就是典型的用例。如果链接到一个缓存的副本,搜索词就被加上标志。例如,如果搜索 “Egret”,那么缓存的 Google 页面可能像下面这样:

The Great <m>Egret</m>
(also known as the American <m>Egret</m>)
 is a large white wading bird found worldwide. The Great <m>Egret</m> flies with slow wing beats.
The scientific name of the Great <m>Egret</m> is <i>Casmerodius albus</i>.

对于这个元素的名称当前还有争议。在规范发布之前,它可能从 m 改为 mark

time

time 元素表示一个时间值,比如 5:35 P.M., EST, April 23, 2007。例如:

<p>I am writing this example at <time>5:35 P.M. on April 23rd</time>. </p>

time 元素可以帮助浏览器和其他程序识别出 HTML 页面中的时间。它不要求对元素内容应用任何特定的格式。但是,每个 time 元素都应该有一个 datetime 属性,其中包含更适合机器识别的时间值,比如:

<p>I am writing this example at <time datetime="2007-04-23T17:35:00-05:00">5:35 P.M. on April 23rd</time>. </p>

适合机器读取的时间值可能对搜索引擎、日历程序等有帮助。

meter

meter 元素表示指定范围内的数字值。例如,可以用它表示薪水、投票给 Le Pen 的法国选民的百分比或考试分数。在这里,我使用 meter 标出 Software Development 2007 上一位 Google 程序员提供的数据:

<p>An entry level programmer in Silicon Valley  can expect to start around <meter>$90,000</meter> per year. </p>

meter 元素帮助浏览器和其他客户机识别 HTML 页面中的数量。它不要求对元素内容应用任何特定的格式。但是,每个 meter 元素可以有最多 6 个属性,它们按照更适合机器识别的形式表示这个数量:

  • value
  • min
  • low
  • high
  • max
  • optimum

这些属性都应该包含一个十进制数字。例如,期末考试的分数可以写成下面这样:

<p>Your score was  <meter value="88.7" min="0" max="100" low="65" high="96" optimum="100">B+</meter>. </p>

这表示这个学生的分数是百分制中的 88.7。可能的最低分数是 0,但是实际的最低分数是 65。可能的最高分数是 100,但是实际的最高分数是 96。用户代理可以用某种数值控件显示这一信息,也可以在工具提示中显示额外的数据,但是最常见的情况可能是像其他内联元素一样对它应用样式。

progress

progress 元素表示一个正在进行的过程的状态,就像图形用户界面(GUI)应用程序中的进度条。例如,可以用它表示一个文件已经下载的百分比或者播放电影时的当前位置。下面这个进度控件表示下载已经完成了 33%:

<p>Downloaded:    <progress value="1534602" max="4603807">33%</progress> </p>

value 属性表示操作的当前状态。max 属性表示操作的总量。这个元素指出要下载的数据总量是 4,603,807 字节,已经下载了 1,534,602 字节。

忽略 max 属性,就可以显示无限的进度。

在操作进行时,应该使用 JavaScript 语言动态地更新进度条。在静态情况下,这个元素没什么意义。


回页首

内嵌的媒体

视频已经在 Web 上广泛流行了,但是其格式几乎都是专有的。YouTube 使用 Flash,Microsoft 使用 Windows Media?,Apple 使用 QuickTime。在一种浏览器中用来嵌入这些内容的标记在另一种浏览器中是无效的。因此,WhatWG 提议引入一个新的 video 元素,用来嵌入任意视频格式。例如,可以用以下代码嵌入我的 QuickTime 电影 “a Sora in Prospect Park”:

<video src="http://www.cafeaulait.org/birds/sora.mov" mce_src="http://www.cafeaulait.org/birds/sora.mov" />

对于以哪种格式和解码器作为首选,仍然有争议。可能会强力推荐或要求使用 Ogg Theora。还可以可选地支持 QuickTime 等专有格式和 MPEG-4 等受专利限制的格式。实际使用的格式很可能由市场决定,就像是 GIF、JPEG 和 PNG 格式那样(这些格式通过市场竞争压倒了 BMP、X-Bitmap 和 JPEG 2000 等竞争者,成为 img 元素的首选格式)。

还提议引入 audio 元素。例如,可以使用以下代码给 Web 页面加上背景音乐:

<audio src="spacemusic.mp3" mce_src="spacemusic.mp3"     autoplay="autoplay" loop="20000" />

autoplay 属性指示浏览器在装载页面后立即开始播放,而不等待明确的用户请求。音频循环播放 20,000 次,然后停止(或者在用户关闭窗口或转到另一个页面时停止)。当然,浏览器可以(而且应该)允许用户关闭内嵌的媒体,不应该只按页面作者的要求去做。

浏览器必须支持 WAV 格式,还可以支持 MP3 等其他格式。

因为老式浏览器不支持这些元素,而且它们对于盲人和聋人用户来说没有意义,所以 audiovideo 元素可以包含额外的标记,用来描述音频和视频的内容。这对搜索引擎也有帮助。在理想情况下,这些标记是音频和视频内容的完整文字版本。例如,清单 8 显示 John F. Kennedy 的就职演说。
清单 8. 用 HTML 5 编写的 John F. Kennedy 的就职演说

  <audio src="kennedyinauguraladdrees.mp3" mce_src="kennedyinauguraladdrees.mp3">
  <p> Vice President Johnson, Mr. Speaker, Mr. Chief Justice, President Eisenhower, Vice President Nixon,
  President Truman, Reverend Clergy, fellow citizens: </p>
  <p> We observe today not a victory of party, but a celebration of freedom -- symbolizing an end, as well as
  a beginning -- signifying renewal, as well as change. For I have sworn before you and Almighty God the same
  solemn oath our forebears prescribed nearly a century and three-quarters ago.
  </p>
  <p> The world is very different now. For man holds in his mortal hands the power to abolish all forms of human
  poverty and all forms of human life. And yet the same revolutionary beliefs for which our forebears fought are
  still at issue around the globe --      the belief that the rights of man come not from the generosity of the
  state, but from the hand of God.
  </p>
  <p>     ...     </p>
  </audio>

回页首

交互

HTML 5 也被称为 Web Applications 1.0。为了实现这个目标,增加了几个为 Web 页面提供交互体验的新元素:

  • details
  • datagrid
  • menu
  • command

这些元素都可以根据用户的操作和选择改变显示的内容,而不需要从服务器装载新页面。

details

details 元素表示在默认情况下可能不显示的详细信息。可选的 legend 元素可以提供详细信息的摘要。details 元素的用途之一是提供脚注和尾注。例如:

The bill of a Craveri's Murrelet is about 10% thinner  than the bill of a Xantus's Murrelet.
<details> <legend>[Sibley, 2000]</legend> <p>Sibley, David Allen, The Sibley Guide to Birds,
(New York: Chanticleer Press, 2000) p. 247  </p> </details>

没有指定具体的显示方式。浏览器可以选用脚注、尾注和工具提示等方式。

每个 details 元素可以有一个 open 属性。如果设置了这个属性,那么详细信息在最初就显示出来。如果没有设置这个属性,那么会隐藏它们,直到用户要求显示它们。无论是哪种情况,用户都可以通过单击一个图标或其他控件来显示或隐藏详细信息。

datagrid

datagrid 元素提供一个网格控件。可以用它显示树、列表和表格,用户和脚本可以更新这些界面元素。与之相反,传统的表格主要用来显示静态数据。

datagrid 从它的内容(一个 tableselect 或其他 HTML 元素)获得初始数据。例如,清单 9 中的 datagrid 包含一张成绩表。在这个示例中,datagrid 的数据来自一个 table。更简单的一维 datagrid 可以从 select 元素获得数据。如果使用其他 HTML 元素,那么每个子元素成为网格中的一行。
清单 9. 成绩表 datagrid

  <datagrid>
  <table>
  <tr><td>Jones</td><td>Allison</td><td>A-</td><td>B+</td><td>A</td></tr>
  <tr><td>Smith</td><td>Johnny</td><td>A</td><td>C+</td><td>A</td></tr>
  <tr><td>Willis</td><td>Sydney</td><td>C-</td><td>D</td><td>F</td></tr>
  <tr><td>Wilson</td><td>Frank</td><td>B-</td><td>B+</td><td>A</td></tr>
  </table> </datagrid>

这个元素与常规表格的区别在于,用户可以选择行、列和单元格;把行、列和单元格折叠起来;编辑单元格;删除行、列和单元格;对网格排序;以及在客户机浏览器中直接进行其他数据操作。可以用 JavaScript 代码监视更新。Document Object Model(DOM)中增加了 HTMLDataGridElement 接口以支持这个元素(清单 10)。
清单 10. HTMLDataGridElement

  interface HTMLDataGridElement : HTMLElement { attribute DataGridDataProvider data;
  readonly attribute DataGridSelection selection; attribute boolean multiple; attribute boolean disabled;
  void updateEverything();   void updateRowsChanged(in RowSpecification row, in unsigned long count);
  void updateRowsInserted(in RowSpecification row, in unsigned long count);   void updateRowsRemoved(in
  RowSpecification row, in unsigned long count);   void updateRowChanged(in RowSpecification row);
  void updateColumnChanged(in unsigned long column);   void updateCellChanged(in RowSpecification row,
  in unsigned long column); };

还可以使用 DOM 在网格中动态地装载数据。也就是说,datagrid 可以不包含那些提供初始数据的子元素。可以用一个 DataGridDataProvider 对象设置它(清单 11)。这样就可以从数据库、XmlHttpRequest 或者 JavaScript 代码能够访问的任何资源装载数据。
清单 11. DataGridDataProvider

  interface DataGridDataProvider {   void initialize(in HTMLDataGridElement datagrid);   unsigned long
  getRowCount(in RowSpecification row);   unsigned long getChildAtPosition(in RowSpecification parentRow,
  in unsigned long position);   unsigned long getColumnCount();   DOMString getCaptionText(in unsigned
  long column);   void getCaptionClasses(in unsigned long column, in DOMTokenList classes);
  DOMString getRowImage(in RowSpecification row);   HTMLMenuElement getRowMenu(in RowSpecification row);
  void getRowClasses(in RowSpecification row, in DOMTokenList classes);   DOMString getCellData
  (in RowSpecification row, in unsigned long column);   void getCellClasses(in RowSpecification row,
  in unsigned long column, in DOMTokenList classes); void toggleColumnSortState(in unsigned long column);
   void setCellCheckedState(in RowSpecification row, in unsigned long column,        in long state);
  void cycleCell(in RowSpecification row, in unsigned long column);   void editCell(in RowSpecification row,
  in unsigned long column, in DOMString data); };

menu 和 command

menu 元素实际上在 HTML 2 中就出现了。在 HTML 4 中废弃了它,但是 HTML 5 又恢复了它并指定了新的意义。在 HTML 5 中,menu 包含 command 元素,每个 command 元素引发一个操作。例如,清单 12 是一个弹出警告框的菜单。
清单 12. HTML 5 菜单

   <menu>
  <command onclick="alert('first command')"  label="Do 1st Command"/>     <command onclick="alert('second command')"
  label="Do 2nd Command"/>     <command onclick="alert('third command')"  label="Do 3rd Command"/> </menu>

还可以用 checked="checked" 属性将命令转

No Comments | Tags: , ,

把应用程序从 Internet Explorer 迁移到 Mozilla

使特定于 Internet Explorer 的 Web 应用程序在 Mozilla 上运行时,您遇到过麻烦吗?本文讨论了将应用程序迁移到基于开源 Mozilla 浏览器上时的常见问题。首先讨论跨浏览器开发的基本技术,然后介绍克服 Mozilla 和 Internet Explorer 之间差异的策略。
Netscape 最初开发 Mozilla 浏览器的时候,明智地决定支持 W3C 标准。因此,Mozilla 和 Netscape Navigator 4.x 以及 Microsoft Internet Explorer 遗留代码不完全向后兼容,比如后面将提到 Mozilla 不支持 。Internet Explorer 4 这些在 W3C 标准的概念出现之前建立的浏览器继承了很多古怪之处。本文中将讨论 Mozilla 的特殊模式,它为 Internet Explorer 和其他遗留浏览器提供了强大的 HTML 向后兼容功能。

我还将讨论 Mozilla 支持的非标准技术,如 XMLHttpRequest 和富文本编辑,因为当时 W3C 还没有对应的标准。其中包括:

HTML 4.01 和 XHTML 1.0/1.1
级联样式表(CSS):CSS Level 1、CSS Level 2 以及 CSS Level 3 的部分。
文档对象模型(DOM):DOM Level 1、 DOM Level 2 和 DOM Level 3 的部分
数学标记语言:MathML Version 2.0
可扩展标记语言(XML):XML 1.0、Namespaces in XML、Associating Style Sheets with XML Documents 1.0、Fragment Identifier for XML
XSL 转换:XSLT 1.0
XML Path 语言:XPath 1.0
资源描述框架:RDF
简单对象访问协议:SOAP 1.1
ECMA-262 修订版 3(JavaScript 1.5):ECMA
通用的跨浏览器编码技巧

虽然存在 Web 标准,但不同浏览器的行为并不完全相同(实际上同一个浏览器在不同的平台上行为也不相同)。很多浏览器,如 Internet Explorer 依然支持 W3C 之前的、从未在 W3C 符合浏览器中获得广泛支持的 API。

深入讨论 Mozilla 和 Internet Explorer 的区别之前,首先介绍一下使 Web 应用程序具备可扩展性以便日后增加新浏览器支持的一些基本方法。

因为不同的浏览器有时会为同样的功能使用不同的 API,因此经常会在代码中看到很多 if() else() 块,来区别对待不同的浏览器。下面的代码块用于 Internet Explorer:

. . .

var elm;

if (ns4)
?elm = document.layers["myID"];
else if (ie4)
?elm = document.all["myID"];

上述代码不具备可扩展性,如果需要支持新的浏览器,必须修改 Web 应用程序中所有这样的代码块。

避免为新浏览器重新编码最简单的办法就是抽象功能。不要使用层层嵌套的 if() else() 块,把通用的任务抽象成单独的函数可以提高效率。这样不但代码更易于阅读,还便于增加新客户机支持:

var elm = getElmById(“myID”);

function getElmById(aID){
?var element = null;

if (isMozilla || isIE5)
? ?element = document.getElementById(aID)
?else if (isNetscape4)
? element = document.layers[aID]
?else if (isIE4)
? element = document.all[aID];

return element;
}

上述代码仍然存在浏览器嗅探 或者检测用户使用何种浏览器的问题。浏览器嗅探一般通过用户代理完成,比如:

Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.5) Gecko/20031016

虽然使用用户代理来嗅探浏览器提供了所用浏览器的详细信息,但是出现新的浏览器版本时处理用户代理的代码可能出错,因而需要修改代码。

如果浏览器的类型无关紧要(假设禁止不支持的浏览器访问 Web 应用程序),最好通过浏览器本身的能力来嗅探。一般可以通过测试需要的 JavaScript 功能来完成。比如,与其使用:

if (isMozilla || isIE5)

不如用:

if (document.getElementById)

这样不用任何修改,在其他支持该方法的浏览器如 Opera 或 Safari 上也能工作。

但是如果准确性很重要,比如要验证浏览器是否满足 Web 应用程序的版本要求或者尝试避免某个 bug,则必须使用用户代理嗅探。

JavaScript 还允许使用内嵌条件语句,有助于提高代码的可读性:

var foo = (condition) ? conditionIsTrue : conditionIsFalse;

比如,要检索一个元素,可以用如下代码:

function getElement(aID){
? return (document.getElementById) ? document.getElementById(aID)
? : document.all[aID];
}

Mozilla 和 Internet Explorer 的区别

首先讨论 Mozilla 和 Internet Explorer 在 HTML 行为方式上的区别。

工具提示

遗留浏览器在 HTML 中引入了工具提示,在链接上显示 alt 属性作为工具提示的内容。最新的 W3C HTML 规范增加了 title 属性,用于包含链接的详细说明。现代浏览器应该使用 title 属性显示工具提示,Mozilla 仅支持用该属性显示工具提示而不能用 alt 属性。

实体

HTML 标记可以包含多种实体,W3 标准体 专门作了规定。可以通过数字或者字符引用来引用这些实体。比如,可以用 #160 或者等价的字符引用 ? 来引用空白字符 。

一些旧式浏览器,如 Internet Explorer,有一些怪异的地方,比如允许用正常文本内容替换实体后面的分号(;):

? Foo
??? Foo

Mozilla 将把上面的 ? 呈现为空格,虽然违反了 W3C 规范。如果后面紧跟着更多字符,浏览器就不能解析 ?,如:

?12345

这样的代码在 Mozilla 中无效,因为违反了 W3 标准。为了避免浏览器的差异,应坚持使用正确的形式(?)。

DOM 差异

文档对象模型(DOM)是包含文档元素的树状结构。可以通过 JavaScript API 来操纵它,对此 W3C 已有标准。但是在 W3C 标准化之前,Netscape 4 和 Internet Explorer 4 以类似的方式实现了这种 API。Mozilla 仅实现了 W3C 标准不支持的那些遗留 API。

访问元素

未按照跨浏览器的方式检索元素的引用,应使用 document.getElementById(aID),该方法可用于 Internet Explorer 5.5+、Mozilla,是 DOM Level 1 规范的一部分。

Mozilla 不支持通过 document.elementName 甚至按照元素名来访问元素,而 Internet Explorer 则支持这种方法(也称为全局名称空间污染)。Mozilla 也不支持 Netscape 4 的 document.layers 方法和 Internet Explorer 的 document.all 方法。除了 document.getElementById 可以检索元素之外,还可用 document.layers 和 document.all 获得具有特定标签名称的全部文档元素列表,比如所有的

元素。W3C DOM Level 1 使用 getElementsByTagName() 方法获得所有相同标签名的元素的引用。该方法在 JavaScript 中返回一个数组,可用于 document 元素,也可用于其他节点只检索对应的子树。要获得 DOM 树中所有元素的列表,可使用 getElementsByTagName(*)。

表 1 中列出了 DOM Level 1 方法,大部分用于把元素移动到特定位置或切换其可视性(菜单、动画)。Netscape 4 使用 标签(Mozilla 不支持)作为可以任意定位的 HTML 元素。在 Mozilla 中,可使用

标签定位元素,Internet Explorer 也用它,HTML 规范中也包含它。表 1. 用于访问元素的方法 方法 说明
document.getElementById( aId ) 返回具有指定 ID 的元素的引用。
document.getElementsByTagName( aTagName ) 返回文档中具有指定名称的元素数组。

遍历 DOM

Mozilla 通过 JavaScript 支持遍历 DOM 树的 W3C DOM API(如表 2 所示)。文档中每个节点都可使用这些 API 方法,可以在任何方向上遍历树。Internet Explorer 也支持这些 API,还支持原来用于遍历 DOM 树的 API,比如 children 属性。

表 2. 用于遍历 DOM 的方法 属性/方法 说明
childNodes 返回元素所有子节点的数组。
firstChild 返回元素的第一个子节点。
getAttribute( aAttributeName ) 返回指定属性的值。
hasAttribute( aAttributeName ) 返回一个 Boolean 值表明当前节点是否包含指定名称的属性。
hasChildNodes() 返回一个布尔指表明当前节点是否有子节点。
lastChild 返回元素的最后一个子节点。
nextSibling 返回紧接于当前节点之后的节点。
nodeName 用字符串返回当前节点的名称。
nodeType 返回当前节点的类型。
值 说明
1 元素节点
2 属性节点
3 文本节点
4 CDATA 选择节点
5 实体引用节点
6 实体节点
7 处理指令节点
8 注释节点
9 文档节点
10 文档类型节点
11 文档片断节点
12 符号节点

nodeValue 返回当前节点的值。对于包含文本的节点,如文本和注释节点返回其字符串值。对于属性节点返回属性值。其他节点返回 null。
ownerDocument 返回包含当前节点的 document 对象。
parentNode 返回当前节点的父节点。
previousSibling 返回当前节点之前的相邻节点。
removeAttribute( aName ) 从当前节点中删除指定的属性。
setAttribute( aName, aValue ) 设置指定属性的值。

Internet Explorer 有一种非标准的特殊行为,这些 API 很多跳过(比如)新行字符生成的空白文本节点。Mozilla 则不跳过,因此有时候需要区分这些节点。每个节点都有一个 nodeType 属性指定了节点类型。比如,元素节点类型是 1,文本节点是 3,而注释节点是 8。仅处理元素节点最好的办法是遍历所有子节点,然后处理那些 nodeType 为 1 的节点:

HTML:

? Test
?c

JavaScript:
? var myDiv = document.getElementById(“foo”);
? var myChildren = myXMLDoc.childNodes;
? for (var i = 0; i < myChildren.length; i++) {
? if (myChildren[i].nodeType == 1){
? // element node
? }
? }

生成和操纵内容

Mozilla 支持向 DOM 动态增加内容的遗留方法,如 document.write、document.open 和 document.close。Mozilla 也支持 Internet Explorer 的 InnerHTML 方法,该方法基本上可以在任何节点上使用。但是不支持 OuterHTML(围绕着元素添加标记,标准中也没有等价的方法)和 innerText(设置节点的文本值,在 Mozilla 中可使用 textContent)。

Internet Explorer 有一些非标准的、Mozilla 不支持的内容操作方法,包括检索值、插入文本以及邻近某个节点插入元素,比如 getAdjacentElement 和 insertAdjacentHTML。表 3 说明了 W3C 标准和 Mozilla 操纵内容的方法,这些方法适用于任何 DOM 节点。

表 3. Mozilla 用于操纵内容的方法 方法 说明
appendChild( aNode ) 创建新的子节点。返回新建子节点的引用。
cloneNode( aDeep ) 创建调用节点的副本并返回。如果 aDeep 为 true,则复制该节点的整个子树。
createElement( aTagName ) 创建并返回一个 aTagName 指定类型的无父 DOM 节点。
createTextNode( aTextValue ) 创建并返回一个新的无父 DOM 文本节点,值由 aTextValue 指定。
insertBefore( aNewNode, aChildNode ) 在 aChildNode 前插入 aNewNode,前者必须是当前节点的子节点。
removeChild( aChildNode ) 删除 aChildNode 并返回对它的引用。
replaceChild( aNewNode, aChildNode ) 用 aNewNode 替换 aChildNode 并返回被删除节点的引用。

文档片断

出于性能方面的原因,可以在内存中创建文档而不是处理已有文档的 DOM。DOM Level 1 Core 引入了文档片断,这是一种轻型文档包含一般文档接口的一个子集。比如没有 getElementById 但是有 appendChild。很容易向已有文档添加文档片断。

Mozilla 使用 document.createDocumentFragment() 创建文档片断,该方法返回一个空的文档片断。

但是,Internet Explorer 的文档片断实现没有遵循 W3C 标准,仅仅返回一般的文档。

JavaScript 差异

Mozilla 和 Internet Explorer 的多数差异都和 JavaScript 有关。但问题通常源自浏览器向 JavaScript 公开的 API,比如 DOM 钩子。两种浏览器在核心 JavaScript 上区别不大,遇到的问题通常和时间有关。

JavaScript date 差异

Date 惟一的区别是 getYear 方法。根据 ECMAScript 规范(这是 JavaScript 所遵循的规范),该方法没有解决千年问题,在 2004 年运行 new Date().getYear() 将返回“104”。根据 ECMAScript 规范,getYear 返回的年份减去 1900 最初是为了在 1998 年返回“98”。ECMAScript Version 3 废止了 getYear,用 getFullYear() 代替。Internet Explorer 修改了 getYear() 使其和 getFullYear() 类似,消除了千年问题,而 Mozilla 坚持采用标准的行为方式。

JavaScript 执行差异

不同的浏览器执行 JavaScript 的方式是不同的。比如,下列代码假设 script 块执行的时候 div 节点已经存在于 DOM 中:

Loading…

但是并不能保证这一点。为了保证所有的元素已经存在,应该对 元素使用 onload 事件处理程序:

Loading…


这类与时间有关的问题也和硬件有关,速度慢的系统可能会发现速度快的系统隐藏起来的 bug。一个具体的例子是 window.open,它打开新的窗口:

这段代码的问题在于 window.open 是异步的,在窗口打开之前没有阻塞 JavaScript 的执行。因此,window.open 后面的行有可能在新窗口打开之前执行。可以在新窗口的 onload 处理程序中解决这个问题,然后回调打开它的窗口(使用 window.opener)。

JavaScript 生成 HTML 的差别

JavaScript 可以通过 document.write 即时用字符串生成 HTML。主要的问题在于,如果内嵌在 HTML 文档(因此也在一个 解释成外层 “)

由于该页面采用严格模式,Mozilla 解析器就会看到第一个 。这是因为解析器不知道 JavaScript(或者其他任何语言)何时采用严格模式。在特殊模式下,解析器在解析的过程中分析 JavaScript(因而降低了速度)。Internet Explorer 总是采用特殊模式,因此不真正支持 XHTML。为了在 Mozilla 中使用严格模式,需要将字符串分解成两部分:

?”http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

调试 JavaScript

Mozilla 提供了多种方法调试为 Internet Explorer 创建的应用程序中的 JavaScript 相关问题。第一个工具是内置的 JavaScript 控制台,如图 1 所示,它记录了错误和警告信息。在 Mozilla 中选择 Tools -> Web Development -> JavaScript Console,或者在 Firefox(来自 Mozilla 的独立浏览器产品)中选择 Tools -> JavaScript Console 就能打开它。

图 1. JavaScript 控制台

JavaScript 控制台可以显示完整的日志列表,也可以分别显示错误、警告和消息。图 1 中的错误消息表明,aol.com 第 95 行访问的变量 is_ns70 不存在。单击该链接可以打开 Mozilla 内部的查看源代码窗口,突出显示出错的一行。

控制台还允许对 JavaScript 求值。要计算输入的 JavaScript 语法,在输入字段中输入 1+1 然后按 Evaluate,结果如图 2 所示。

图 2. JavaScript 控制台求值

Mozilla 的 JavaScript 引擎内建了对调试的支持,从而为 JavaScript 开发人员提供了强大的工具。图 3 所示的 Venkman 是一种强大的跨平台 JavaScript 调试器,它与 Mozilla 集成在一起。它通常和 Mozilla 发行包捆绑在一起,可以通过选择 Tools -> Web Development -> JavaScript Debugger 打开它。Firefox 没有捆绑这个调试器,但是可以从 http://www.mozilla.org/projects/venkman/ 下载安装。还可以在开发页面上找到相关教程,开发页面的 URL 为 http://www.hacksrus.com/~ginda/venkman/。

图 3. Mozilla 的 JavaScript 调试器

JavaScript 调试器可以调试在 Mozilla 浏览器窗口中运行的 JavaScript。它支持断点管理、查看调用栈和变量/对象检查这样的标准调试特性。所有特性都可通过用户界面或者调试器的交互控制台来访问。通过控制台,可以在和调试的 JavaScript 代码同一作用域内执行任何 JavaScript。

CSS 差异

和 Internet Explorer 及其他浏览器相比,Mozilla 对级联样式表(CSS)的支持是最好的,包括 CSS1、CSS2 的全部和 CSS3 的一部分。

对于下面提到的多数问题,Mozilla 都会在 JavaScript 控制台中添加错误或警告记录。如果遇到和 CSS 有关的问题请检查 JavaScript 控制台。

Mimetypes(如果未应用 CSS 文件)

与 CSS 有关的最常见的问题就是:未应用所引用的 CSS 文件中的 CSS 定义。这通常是因为服务器为 CSS 文件提供了错误的 mimetype。CSS 规范指出,CSS 文件的 MIME 类型应该是 text/css。Mozilla 遵守这一点,在严格标准模式下只有这种 MIME 类型的 CSS 文件才会被加载。Internet Explorer 总是加载 CSS 文件,无论使用什么 mimetype。如果以严格的文档类型开始,则该网页被认为是严格标准模式。为了解决这个问题,可以让服务器发送正确的 mimetype 或者删除文档类型。下一节将进一步讨论文档类型。

CSS 和单位

很多 Web 应用程序没有在 CSS 中使用单位,尤其是如果使用 JavaScript 设置 CSS。Mozilla 允许这样做,只要页面不以严格模式呈现。因为 Internet Explorer 不支持真正的 XHTML,没有指定单位也不必担心。如果页面处于严格标准模式而没有使用单位,则 Mozilla 将忽略该样式:

? “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”>

?
? // works in strict mode

? Text ?

// will fail in strict mode

? Text ?

因为上面的例子使用了严格的文档类型,页面以严格标准模式呈现。第一个 div 的宽度为 40px,因为使用了单位;但是第二个 div 没有设置宽度,因此使用默认值 100%。如果通过 JavaScript 设置宽度,情况也是一样。

JavaScript 和 CSS

因为 Mozilla 支持 CSS 标准,它也支持通过 JavaScript 设置 CSS 的 CSS DOM 标准。可以通过元素的 style 成员访问、删除和修改元素的 CSS 规则:

? Text

通过这种方法可以访问每一个 CSS 属性。同样,如果网页采用严格模式,就必须设置单位,否则 Mozilla 将忽略该命令。

在 Mozilla 和 Internet Explorer 中查询一个值,比如说 .style.width,返回值也包含单位,就是说是一个字符串。可用 parseFloat(“40px”) 将字符串转换成数字。

CSS 溢出的区别

CSS 增加了溢出的概念,允许定义如何处理溢出;比如,如果指定高度的 div 的实际高度超出的时候。 height.CSS 标准规定如果这种情况下没有定义溢出行为,则 div 内容就会溢出。但是,Internet Explorer 没有遵循这一点,而是扩展 div 的高度以便容纳其内容。下面的例子说明了这种差异:

? a ?

从图 4 可以看出,Mozilla 是按照标准规定处理的。标准规定,这种情况下内层的 div 溢出到底线,因为内层的内容比外层元素还高。如果愿意采用 Internet Explorer 的方式,只要不指定外层元素的高度即可。

图 4. DIV 溢出

悬停差异

Internet Explorer 的非标准 CSS 悬停行为出现在很多 IBM 网站上。Mozilla 中悬停的时候一般通过改变文本样式来表明自身,但是 Internet Explorer 没有这种行为。这是因为 a:hover CSS 选择器在 Internet Explorer 中和 匹配,但是与 不匹配,后者在 HTML 用于建立锚链接元素。文本变化是因为作者用锚设置标记包围了该区域:

CSS:
a:hover {color:green;}

HTML:
This should turn green when you hover over it.


?This should change color when hovered over, but doesn’t
? in Internet Explorer.

Mozilla 正确地遵循了 CSS 规范,该例中文本的颜色变成绿色。有两种方法可以让 Mozilla 的行为和 Internet Explorer 一样,即悬停的时候不改变文本颜色:

首先将 CSS 规则改为 a:link:hover {color:green;},这样只有链接(带有 href 属性)才会改变颜色。
或者修改标记在文本开始之前加入 ,修改后锚仍然能正常工作。

特殊模式与标准模式

老的浏览器如 Internet Explorer 4 在特定情况下会以所谓的特殊模式呈现。虽然 Mozilla 的目标是成为符合标准的浏览器,但是提供了三种模式支持带有这些特异行为的较老的网页。页面的内容和交付决定了 Mozilla 使用哪种模式。Mozilla 在 View -> Page Info(或 Ctrl-i)中列出呈现模式。页面选择哪种模式取决于文档类型。

文档类型(doctypes,即文档类型声明的缩写)如下所示:
蓝色部分称为公共标识符,绿色的部分称为系统标识符,是一个 URI。

标准模式

标准模式是最严格的呈现模式,根据 W3C HTML 和 CSS 规范呈现页面,不支持任何特异情况。如果满足下列条件,Mozilla 使用该模式:

如果页面以 text/xml mimetype 或者其他 XML 或 XHTML mimetype 发送
IBM 文档类型之外的任何“DOCTYPE HTML SYSTEM”文档类型(比如 )
没 DTD 的文档类型或未知的文档类型
准标准模式

Mozilla 引入准标准模式有一个原因:CSS 2 中的一部分破坏了基于小图片在表格中精确布局的设计。不是为用户组成一幅完整的图片,而是在每个小图片后面都带一段间隙。图 5 所示的旧的 IBM 主页给出了一个例子。

图 5. 图片间隙

除了图片间隙问题外,准标准模式基本上和标准模式完全相同。这个问题常常出现在符合标准的页面上,并造成不正确的显示。

Mozilla 在下列情况下使用准标准模式。

任何 “宽松” 文档类型(如 、)
IBM 文档类型()
请阅读相关资料进一步了解 图片间隙问题。

特殊模式

目前 Web 上到处充斥着不合法的 HTML 标记以及依靠浏览器的缺陷工作的标记。早在老的 Netscape 浏览器当还是市场领先者的时候就有这方面缺陷。Internet Explorer 出现时,为适应当时的内容而模仿了这些缺陷。随着新的浏览器进入市场,原来的这些缺陷,通常称为特异情况(quirks),为保持向后兼容大部分保留了下来。Mozilla 在特殊呈现模式中支持很多这样的特异情况。要注意,由于这些特异情况,页面与完全符合标准的情形相比呈现速度更慢。多数网页都用这种模式呈现。

Mozilla 在下面情况下使用特殊模式:

没有指定文档类型
文档类型没有系统标识符(比如 )
如果希望进一步了解相关内容,请阅读 List of Quirks 和 List of Doctypes and What Modes They Cause。

事件差异

在事件方面,Mozilla 和 Internet Explorer 几乎完全不同。Mozilla 事件模型按照 W3C 和 Netscape 模型。在 Internet Explorer 中,如果从事件中调用一个函数,可以通过 window.event 访问 event 对象。Mozilla 把 event 对象传递给事件处理程序。必须通过参数把该对象明确传递给调用的函数。下面是一个跨浏览器事件处理的例子:

Click me!

事件对象公开的属性和函数的名称在 Mozilla 和 Internet Explorer 中也常常不同,如表 4 所示。

表 4. Mozilla 和 Internet Explorer 中的事件属性 Internet Explorer 名称 Mozilla 名称 说明
altKey altKey 布尔属性,表示事件过程中是否按下了 alt 键。
cancelBubble stopPropagation() 用于停止事件进一步沿树上行。
clientX clientX 事件的 X 坐标,相对于客户机。
clientY clientY 事件的 Y 坐标,相对于客户机。
ctrlKey ct>Mozilla 1.3 实现了 Internet Explorer 的 designMode 特性,将 HTML 文档变成了一个富文本编辑器字段。变成了编辑器之后,就可以通过 execCommand 在文档上执行命令。Mozilla 不支持 Internet Explorer 的 contentEditable 属性,后者允许编辑任何组件。可以使用 iframe 增加富文本编辑器。

富文本差异

Mozilla 支持通过 IFrameElm.contentDocument 访问 iframe 文档对象的 W3C 标准,而 Internet Explorer 要求通过 document.frames["name"] 访问它,然后再访问最终得到的 document:

function getIFrameDocument(aID){
var rv = null;

// if contentDocument exists, W3C compliant (Mozilla)
if (document.getElementById(aID).contentDocument){
?rv = document.getElementById(aID).contentDocument;
} else {
?// IE
??rv = document.frames[aID].document;
}

return rv;
?}

Mozilla 和 Internet Explorer 的另一个区别是富文本编辑器所创建的 HTML。Mozilla 默认对生成的标记使用 CSS。但是,Mozilla 允许使用 useCSS execCommand 分别改为 true 和 false 来在 HTML 和 CSS 之间切换。Internet Explorer 总是使用 HTML 标记。

Mozilla (CSS):
Big Blue

Mozilla (HTML):
Big Blue

Internet Explorer:
Big Blue

下面列出了 Mozilla 支持的 execCommand 命令:

表 6. 富文本编辑命令 命令名 说明 参数
bold 决定所选内容是否以粗体显示。 —
createlink 从选中的文本创建 HTML 链接。 链接的 URL
delete 删除所选内容。 —
fontname 改变所选文本使用的字体。 使用的字体名(比如 Arial)
fontsize 改变所选文本的字体大小。 使用的字体大小
fontcolor 改变所选文本使用的字体颜色。 使用的颜色
indent 缩进光标所在的块。 —
inserthorizontalrule 在鼠标位置插入


元素。 —
insertimage 在鼠标位置插入图片。 图片的 URL
insertorderedlist 在当前位置插入有序列表(

  1. ?
      )元素。 —
      italic 切换所选内容的的斜体属性。 —
      justifycenter 当前行居中对齐。 —
      justifyleft 当前行左对齐。 —
      justifyright 当前行右对齐。 —
      outdent 减少光标所在块的缩进。 —
      redo 恢复撤销的上一个命令。 —
      removeformat 去掉所选内容的全部格式。 —
      selectall 选择富文本编辑器中的全部内容。 —
      strikethrough 切换所选文本的删除线。 —
      subscript 将当前选择的内容改为下标。 —
      superscript 当前所选内容转化为上标。 —
      underline 添加或删除所选文本的下划线。 —
      undo 撤销上一次执行的动作。 —
      unlink 删除所选内容的链接信息。 —
      useCSS 在生成的标记中使用/不使用 CSS。 布尔值更多信息请访问 DevEdge。

      XML 差异

      Mozilla 对 XML 及 XML 相关技术提供了强大的支持,如 XSLT 和 Web 服务。也支持 Internet Explorer 的一些非标准扩展,如 XMLHttpRequest。

      如何处理 XML

      和标准 HTML 一样,Mozilla 也支持 W3C XML DOM 规范,允许执行 XML 文档大多数方面的操作。和 Internet Explorer XML DOM 的区别多数是由于 Internet Explorer 的非标准行为造成的。可能最常见的一个差别就是处理空白文本节点的方式。生成的 XML 通常在 XML 节点之间带有空白。Internet Explorer 在使用 XMLNode.childNodes[] 的时候不包含这些空白节点。但是在 Mozilla 中,这些节点也包含在数组中。

      XML:


      ?bar

      JavaScript:
      var myXMLDoc = getXMLDocument().documentElement;
      alert(myXMLDoc.childNodes.length);

      JavaScript 的第一行加载 XML 文档并通过检索 documentElement 访问根元素(myXMLDoc)。第二行仅仅告诉您子节点的个数。按照 W3C 规范,相连的空格和新行字符合并为一个文本节点。对于 Mozilla,myXMLdoc 节点有三个孩子:包含新行字符和两个空格的文本节点、myns:foo 节点和包含新行字符的另一个文本节点。但是 Internet Explorer 没有遵守这一点,上面的代码将返回“1”,即 myns:foo 节点。因此要遍历子节点和忽略文本节点,必须区分出这样的节点。

      如前所述,每个节点都有 nodeType 属性表示节点类型。比如,元素节点类型是 1,而文档节点类型是 9。要丢掉文本节点,必须检查类型 3(文本节点)和 8(注释节点)。

      XML:
      ?

      ?bar
      ?

      JavaScript:
      var myXMLDoc = getXMLDocument().documentElement;
      var myChildren = myXMLDoc.childNodes;
      for (var run = 0; run < myChildren.length; run++){
      ?if ( (myChildren[run].nodeType != 3) &&
      (myChildren[run].nodeType != 8) ){
      ?// not a text or comment node
      ?}
      }

      XML 数据岛

      Internet Explorer 有一个非标准特性称为 XML 数据岛,它允许使用非标准 HTML 标签

      Cross-browser solution:
      var xmlString = “ id=\"xmldataisland\">bar”;
      var myDocument;

      if (document.implementation.createDocument){
      ?// Mozilla, create a new DOMParser
      ?var parser = new DOMParser();
      ?myDocument = parser.parseFromString(xmlString, “text/xml”);
      } else if (window.ActiveXObject){
      ?// Internet Explorer, create a new XML document using ActiveX
      ?// and use loadXML as a DOM parser.
      ?myDocument = new ActiveXObject(“Microsoft.XMLDOM”)
      ?myDocument.async=”false”;
      ?myDocument.loadXML(xmlString);
      }

      XML HTTP 请求

      Internet Explorer 允许使用 MSXML 的 XMLHTTP 类发送和检索 XML 文件,该类通过 ActiveX 使用 new ActiveXObject(“Msxml2.XMLHTTP”) 或者 new ActiveXObject(“Microsoft.XMLHTTP”) 进行实例化。由于不存在完成这一任务的标准方法,Mozilla 在 JavaScript 全局对象 XMLHttpRequest 中提供了同等的功能。该对象默认生成异步请求。

      使用 new XMLHttpRequest() 实例化该对象后,可用 open 方法指定使用的请求类型(GET 或 POST)、加载的文件以及是否异步执行。如果采用异步调用,则为 onload 成员提供一个函数引用,请求完成的时候调用它。

      Synchronous request:

      var myXMLHTTPRequest = new XMLHttpRequest();
      ?myXMLHTTPRequest.open(“GET”, “data.xml”, false);
      ?myXMLHTTPRequest.send(null);

      var myXMLDocument = myXMLHTTPRequest.responseXML;

      Asynchronous request:

      var myXMLHTTPRequest;

      function
      ? xmlLoaded
      ? () {
      ? var myXMLDocument = myXMLHTTPRequest.responseXML;
      ?}

      function loadXML(){
      ? myXMLHTTPRequest = new XMLHttpRequest();

      myXMLHTTPRequest.open(“GET”, “data.xml”, true);

      myXMLHTTPRequest.onload =
      ? xmlLoaded
      ? ;

      myXMLHTTPRequest.send(null);
      ?}

      表 7 列出了 Mozilla XMLHttpRequest 提供的方法和属性。

      表 7. XMLHttpRequest 方法和属性 名称 说明
      void abort() 如果请求依然在运行则停止它。
      string getAllResponseHeaders() 用一个字符串返回所有的请求头。
      string getResponseHeader(string headerName) 返回指定头的值。
      functionRef onerror 射之后,请求中发生错误时将调用指定的函数。
      functionRef onload 射之后,请求成功完成并收到响应后将调用引用的函数。用于异步请求。
      void open (string HTTP_Method, string URL)

      void open (string HTTP_Method, string URL, boolean async, string userName, string password) 初始化对指定 URL 的请求,使用 GET 或 POST HTTP 方法。要发送请求需要在初始化之后调用 send() 方法。如果 async 是 false,则请求是同步的,否则默认使用异步请求。如果需要,可以为给定的 URL 指定用户名和口令。
      int readyState 请求的状态。可能值包括:0 UNINITIALIZED —— 尚未调用 open()。
      1 LOADING —— 尚未调用 send()。
      2 LOADED —— 调用了 send(),头和状态可用。
      3 INTERACTIVE —— 下载中,responseText 保存下载的部分数据。
      4 COMPLETED —— 全部操作已完成。

      string responseText 包含响应字符串。
      DOMDocument responseXML 包含响应 DOM Document。
      void send(variant body) 发起请求。如果定义了 body,则作为 POST 请求体发送。body 可以是 XML 文档或者序列化 XML 文档的字符串。
      void setRequestHeader (string headerName, string headerValue) 设置 HTTP 请求头以便在 HTTP 请求中使用。必须在 open() 之后调用。
      string status HTTP 请求的状态码。

      XSLT 差异

      Mozilla 支持 XSL Transformations(XSLT)1.0。还允许 JavaScript 执行 XSLT 转换和对文档运行 XPATH。

      Mozilla 要求使用 XML mimetype(text/xml 或 application/xml)发送 XML 和包含样式表的 XSLT 文件。这也是 XSLT 不能在 Mozilla 而能在 Internet Explorer 中运行的主要原因之一。Mozilla 在这方面很严格。

      Internet Explorer 5.0 和 5.5 支持 XSLT 工作草案,后者与最终的 1.0 推荐标准存在根本的区别。判断 XSLT 使用哪一个版本的最简单办法就是查看名称空间。1.0 推荐标准的名称空间是 http://www.w3.org/1999/XSL/Transform,而工作草案的名称空间是 http://www.w3.org/TR/WD-xsl。Internet Explorer 6 为保持向后兼容而支持工作草案,但是 Mozilla 不支持工作草案,仅支持最终推荐标准。

      如果 XSLT 需要判断浏览器,可以查询 “xsl:vendor” 系统属性。Mozilla 的 XSLT 引擎将报告 “Transformiix”,Internet Explorer 则返回 “Microsoft”。






      Mozilla 还为 XSLT 提供了 JavaScript 接口,Web 站点可以在内存中完成 XSLT 转换。可以使用 XSLTProcessor JavaScript 全局对象完成这项工作。XSLTProcessor 需要加载 XML 和 XSLT 文件,因为需要它们的 DOM 文档。XSLTProcessor 导入的 XSLT 文档允许修改 XSLT 参数。XSLTProcessor 可以使用 transformToDocument() 创建标准文档,或者使用 transformToFragment() 生成文档片断,您可轻松地将其添加到其他 DOM 文档中。下面是一个例子:

      var xslStylesheet;
      var xsltProcessor = new XSLTProcessor();

      // load the xslt file, example1.xsl
      var myXMLHTTPRequest = new XMLHttpRequest();
      myXMLHTTPRequest.open(“GET”, “example1.xsl”, false);
      myXMLHTTPRequest.send(null);

      // get the XML document and import it
      xslStylesheet = myXMLHTTPRequest.responseXML;

      xsltProcessor.importStylesheet(xslStylesheet);

      // load the xml file, example1.xml
      myXMLHTTPRequest = new XMLHttpRequest();
      myXMLHTTPRequest.open(“GET”, “example1.xml”, false);
      myXMLHTTPRequest.send(null);

      var xmlSource = myXMLHTTPRequest.responseXML;

      var resultDocument = xsltProcessor.transformToDocument(xmlSource);

      创建 XSLTProcessor 后使用 XMLHttpRequest 加载 XSLT 文件。XMLHttpRequest 的 responseXML 成员包含 XSLT 的文件的 XML 文档,传递给 importStylesheet。然后再使用 XMLHttpRequest 打开需要转换的源 XML 文档,将该文档传递给 XSLTProcessor 的 transformToDocument 方法。表 8 列出了 XSLTProcessor 的方法。

      表 8. XSLTProcessor 方法 方法 说明
      void importStylesheet(Node styleSheet) 导入 XSLT 样式表。styleSheet 参数是 XSLT 样式表 DOM 文档的根节点。
      DocumentFragment transformToFragment(Node source, Document owner) 应用通过 importStylesheet 方法导入的样式表,并生成 DocumentFragment,通过这种方法来转换节点 source。owner 指定了 DocumentFragment 属于哪个 DOM 文档,以便添加到相应的 DOM 文档中。
      Document transformToDocument(Node source) 应用通过 importStylesheet 导入的样式表,并返回一个独立的 DOM 文档,通过这种方法来转换节点 source。
      void setParameter(String namespaceURI, String localName, Variant value) 设置导入的 XSLT 样式表中的参数。
      Variant getParameter(String namespaceURI, String localName) 获得导入 XSLT 样式表的参数值。
      void removeParameter(String namespaceURI, String localName) 从导入的 XSLT 样式表中删除所有已设置的参数,使用 XSLT 定义的默认值。
      void clearParameters() 删除所有已设置的参数并将其设置为 XSLT 样式表的默认参数。
      void reset() 删除所有的参数和样式表。

      结束语

      本文介绍了 Web 应用程序开发人员尝试使其应用程序在基于 Mozilla 的浏览器中工作时面临的常见问题。开发 Web 应用程序时,一定要考虑到可能存在的浏览器差异并牢记在心。参考资料 中提供了两篇很好的参考资料,深入探讨了跨浏览器开发问题。根据这些原则开发的 Web 应用程序可以在其他浏览器乃至其他平台上工作。

  2. )元素。 —
    insertunorderedlist 在光标位置插入无序列表(

No Comments | Tags: ,

互联网的下一代新星-Web3.0先驱

下一个MySpace——Blue Dot(Bluedot.us):?  一位投资者曾经这样评价Blue Dot,从Blue Dot身上,我看到了电子邮件和即时信息工具的影子,它有可能会成为第三代通信工具。当用户在网页上发现自己感兴趣的内容时,只需点击屏幕上的一个蓝点,就可以将其保存下来,并与好友共享。Blue Dot发言人埃林·皮特里(Erin Petrie)表示:通过Blue Dot,你可以了解好友看过什么电影,以及去过哪些餐馆。?  下一个YouTube——Loopt(Loopt.com):?  有一天,21岁的斯坦福大学学生萨姆·阿尔特曼(Sam Altman)在计算机课结束时希望与好友共进午餐。他说:当时我想,如果能通过手机看到每个人的位置就太好了。他随后就开始编写软件,实现了这一功能,并获得了500万美元的风险投资。通过Loopt,手机每15分钟就会向手机基站或卫星发送特定指令,从而确定自己的准确位置。手机所有者可以同好友的手机或计算机共享位置信息,每月只需交纳2.99美元的费用。?  下一个iTunes——Pandora(Pandora.com):?  在加州奥克兰的一间办公室里,很多音乐家都头戴耳机,正通过计算机分析歌曲。他们正在对音乐做有史以来最全面的分析,这一项目名为音乐基因工程。对于每一首歌曲,他们都会分析数百个细节,包括音调、节奏和歌词等等。通过Pandora网站,用户只需提交自己最喜欢的歌曲或艺人名称,就可以找到最相似的歌曲,并像广播电台一样播放。这项服务完全免费,主要通过广告获得营收。到目前为止,Pandora已经拥有400万名听众。?  下一个Google——Powerset(Powerset.com):?  巴尔尼·佩尔(Barney Pell)一直希望实现打造自然语言搜索引擎的梦想。他表示,当前的很多搜索产品,如Google或雅虎的搜索引擎,只能搜索关键字,而不能理解为孩子写的书孩子写的书、以及关于孩子的书之间的区别。自然语言搜索引擎则可以有效地区分功能词汇,从而能提供更加准确、有用的搜索结果。今年38岁的佩尔认为,即将推出的Powerset搜索引擎将成为语义网络的催化剂。?  下一个Craigslist——Yelp(Yelp.com):?  Yelp的主要功能是邀请用户就所有事物,如本地餐馆、商店和医生等等发表评论,并与他人共享。Yelp员工、今年26岁的鲍勃·古德森(Bob Goodson)表示:Yelp借助了口口相传的力量,并通过互联网将这一力量放大。最新数据显示,Yelp上月的访问者人数达到了160万。Yelp计划在美国28个城市开展业务,并可能进军英国市场。(马丁)

No Comments | Tags: , ,

在父元素里清楚浮动

做web标准的朋友可能有时会遇到这样的问题,当出现浮动需要用清除时,在最后一个浮动后面用<div style=”clear:both;”></div>,但是这样写不利于程序的循环,需要把清除浮动写在父元素里边,那就要用到下面的方法了

方法1

div.container { border: 1px solid #000000; overflow: hidden; ?width: 100%; }

div.left { width: 45%; float: left; }

div.right { width: 45%; float: right; }

方法2

.class:after{content:”;display:block;clear:both;}

在ie6中只要定个宽度就可以了

红色部分清楚浮动代码

No Comments | Tags: , , , , , ,

消除链接虚线的方法

一、局部消除?

1.firefox 的链接有时会产生难看的虚线说是因为负值的 text-indent 的缘故,可我怎么觉得是因为 block元素外面没有被限制的原因。可以使用 outline:none 来消除点击链接时的虚线。<a href=”#2″ mce_href=”#2″ style=”display:block;outline:none;”>aaa bb</a>

?

2.IE使用这三种方法消除链接虚线

(1)<a href=”#1″ mce_href=”#1″ hidefocus=”true”>aaa</a>

(2)<a href=”#1″ mce_href=”#1″ style=”nofocus:expression(this.onFocus=this.blur())”>aaa</a>

(3) <a href=”#1″ mce_href=”#1″onfocus=”blur()”>aaa</a>

二、全局消除??????? CSS实现(实践可用)

?????? a{blr:expression(this.onFocus=this.close());} /* 只支持IE,过多使用效率低 */

???????a{blr:expression(this.onFocus=this.blur());} /* 只支持IE,过多使用效率低 */

????? a:focus { -moz-outline-style: none; } /* IE不支持 */

????? HTC实现 IE支持,页面载完才有效果

????? 把下面这段代码存为.htc为扩展名的文件

????? <public:attach event=”onfocus” onevent=”hscfsy()”/>
????? <script language=”javascript”>
???????function hscfsy(){
?????? this.blur();
??????? }
????? </script>

???? 调用 a {behavior:url(htc文件所在路径地址)}

???? JS遍历实现

???? window.onload=function()
????? {
??????? for(var ii=0; ii<document.links.length; ii++)
??????? document.links$[$ii$]$.onfocus=function(){this.blur()}
???? }

???? JS封装为函数

???? function fHideFocus(tName){
?????aTag=document.getElementsByTagName(tName);
??? for(i=0;i<aTag.length;i++)aTag$[$i$]$.hideFocus=true;
??? //for(i=0;i<aTag.length;i++)aTag$[$i$]$.onfocus=function(){this.blur();};
??? }

????? 当前是添加一个hidefocus的属性,注释掉的句子是添加onfucus=this.blur();
????? 然后调用fHideFocus(“A”),即可把a的虚线框去掉
????? 通过传递不同的参数,可以去掉更多的虚线框,比如”BUTTON”可以去掉button的
????? 但要记住参数要用大写字母

????? A. map area内链接如何消除链接虚线?

????? 这是一个观念上的错误,其实应该在所在map的图片上加以控制,而不是在area内,参考传统办法

???? B. 关于onFocus

???? <a href=“http://blog.csdn.net/alonesword/“ onFocus=”this.blur()”>
???? <Img Src=”Example.jpg” Border=0>
????? </a>

????? onFocus是设置鼠标焦点事件的东西,这个可以用,也可以不用,不过为了让更多的浏览器识别的话,建议采用Border=0 这个才是去除虚线框的关键所在

No Comments | Tags: , ,

HTML默认的CSS样式

HTML默认的CSS样式这个东西,在你需要还原默认值的时候,比较有用。

开始的时候 *{margin:0;padding:0;},当需要使用边距的时候,就需要还原HTML默认CSS值了。

以前一直在找这份文档,今天偶然在w3上看到了。除了inline和block的定义,主要是要注意body|h1~h6|blockquote|menu|ul|ol|dd等标签的默认样式(margin和font-size)。
html, address,
blockquote,
body, dd, div,
dl, dt, fieldset, form,
frame, frameset,
h1, h2, h3, h4,
h5, h6, noframes,
ol, p, ul, center,
dir, hr, menu, pre?? { display: block }
li????????????? { display: list-item }
head??????????? { display: none }
table?????????? { display: table }
tr????????????? { display: table-row }
thead?????????? { display: table-header-group }
tbody?????????? { display: table-row-group }
tfoot?????????? { display: table-footer-group }
col???????????? { display: table-column }
colgroup??????? { display: table-column-group }
td, th????????? { display: table-cell; }
caption???????? { display: table-caption }
th????????????? { font-weight: bolder; text-align: center }
caption???????? { text-align: center }
body??????????? { margin: 8px; line-height: 1.12 }
h1????????????? { font-size: 2em; margin: .67em 0 }
h2????????????? { font-size: 1.5em; margin: .75em 0 }
h3????????????? { font-size: 1.17em; margin: .83em 0 }
h4, p,
blockquote, ul,
fieldset, form,
ol, dl, dir,
menu??????????? { margin: 1.12em 0 }
h5????????????? { font-size: .83em; margin: 1.5em 0 }
h6????????????? { font-size: .75em; margin: 1.67em 0 }
h1, h2, h3, h4,
h5, h6, b,
strong????????? { font-weight: bolder }
blockquote????? { margin-left: 40px; margin-right: 40px }
i, cite, em,
var, address??? { font-style: italic }
pre, tt, code,
kbd, samp?????? { font-family: monospace }
pre???????????? { white-space: pre }
button, textarea,
input, object,
select????????? { display:inline-block; }
big???????????? { font-size: 1.17em }
small, sub, sup { font-size: .83em }
sub???????????? { vertical-align: sub }
sup???????????? { vertical-align: super }
table?????????? { border-spacing: 2px; }
thead, tbody,
tfoot?????????? { vertical-align: middle }
td, th????????? { vertical-align: inherit }
s, strike, del? { text-decoration: line-through }
hr????????????? { border: 1px inset }
ol, ul, dir,
menu, dd??????? { margin-left: 40px }
ol????????????? { list-style-type: decimal }
ol ul, ul ol,
ul ul, ol ol??? { margin-top: 0; margin-bottom: 0 }
u, ins????????? { text-decoration: underline }
br:before?????? { content: “\A” }
:before, :after { white-space: pre-line }
center????????? { text-align: center }
abbr, acronym?? { font-variant: small-caps; letter-spacing: 0.1em }
:link, :visited { text-decoration: underline }
:focus????????? { outline: thin dotted invert }

/* Begin bidirectionality settings (do not change) */
BDO[DIR="ltr"]? { direction: ltr; unicode-bidi: bidi-override }
BDO[DIR="rtl"]? { direction: rtl; unicode-bidi: bidi-override }

*[DIR="ltr"]??? { direction: ltr; unicode-bidi: embed }
*[DIR="rtl"]??? { direction: rtl; unicode-bidi: embed }

@media print {
? h1??????????? { page-break-before: always }
? h1, h2, h3,
? h4, h5, h6??? { page-break-after: avoid }
? ul, ol, dl??? { page-break-before: avoid }
}

No Comments | Tags: , ,

CSS Hack总结

CSS Hack是在标准CSS没办法兼容各浏览器显示效果时才会用上的补救方法,在各浏览器厂商解析CSS没有达成一致前,我们只能用这样的方法来完成这样的任务.

在正常的 selector { property:value; } 的基础上常会根据具体情况为相同元素使用Hack以达到浏览器间统一.

IE系列:

  • selector { +property:value; } 在属性名前加上加号”+“,这个Hack只有IE系列可以识别.
  • selector {?*property:value; } 在属性名前加上星号”*“,这个Hack只有IE系列可以识别.
  • selector {?_property:value; } 在属性名前加上下划线”_“,这个Hack只有IE系列 (除IE7外) 识别.
  • *?html selector{?property:value; } 在选择器上运用继承法 * html selector, 这个Hack只有IE系列 (除IE7外) 可以识别.
  • html/**/ >body? selector { property:value; } 在选择器上运用继承法 html/**/ >body? selector ,这个Hack只有IE系列 (除IE7外) 可以识别.
  • selector {?property/**/:value; } 在属性名和冒号”:“之间加入注释,屏蔽IE6用.
  • selector/**/ { property/**/:value; } 在选择器和花括号”{“之间以及在属性名和冒号”:“之间加入注释,屏蔽IE5和IE6用 (不屏蔽IE5.5) .
  • select/**/ { property:value; } 在选择器和花括号”{“之间加入注释,屏蔽IE5用.
  • *+html? selector { property:value !important; } 在选择器上运用继承法 *+html selector 再加上 !important, 这个Hack只有IE7可以识别.
  • div { +property:value; } 在属性名前加上加号”+”,这个Hack只有IE系列可以识别.
    div { *property:value; } 在属性名前加上星号”*”,这个Hack只有IE系列可以识别.
    div { _property:value; } 在属性名前加上下划线”_”,这个Hack只有IE系列 (除IE7外) 识别

Firefox:

  • *:lang(lang) selector {?property:value !important;?}伪类lang(语言)再加上!important进行定义的话,目前只有Firefox可以识别.
  • selctor , x:-moz-any-link, x:default{display: block;}     /* FF3 and IE7 know */

Safari:

  • selector:empty { property:value !important; }伪类empty再加上!important进行定义的话,目前只有Safari可以识别.

Opera:

  • @media all and (min-width: 0px){ selector { property:value; } } 利用特殊继承法进行定义的话,目前只有Opera可以识别.

对Hack的运用,最普遍的是CSS盒模型Hack,清除浮动Hack.

CSS盒模型在IE5.X上是有严重解析错误的.这个Hack针对IE5.X:

selctor { width:IE5.X宽度; voice-family :”\”}\”"; voice-family:inherit; width:正确宽度; }

清除浮动Hack,相信这个定义用的人很多:

selector:after { content:”.”; display:block; height:0; clear:both; visibility:hidden; }

最新更新css终极hack
.e{
color:#FFF;/* FF,OP */
[;color:#0F0;]/* Sa,CH */
color:#FFF\9;/*IE6、7、8*/
*color:#FF0;/* IE7、6 */
_color:#F00;/* IE6 */
}
@media all and(min-width:0){
.e{
background-color:#FF5500;/* OP */
}
}

FF2,FF3的css hacks

FF2:?? a, x:-moz-any-link{FF2 style}

FF3??? a, x:-moz-any-link:default{FF3 style}

No Comments |

my baby

很兴奋,很幸福,第一个真正意义上的博客,等待了太久了,不知道叫你什么 “baby or darling”,还是baby吧!在这里感谢丫头给我了这个空间!

No Comments |

缘分解读

《辞海》“缘分”是因缘、机缘,指出“缘”为梵语,经典解释为“原因”,它常常和“因”一起合称为“因缘”。

一:什么是缘分?有人问隐士。隐士想了一会说:缘是命,命是缘。此人听的糊涂,去问高僧。高僧说:缘是前生的修炼。 这人不解自己的前生如何,就问佛祖。 佛不语,用手指天边的云。这人看去,云起云落,随风东西,于是顿悟:缘不可求的,缘如风,风不定。云聚是缘,云散也是缘。

感情也如云,万千变化,云起时汹涌澎湃,云落时落寞舒缓。感情的事如云聚云散,缘分是可遇不可求的风。

世上有很多事可以求,唯缘分难求。茫茫人海,浮华世界,多少人真正能寻觅到自己最完美的归属,又有多少人在擦肩而过中错失了最好的机缘。或者又有多少人有正确的选择却站在了错误的时间和地点。有时缘去缘留只在人一念之间。

缘即如风,来也是缘,去也是缘。已得是缘,未得亦是缘。

让我们好好珍惜这难得的缘吧。

二:世上有了咖啡,也就有了咖啡伴侣。没冲的咖啡,特别的苦; 咖啡伴侣,也没什么味道,远不如它那白花花的样子诱人。可把咖啡和咖啡伴侣掺和在一起,用水轻轻地勾兑居然是那么的香醇。

男人原来就是咖啡,男人也可以是咖啡伴侣,两个人搅和在一起就有了故事。冲得好了,完全融合在一起,就会散发出香味;搭配得出了问题,总有些东西漂在上面,不好看,喝起来也略带着点儿苦味。爱情就是个杯子,能让两个男人重新活一回。不过这个杯子也没配小勺,谁都不可能非把两个人搅和在一起,别人看着着急也没有办法。只能靠相互的融合力,让这本来平淡的生活散出香味来。

一首诗曾说:“此情可待成追忆,只是当时已惘然。”如果把两个人放进爱情的杯子要靠缘分的话,那能够让两个人融合到一起的水,就叫“宽容”。对于没有勺子搅拌的咖啡来说,这似乎决定了最后的味道。

愿你我的融合,会散发出浓浓的香味。

佛早就说过:前世五百次的回眸,才换得今生的擦肩而过!所有的一切都有它出现的理由,不必为此而感到惊讶!

三:缘分是世间男女情爱的开端,从不相识到相识相知,让人觉得象是冥冥中的注定,美好而直扣心扉。因一个缘字,让世间多少男女为之癫狂。但也有时有缘却没份,这种情况最让人心伤。还有有份无缘的,无缘无份的。当然,有缘有分是最好的结局,诸君该珍惜。

茫茫人海中两人从相遇,相识,相知,或是相亲相爱,这就是缘分,缘分无需等待 ,缘分是人争取的,是人创造的,只有懂得努力创造缘分的人,才是最理智的,可是又有多少人,能在缘分来的时候,抓得住它,珍惜它呢!缘分是美丽的,缘分和爱情一样,是个古老的话题,同时缘分也需要精心呵护的,缘分不是诗,但它比诗更美丽,缘分不是酒,但它比酒更香浓。爱是不分距离不分地域的,在缘分的天空里,缘分并不是永远都不会远逝的,珍惜你的缘分,善待你的爱情。莫等失去空遗恨。

其实缘分有着两个定义,如果你觉得缘分是天注定的,那么你的一生只是命运的安排!另一种缘分就是你自己的安排了,如果你只等着缘分的到来的话,不去追求是永远也不可能得到的,知道自己喜欢那就是你的缘分,如果你不去追求那你会可能得到吗?所以缘分是要靠自己的,30%是天注定,70%是自己追求得来的!

四:缘分是人平等精神的体现,它要求有缘人地撇开地位、等级、学历、财富等世俗观念,超然物外地共同创造美好的精神境界。伯牙当时是声名显赫的在朝官员,子期则是砍柴为生的樵夫,两人地位差别悬殊,但他们以音乐为媒,情投意合,挚友终身,成为千古佳话。现任法国总统希拉克早年与一位钟表匠很投缘,他无论是做职员还是当议员,直到高居总统宝座,都没有中断与这位挚友的联系,其缘分在他执政中成为体恤民情,关注社会,关爱民众的感情资源。

因缘而生情,随着时间的推移逐渐被诗化的缘分,尤其值得珍惜。缘分是属于精神领域的,它总是想超脱凡尘,维系自己情有独钟的精神境界,但它又不得不与现实社会生活的世俗偏见发生冲突,这种冲突有时是很剧烈的,有的人甚至因此而遭到毁灭性的精神打击。梅克夫人因资助柴珂夫斯基遭到家人的围攻和折磨,最后死在了精神病院;柴珂夫斯基在临终前不停喊着梅克夫人的名字,在一声“冤家”的最后悲叹中结束了自己生命。陆游和唐婉情缘相投,是举世公认的,但旧婚姻道德观使他们不能终身相依,唐婉在年轻美貌时就悲苦离开了人间,陆游人生七十六年,写了许多怀念唐婉的诗篇,临终之际也梦留沈园,遗恨人寰。由此,我想呵护来之不易的缘分,对我们的情感生活很重要。我们可以穷困潦倒,但我们有了遮蔽苦寒风雨的情缘,我们一样能获得生活的勇气,一样能有精神的乐土。

最富有哲理的解释

缘分是一杯清水

你表面上是不经意地端起

喝下去了

其实,生命中你必须有这样的一杯水

或许你可以说

没有这杯水我的命运也是如此

可是幸运的是

说完这句话时

那杯水你已经喝过

最富有诗意的解释

《幸福的缘分感动了我

——让我们来祝福!(十四行)》

今天是你的日子我的司马迁迁,

我不曾认识你你也不曾认识我,

可是我情不自禁地要向你祝福,

因为你的幸福一不小心感动了我。

的确是因为你灿烂所以你才幸福,

可爱的你可爱的幸福有了祝福的执著。

你看看围绕在身边出息的伙伴,

是不是感觉幸福在一阵阵飘过。

询问缘分的迁迁圈主老姐,

幸福有时就是这样悄然而落,

祝愿你轻轻的捧起然后静静的吻过,

真心地告诉自己我是那么得快活!

祝愿你永远年轻永不寂寞,

美好的记忆和幸福的缘分就这样一起来过!

No Comments | Tags: