Pro JavaScript (13)

January 23, 2006 at 3:17 am | Posted in JavaScript | 1 Comment

Pro JavaScript (13) 错误处理

—————————————————————————————————————————

ECMAScript规范v3中加入了对try..catch..finally throw的支持。而对于早期的浏览器由于不支持异常处理语句,所以只有用原始的函数返回值(如-1true/false)来进行判断(结合alert语句)。

语法错误与运行时错误。另外对于BOMwindow对象(和image对象)有一个onerror方法,可以定义错误处理例程与之关联,进行错误处理。

使用onerror方法

Windowonerror方法可以传入几个参数来描述具体错误的情况,按顺序分别为,错误信息,URL,错误行。

alert语句会把详细错误信息输出,注意:最后,把返回值置为true,为的是对浏览器遮蔽该错误(也就是浏览器的debugger不会显示错误)。

Onerror主要的缺点是由于是BOM的支持,所以不同浏览器的实现行为有所不同。而且对于SafariKonqueror也不支持window.onerror

使用try..catch..finally来捕捉异常

注意的是,Javacatch不同,JavaScript只能有一个catch语句,因为它不是强型别语言,所以无法判断异常的型别,所以所有的错误都通过一个catch语句来处理。但是JavaScript的异常还是有不同的类型的,它们的基类为Error,都具有namemessage两个属性,它们包括:

如何根据不同的类型来进行处理呢?因为无法使用多个catch,所以只有在catch语句内使用if…else,并通过该异常的name属性是否等于某种异常类型来判断,当然使用(oException instanceof XxxxError

)语句也可以,这样更Java-like一些。

使用xxx.name==xxxError

使用instanceof语句

使用Throw抛出异常

JavaScript可以说什么都可以抛出,抛出的可以是一个string,一个数字,一个布尔值,一个实际的对象,当然也可以抛Error对象。当抛出Error时,需要构造一个Error对象,Error对象的构造子只接受一个参数,即message

使用Java console进行Debug

可以在JavaScript中直接使用java.lang.System.out.println()来把输出写入Java Console,除IE不支持外,其他浏览器基本都支持。

MozilliaJavaScript DebuggerVenkman的使用

(venkman来自Dr.Pater Venkman,是电影《捉鬼队》中主角的名字)

命令行的使用:

/break http-patterns line_num

/stop /cont

/next (step over)

/step (step in)

/finish (step out)

/watch-expr variable_name

Advertisements

Pro JavaScript (12)

January 20, 2006 at 4:46 am | Posted in JavaScript | 1 Comment

Pro JavaScript (12) 鼠标拖放

—————————————————————————————————————————

能实现鼠标拖放当然很好,例如IE的实现方法就不错,简单易用,但是只适用于IE,对于其他浏览器则,由于不支持拖拽的时间,需要我们自己去定义方法,使用mouse的低级事件来进行模拟。UGLY也没有办法,目前漂亮的实现拖放功能的是google的个性化主页netvibes

简单介绍一下IE的方式

IE建立了完善的Drag-Drop事件机制:

当某Dragable对象被drag时,事件激发属性是:dragstart->drag(一直持续)->dragend(停止) ,注意这些事件针对被Drag的对象。

对于Drag的目标对象,当被拽对象进入目标时候,dragenter被激发,然后只要被拽对象还在目标范围内,dragover就会一直继续激发(同时drag事件也会持续激发),这时如果放下/drop,则drop事件被激发,如果没有放下,而被拽离目标对象时则dragleave被激发。

对于默认本来不是合法的目标对象,可以通过改变dragenterdragover的默认属性来使之成为合法的目标。

IE5.0以后,可以通过dataTransfer来进行拖拽对象的数据传递。

该对象除了setter/getter之外还有两个重要的属性:针对拖拽对象的effectAlloweduninitiallized /none/copy/link/move/copyLink/copyMove/linkMove/all)和针对目标对象的dropEffect none/move/copy/link

另外,对于IE5.5以上,基本上对于所有的HTML元素,都可以使用dragDrop()方法使得本来不是拖拽对象的元素可以变为可拖拽对象(即可以激发dragstart, drag, dragend事件)

通用浏览器的方式:

可惜的是,没有很好的跨浏览器解决办法,(DOM3遥遥无期,XUL只适用于Mozilla),只能采取模拟的方式。思路是利用鼠标事件的低级方法,以及事件的鼠标位置和Divstyle方法,来控制Div的位置。也就是在oDiv.style.left/oDiv.style.topoEvent.clinetX/oEvent.clinetY上做文章。以及运用oDiv.offsetXXX诸方法。


让一个Div跟随鼠标移动,首先定位出初始时(即mousedown事件)鼠标初始点(clientX/Y)与div左上角(offsetLeftoffsetTop)之间的距离。

然后当鼠标移动时(mousemove事件),把div的位置(style.left/style.top)置为鼠标当前点(clientX/Y)与前面初始时获得的距离(DiffX/Y)之差。


Netvibesgoogle)的Drag.js

预备知识:JSONJavaScriptiterals

ECMAScript v3规范中,变量可以直接为作为对象字面量(object literal) 如:

Var foo ={ x:1, y:2 } // An object initializer

object literalsJavaScript 1.2 就被支持,但直到ECMAScript v3才成为标准。,JSON,使用了这种对象定义方法,JSON主要的好处时可以把对象通过纯文本来传递(好像XML),但是不需要XML parser,直接使用JavaScriptevel语句,客户端就可以得到对象

参考:

http://www.crockford.com/JSON/index.html

http://developer.yahoo.net/common/json.html

http://www.quirksmode.org/blog/archives/2005/12/the_ajax_respon.html


netvibes的拖拽界面实现的很不错,它和google的个性化主页实现的原理是一样的。其中实现DragDorp功能的主要是由Drag.jshttp://www.netvibes.com/js/Drag.js)。

拖拽divModuleHeader时,首先mousedown事件被触发调用Drag.startDrag.start 会调用divMoudleonDragStart方法,并设置mousemove/moseup事件的处理函数。

然后mousemove事件触发Drag.drag,它会调用divModuleonDrag方法

然后mouseup事件触发Drag.end,它会调用divModuleonDragEnd方法

divMoudle的几个方法onDragStartonDragonDragEnd,主要为了解决divMoudleGhost(指divMoudle下面红色的虚线标示框)的创建,在页面中的位置,移动。

Pro JavaScript (11)

January 18, 2006 at 6:16 am | Posted in JavaScript | Leave a comment

Pro JavaScript (11) 列表排序

—————————————————————————————————————————

想想电子邮件,想想CRM系统中的用户列表,需要排序的地方太多了,但是如果把这不分处理推给Server端,则把Server的能力浪费在重复劳动上,而且蚁多咬死象,Server端很多的负载消耗在数据展现的形式上,而不是集中于获得具体的数据,这也是客户对于UI认为响应缓慢,而心生不满的缘由之一。

排序用到的最重要的方法是Arraysort()方法:sort(compareFunction) 注意,sort的参数为一个比较函数,当函数不指定时,会把数组中的元素首先转化为String,然后按字符顺序排序(也就是字典顺序,lexicographic)。列表排序的一般方法是,把需要排序的数据首先存入一个array中,然后使用自定义排序函数的sort方法进行排序。

需要注意的是这个自定义的排序函数有一般的格式,即入参有两个,返回值根据两个入参的比较结果返回>0,==0,<0。另外当sort执行完毕后,对于反向的排序使用reverse,速度要比重新sort,使用反向排序的算法要快很多。

注:这里介绍的是完全客户端的排序,如果数据获取一次后就不跟server端打交道的话,可能存在数据不一致的情况,为了更好的解决这个问题,可能需要使用AJAX的方法。

注意:这里sort的实际是一个个的<tr/>元素对象,用对象的方法看待被sort的元素这样可以简化操作,不论是代码理解上,还是后面使用appendChild方法都很方便。另外注意当一个fragment被传入appendChild时,append的是fragment的所有子节点。并不包括fragment本身。

上述sort对单行有效,但是更实际的数据源都是多列的,所以需要对compareTRs方法作一些修改,使之适应不同列:

也就是说通过列为参数,动态的创造compareTRs函数。

同时,修改sortTable方法,加入iCol参数来表示不同的列,这时可以针对不同的列进行排序,其中一个有用的技巧是,如果重复点击同一列时(也就是iCol输入参数与上次输入时相同时)可以加入判断来调用reverse()方法来进行反序。

上述都是针对String的排序,编写类似的排序函数,可以把排序扩展到对数值,日期,等方面。这里的思路是首先对数据类型进行判断,然后根据不同的数据类型来parse值,然后再进行比较,注意的是对于date类型是没有==的(==表示两对象相等,而不是值相等),所以判断的时候要加以注意。

通过添加自定义的属性,还可以对文件类型等进行排序,思路是首先通过自定义的属性得到文件的类型,然后再比较,需要注意的是,XHTML来说是不支持自定义属性的,如果要保证遵守XHTML则可以把<div>包含在单元格了,然后取得div的属性来指示文件的类型。

Pro JavaScript (10)

January 17, 2006 at 3:58 pm | Posted in JavaScript | Leave a comment

Pro JavaScript (10) 表单(form)与数据集成

—————————————————————————————————————————

使用传统的Form元素(<form/><input/><select/><text/>是向server传送数据的最基本的办法。JavaScript可以强化这方面的功能。

基础回顾

HTML form 的属性

  • method request的类型,GET还是POST

  • action : 该form summit的目标URL

  • enctype : 发送的数据将在Server端的解码方式,默认为application/x-www-url-encoded如果该form为上传文件则为multipart/form-data

  • accept : 使用逗号分隔的MIME类型,如text/html”image/*”等。用来表示server可以正确处理的文件类型,常见的是加在<input type=File>标签中,这在RFC1867中本来作为文件类型的过滤器来用的。但是,需要注意的是,实际的browser实现中,对于文件类型是不进行过滤的,是无法阻止用户submit一个不合法的文件,所以要么在clinet端使用Javascript进行处理,要么在server端进行判断处理。
    (参考:File input (or "upload") in HTML forms

  • accept-charset:用来表示server可以接受的输入数据的字符集的列表,也就是说,server根据这里定义的字符集来处理表单。

一个form可以包含任意数目的输入元素:(<input/>,<select/>,<textarea/>

<input/>的属性:

  • text 单行文本框,注意:size指可见字符数,maxlength指最大字符数

  • radio 单选框,具有相同name的一组radio,当选择其中的一个则其他的checked属性自动为false

  • checkbox 对勾,通过checked属性为true/false来判断是否选中。

  • file 文件上载

  • password 密码

  • button 按钮,用来引起一个自定义的时间

  • submit 提交,专门用以引起提交事件的button

  • reset 重置(所有form中的field都变为默认值)

  • hidden 隐藏

  • image 并用来作为submit使用的image

<select/> 与子标签<option>的连用

<textarea/> 多行文本框,大小由rowscols决定。


注意:id vs. name 当使用labelinput连用时,需要注意inputname属性和id属性是都需要的,form只提交具有name属性的input,而label标签中for的值是id,所以这时,最好的办法是idname都置为同名。参考:http://www.quirksmode.org/oddsandends/forms.html

不太精确的说,可以这样理解,Server端使用name,如servletrequest.getParameterClient端使用的是Id,如DOMgetElementById

—————————————————————————————————————————

得到Form对象

多种办法:

Form中的每个field可以通过oForm.elements[index]oForm.elements[“name”],或者直接使用oForm.elements.name当然也可以随时使用document.getElementById()。每个field的通用属性/方法主要有:disabled(阻止使用),form(指向包含该fieldform),blur()(失去焦点),focus()(得到焦点)。

使第一个field获得焦点

粗略的解决方法:document.forms[0].elements[0].focus(); 缺点是如果第一个field是隐藏的话,就会发生错误。

使用工具类:

Form的提交

HTML语言中,提交一个标单有两种方法,1,使用submit button2,使用可以代替submit button使用的图片。

通过DOM中定义的方法form.submit()也可以提交表单。

注意:submit事件和onsubmit event handler,当使用上述两者Button是,在按下按键后,会激发submit事件,这时如果定义了onsubmit handler则,会先执行handler,这通常被用来进行form数据的验证,如同不过验证可以使用preventDefault()来阻止提交,如通过,则执行submit(),把数据发送到server端,但是如果直接调用form.submit()方法,则不会激发submit事件。而直接把数据发送到server端。

选择文本框中的文本

两种文本框(<input type=”text”/><textarea/>)都支持select(),该方法会选定文本框中的所有文本,注意,安全起见,在执行select()前,先执行focus()

自动根据文本长度移动焦点:(输入序列号等)

使用keyup事件(onkeyup="FormUtil.tabForward(this)"),并判断是否到达inputmaxlength,如到达则把焦点转移到下一个文本框。:

限制<textarea/>的输入字符数

<textarea>本身没有maxlength属性,但是我们可以硬加入一个maxlength,然后通过getArribute(“maxlength”)来实现判断。

然后通过设置onkeypress属性为true还是false来控制是否让用户输入。

如上述的<textarea>就只能输入25个字符。这里之所以不使用标准event模型中的preventDefault()是因为Mozilla对于onkeypress的实现有问题,而使用置true/false值的方法对于所有浏览器都是适用的。

阻止不正确的输入类型:(例如要求文本输入数字)

與限制輸入字符數類似,我們需要自造一對invaliedchars/valiedchars屬性,然後通過控制onkeypress handler的返回值来阻止不正确的输入,同时还需要考虑粘贴的问题(ctrl+v键和鼠标右键后出现的选择菜单)对于IE,可以直接设置:onpaste=”return false”,而对于则需要设置:oncontextmenu=”return false”,然后就是解决Ctrl+V的问题,这可以在onkeypress例程里边通过oEvent.ctrlKey && sChar==”v”来判断。

只能输入数字:

相应的allowChars方法:

注意,该程序在FireFox1.5无法使用Backspaceshief键。而在IE中正常,修改代码为:

使用了keyCode==8这种ugly的办法,有更好的办法吗?

当你想让文本框具有粘贴的功能,但是又要限制输入字符的情况,则可以利用onblur,也就是在文本框失去焦点时进行判断,方法与前面的介绍的类似。只所以使用onblur而不用onchange是因为onchange只在文档发生变化是激发事件,也就是说,如果粘贴入非法字符,则移动焦点时会激发一次,因为文档发生了变化,而如果不做任何修改,再次转移焦点,这时由于没有任何修改,则onchange不会触发事件,所以判断程序不会调用。

利用同样的办法,可以添加更多的功能,如使用上下箭头时数字增加或减小(keyCode==38 / keyCode==40

—————————————————————————————————————————

<Select/> <option/>

html语言中(出去input中的radiocheckbox外),选择框通过<select/>表示,注意size属性表示每次显示的选项个数,mutiple=”mutlple”允许多选;对于select中包含的option,可以直接使用options[]访问,如oListbox.option[1].text (当然也可以同普适的DOM方法firstChild.nodeValue; oListbox.option[1].value 得到select中第一个option的显示的文本和该选项的值。同时optionindex属性会指示该option在组中的位置,如oListbox.option[1].index 1, 注意oListbox.selectedIndex指示选择的optionindex,但是对于多选的情况,它包含的值是第一个被选择的option,这时候,需要自己想办法解决,还好,对于每个option具有属性selected,可以根据该值true/false来判断。

灵活的使用DOM中的方法可以进行option的增加,删除,移动,和改变顺序:

  • 增加option(利用appendChild):

  • 删除option

  • 移动option:(注意,对于DOM来说,如果appendChild的参数中提供的节点在文档中原来就存在的话,会从原来的位置删除,然后插入到appendChild的那一点,这给Move带来了很大的方便)。

  • 改变顺序:

上移:oListbox.insertBefore(oOption, oPrevOption);

下移:oListbox.insertBefore(oNextOption, oOption);


Pro JavaScript (9)

January 12, 2006 at 4:29 pm | Posted in JavaScript | 1 Comment

Pro JavaScript (9) 高级DOM

—————————————————————————————————————————

操作某elementCSS style通过该elementstyle对象

通过elementstyle对象的某个属性,就可以操作CSS,这是IE的一般方法

DOM还支持通过get/setPropertyValue来操作CSSIE不支持

DOM中其它有用的方法还有item(index),返回指定序号的CSS属性的名称,如对于:
<div id="div1" style="background-color: red; height: 50px; width: 50px"></div>
item(0)
的值为background-color

以及removeProperty(propertyName),去掉某CSS属性。
有用的例子

  • Tip标签:一般我们常见的Tip标签,即我们把鼠标移动到某处,则给出提示小窗口的特效就是使用stylevisibility置为visible/hidden来实现的

  • 折叠窗口/菜单:这也是一个非常常见的效果,通过点击,某窗口/菜单缩小为一个标题栏,再点击恢复原状,某通过styledisplay属性被置为none/block来实现的。

操作CSS Sheet
与操作某elementCSS style不同,可能CSS被放在<style>…</style>中或是某css文件中,也就是说定义的是CSS ruleclass。这时需要使用document.styleSheets 来得到CSS sheet,在从中取出Css Rules,再Css Rulestyle属性中操作CSS style


注意:之所以使用||是为了浏览器兼容,因为DOM使用cssRules,而IE使用rules,还有如果修改Css RuleStyle则对于所有应用该Ruleelement都会发生改变。

—————————————————————————————————————————

使用IEinnerText/innerHTMLouterText/outerHTML
innerText
innerHTML可以向element中添加文本和html语句。它们比使用DOM来得方便,由于不是DOM规范,所以适用于IE,其他也支持,但是Mozilla只支持innerHTML


outerText/outerHTML
的意思是用文本或Html语句占据目标element本身的位置。即对于oDiv来说,执行后,<div></div>标签就不存在了,而被一段文本或html语句所取代。只有IEOpera支持

—————————————————————————————————————————

使用Range

Range指选择文档的一部分内容而不受节点边界的限制。

DOM Range

生成DOM Range对象:使用createRange()来生成Range对象。同时可以用hasFeature()判断是否支持DOM range

选取DOM Range:使用selectNode()selectNodeContents()来选取Range

DOM Range的只读属性


  • startContainer selection中第一个节点的父节点。

  • startOffset :父节点与第一个节点的偏移量,如果父节点是Text,comment,CData,则偏移量为字符数,否则,偏移量为第一个节点之前的节点数,如没有其它节点则为0

  • endContainer Selection中最后一个节点的父节点。

  • endOffset :在最后一个节点在endContainer中的位置,

  • commonAncestorContainer

当使用selectNode()时候,startContainerendContainercommonAncestorContainer为入参节点的父节点(即p的父节点body),startOffset为入参节点在其父节点的childNodes容器中的index,(即0),endOffsetstartOffset+1,因为只有一个节点(即1)。
当使用selectNodeContents的时候,startContainerendContainercommonAncestorContainer为入参节点本身(即p),startOffset0endOffset为入参节点子节点的个数,也就是node.childNodes.length(即2)。

DOM Range的其他方法

  • setStartBefore(refNode):起始点在refNode前,也就是说refNode是第一个节点,startContainerrefNode的父节点,startOffsetrefNode在它的父节点的所有字节点中的位置。

  • setStartAfter(refNode):起始点在refNode后,第一个节点是refNode后的节点,也就是说refNode不再selection中,但startContainerstartOffset的值是和setStartBefore一样的。

  • 类似,还有setEndBefore(refNode)setEndAfter(refNode),只不过,在setEndBefore中,refNode不在Selection中,而setEndAfterselection中包括refNode

  • setStart(refNode,offset) :这会使得startContainerrefNodestartOffsetoffset

  • setEnd(refNode,offset) :这会使得endContainerrefNodeendOffsetoffset

  • deleteContents, extraceContents, cloneContens

  • collapse(true/false) collapse range,detach()不同,collapsed是使得边界点重合,detach()是消除该range对象。

—————————————————————————————————————————

IE Range

IE range的理念与DOM不同,它针对的是text range,而不是节点。

  • 生成: document.body.createTextRange()

  • 寻找Text oRange.findText(fooText) 如果为true则表示找到,这时对oRange的各个属性进行操作,如oRange.textfooText 注:该方法的第二个参数如果正值则向下查找,负值向上查找。

  • 除了使用findText外还可以使用moveToElementText(oNode),来使用某element节点作为入参,这类似于DOMselectNode()

  • 对于复杂的定位,可以使用move方法来一个字//句的移动。

  • 当想设置的值不止是纯文本,还包括html标签时,这时不法直接设置oRange.text,需要使用oRange.pasteHTML()

  • Collapse Range,使用collapse(true/false) DOM相同,但没有collapsed属性来告诉是否collapsed,需要使用boundingWidth是否为0来判断。

Pro JavaScript (8)

January 11, 2006 at 5:24 pm | Posted in JavaScript | Leave a comment

Pro JavaScript (8) 事件(Events)

背景:Event至少需要DOM2的支持(DOM1不支持事件,DOM3将全面支持事件)。事件模型最早由IE4.0支持,由于那时没有标准,所以IE的事件模型是基于propriety的,后来在一体化的驱动下,DOM标准诞生,但是由于历史原因,Mozilla系列是最接近DOM标准的,相应OperaSafari也趋向于DOM标准,而IE则对于DOM标准的事件模型支持的不好。

事件流的区别IE vs. DOM
IE
使用起泡法,即事件由触发点逐层向上传递。

NS使用捕捉法,即事件从根节点(document)逐层向下传递。

DOM同时支持两种方法,但先捕捉后起泡。

注意DOMText也会触发事件。

事件处理

事件的种类最常用的有click,load,mouseover

简单事件调用:方法是置property值法,例如,针对click事件,可以直接对节点的onclick属性置值,来把该节点的click事件通过event handler onclick与某个Event Handler function进行关联:

高级事件调用:置值法的缺点是无法解决如果针对该event handler需要关联多个function的情况。

IE

[Object].attachEvent(“name_of_event_handler”, fnHandler);
[Object].detachEvent(“name_of_event_handler”, fnHandler);

DOM

[Object].addEventListener(“name_of_event”, fnHandler, bCapture);
[Object].removeEventListener(“name_of_event”, fnHandler, bCapture);

注意:element对象的方法,第一个参数是event名,也就是说click,而不是onclick,另外,第3个参数指是否使用捕捉法

,置为false则使用起泡法,这里需要特别注意的是,如果你addremove时候,第3个参数必须一致,否则,虽然不报错,但实际上不会被remove

关于事件对象

事件对象封装了程序员可能需要的事件信息,例如:是那个对象引起了该事件,事件触发时鼠标/键盘的状态等。IEDOM的使用方法是不同的。

对于IE来说,事件对象就是window对象的event属性,但该属性只有在事件触发时,才可用,当所有event hander都被执行完后,window.event会自动被置为null。这点可以直接观察window.event的字面值来证明,在IE中是个Null,而在Mozilla系列中是个Undefined

DOM规范中规定,事件对象是event listener的唯一参数

当获得event对象后,就可以取用其中的属性和方法,IEDOM的属性很相似,但有不同之处,需要特别注意的是:

  • 获得target的方法(target指激发事件的那个对象,如div
    IE
    oEvent.srcElement
    DOM
    oEvent.target

  • 阻止默认行为 (有用的功能,例如阻止用户对某对象的鼠标右键事件)
    IE
    oEvent.returnValue=false
    Mozilla
    oEvent.preventDefault()

  • 阻止event起泡
    IE
    oEvent.cancelBubble=true
    Mozilla
    oEvent.stopPropagation()

事件的类型

  • 鼠标事件:
    click,dblclick,mousedown,mouseout,mouseover,mouseup,mousemove

  • 键盘事件:
    keydown,keypress,keyup

  • HTML事件:
    load,unload,abort,error,select,change,submit,reset,resize,scroll,focus,blur(lost focus)
    注:unload指离开该页面或关闭窗口
    浮动标签的特效就是利用scroll事件并把该标签的style.top置为document.body.scrollTop

  • DOM 事件:
    反映DOM结构变化的情况,属于DOM标准,目前还未被主流浏览器实现
    DOMSubtreeModified,DOMNodeInserted,DOMNodeRemoved,DOMNodeRemovedFromDocument,DOMNodeInsertedIntoDocument

提供统一的工具方法来整合不同浏览器

由于IEDOM的事件模型不同,为了能使得代码能满足跨浏览器的要求,所以最好有一个工具类来提供统一的事件add/remove等方法。

Eclipse WTP Encoding

January 11, 2006 at 2:53 pm | Posted in Eclipse | Leave a comment

Eclipse WTP 中文显示问题的解决办法

EclipseWTP(Web Tool Platform)JavaScript Editor对于中文支持有问题,无法正确的显示中文,目前0.71.0都存在这个问题,有两个解决办法:

方法1:把默认的encoding改为UTF-8,这样所有新建的文档都采用UTF-8编码,这样中文可以正确显示。缺点是对于原本存在的文档,需要使用工具进行转码才能正确显示。

方法2:修改项目目录下./settings/org.eclipse.core.resources.prefs文件,具体为每个设置encoding,你可以置为GBK,这样原本不能显示的文件就显示正常了。缺点是每个文件都需要设置,太繁琐。

这两种方法都不是太好,目前还没有发现更好的办法。

Pro JavaScript (7)

January 11, 2006 at 3:00 am | Posted in JavaScript, Note | Leave a comment

Pro JavaScript (7) 分辨浏览器和客户端操作系统

—————————————————————————————————————————

检查对象的方法是否存在

如果方法不存在会返回undefined,当转为Boolean型时,为false,注意判断句中方法名后不能带括号,因为这不是方法调用。

使用navigator.userAgent 得到User-Agent字符串:

使用parseFloat(navigator.appVersion) 得到版本号。注意: appversion属性返回的是/号后的所有值,包含字符串,所以要用parseFloat方法。
另外userAgent.indexOf(“foo”)>-1 可以判断userAgent中是否有foo字符。(之所以使用indexOf是因为JavaScript很早的版本就可以支持它),此外使用RegExp的test方法以及$1来抽取匹配的字符串。

使用navigator.platform得到OS类型

登陆页面的一般流程:判断浏览器版本和OS平台一般在登陆页面中进行,也就是一般在该页面的window.onload中,一般改页面都包含一个含有错误显示的<div>,根据判断版本的结果,来决定该div的style.visibility是否为 “hidden”

Pro Javascript (6)

January 10, 2006 at 9:41 am | Posted in JavaScript, Note | Leave a comment

Pro JavaScript (6) 规则表达式(Regular Expressions)

—————————————————————————————————————————

生成RegExp对象:JavaScript通过ECMAScprit规范中的RegExp类来支持规则表达式。你可以使用RegExp的构造器生成RegExp,也可以通过类似Perl风格的字面常量(即把字符加在一对slash(/)中)。

规则表达式

  1. 字面量字符,直接的数字与字符和 ,\t,\n,\v,\f,\r,\xnn,\uxxxx,\cX
  2. 字符,用[]扩起来,(.表示除\n\r外全部字符,\w,\W,\s,\S,\d,\D )
  3. 字符重复的次数可以用{n,m}{n,}{n} ?等于{0,1} +等于{1,} *等于{0,} 定义
  4. 或 |
  5. 分组 ()
  6. subPattern () 小括号除了分组外还可以表示subPattern,然后通过\1,\2..来引用
    例子:批评引号中的内容(保护单引号和双引号)
  7. 位置:$ 表示String尾,^表示String头,注意与在[]中表示否定是不同的。
    \b,\B,注意\b指词的边界,\B指不是词边界

使用RegExpexec()与使用Stringmatch()

使用Stringreplace方法:,注意$1的使用,$加数字,表示subPattern匹配的地方。

有用的实例:验证时期,Credit Card号,电子邮件

—————————————————————————————————————————

Pro Javascript (5)

January 9, 2006 at 4:40 pm | Posted in JavaScript, Note | Leave a comment

========================================================

Pro JavaScript (5) DOM

—————————————————————————————————————————

基础知识回顾:

DOM 即(Document Object Model),文档对象模型,DOM实际是把HTML当作XML文件来进行处理,用对象的眼光来打量HTML,可以说DOM是继HTML后Web的最有用的发明。

Some review of XML

SGML(基于标签的语言的普遍规范),在SGML被用于定义HTML的DTD时,发现HTML本身是很不规范的。主要表现在某些标签可以省略/没有/不允许结束标签(</xxx>),标签互相嵌入而很不不规范,属性值的定义方法也不统一等等。所以XML出现了,HTML中不规范的地方都被明确定义,注意的是XML定义的是一种语言的语法和规范,是一系列满足这种规范的语言的统称,具体不同的场合会有不同的具体实现定义不同的标签及属性来来解决不同的问题,如RDF,RSS,SOAP,XSLT,XSL等等,当然HTML的XML实现为XHTML。XML的实质含义是使用结构化的纯文本来表达数据。

XML几个语法要点:

  1. 首行为XML prolog,一般为<?xml version=”1.0”?>,该行告诉xml praser/浏览器,该XML如何被prase。
  2. 然后是文档类型声明(DTD),例如<!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”&gt;
  3. 然后是document element,它必须把所有其他标签都括入其中。就是该XML的最外层标签。也就是Root Element,注意这个要与DTD中声明的root element type相一致,如上面的html。
  4. 不想被Praser解析的东西用<![CDATA[ ]]>括起来。
  5. 在document element中间的用<? … ?>括起来的语句被称为PI(processing instruction),作用是给praser一些更特定的信息。

XML的API:

    • SAX(Sample API for XML):第一个,Java语言实现,event-based,praser从上到下的解析XML文档,当遇到每个标签/属性/值…时就会激发事件,而具体在该事件做什么由程序员定义。
      优点,lightweight,fast,缺点,任何时候,你想停下,回退,或专门指定解析该文档的某特定部分时,都得从头从文档的第一行开始解析。
    • DOM:基于树结构,并且当解析完后,你想访问或修改添加文档对象都不需要重新解析。DOM是不针对于语言的,浏览器负责对DOM实现进行Javascript的支持。

—————————————————————————————————————————

DOM的核心: Node

由于DOM是树形结构,所以一个节点被抽象为对象Node,这是DOM的核心对象:

Node的种类一共有12种,通过Node.nodeType的取值来确定(为1-12),分为:

❑ Node.ELEMENT_NODE (1)

❑ Node.ATTRIBUTE_NODE (2)

❑ Node.TEXT_NODE (3) :<![CDATA[ ]]>中括着的纯文本,他没有子节点

❑ Node.CDATA_SECTION_NODE (4) :子节点一定为TextNode

❑ Node.ENTITY_REFERENCE_NODE (5) :

❑ Node.ENTITY_NODE (6) DTD中的实体定义<!ENTITY foo “foo”>,无子节点

❑ Node.PROCESSING_INSTRUCTION_NODE (7) :PI,无子节点

❑ Node.COMMENT_NODE (8)

❑ Node.DOCUMENT_NODE (9) :最外层的Root element,包括所有其它节点

❑ Node.DOCUMENT_TYPE_NODE (10) DTD,<!DOCTYPE………..>

❑ Node.DOCUMENT_FRAGMENT_NODE (11)

❑ Node.NOTATION_NODE (12) :DTD中的Nation定义

Node的属性和方法

—————————————————————————————————————————

DOM的使用

DOM是分级别的,不同浏览器对DOM支持的级别不同。DOM level1 (core,用来解析XML-base的文档,和DOM HTML,用来针对HTML,因为DOM并非只针对HTML的),DOM Level2(event,以前都是通过DHTML支持,style,与CSS沟通,等等。。)DOM level3(DOM Load and Save;DOM Validation;对XML1.0的支持,包括:XML Infoset, XPath,XML Base)

获得Node

使用Attributes:Node接口的attributes()方法返回一个NamedNodeMap,从它可以得到具体的Attribute并加以操作。或者是有Node接口本身的getAttribute()方法来直接得到Attribute。

得到指定的Node:使用getElementsByTagName()

还有getElementsByName(),getElementsById();

生成与操作Node

观察可知最普遍的,最重要的方法是createElement(),createDocumentFragment(), create TextNode()

使用createElement(),createTextNode(),appendChild()

使用removeChild(), replaceChild(), and insertBefore()


使用createDocumentFragment()

—————————————————————————————————————————

HTML DOM

使用DOM的核心方法是针对所有XML的,针对HTML DOM有特殊的方法,如

使用DOM core:oImg.setAttribute(“src”, “mypicture2.jpg”);

使用HTML DOM:oImg.src = “mypicture2.jpg”;

—————————————————————————————————————————

DOM 遍历

遍历是DOM Level2的功能,所以只针对Mozilla和Safari

使用createNodeIterator()生成NodeIterator,该方法接受4个参数,1.) root,开始点;2.)whatToShow;3.)filter,什么要省略4.) entityReferenceExpansion,Boolean value indicating whether entity references should be expanded

使用NodeIterator进行遍历:

Filter的用法
Filter只有一个方法,acceptNode,入参为Node,返回值为NodeFilter.FILTER_ACCEPT(如该节点被接受)或NodeFilter.FILTER_REJECT(如果拒绝改节点)

使用TreeWalker,它与NodeIterator很相似,使用参数也相同,不同的是有更多的方法,除了已经的外还有parentNode(),firstChild(),lastChild(),nextSibling(),previousSibling()(兄弟)。

========================================================

Next Page »

Blog at WordPress.com.
Entries and comments feeds.