XNJS是校内提供给开发者的JavaScript运行平台,用于满足app对于动态页面的需求。XNJS力求做到尽量与真实的JavaScript运行环境相同,但为了平台的安全性,开发者需要遵守平台的一些限制和编程规范,具体信息请参阅“平台的限制与编程规范”一节。
XNJS支持由<script>标签的src属性指定的外部JS文件。详细信息请参阅CSS/JavaScript外部引用文件。
目录 |
通常,app的开发者并不需要关心隐藏在平台背后的工作原理,但适当了解一下原理性的知识,对于出现问题时的调试过程会有一些帮助,有利于更快速地排查问题。下面做一简单介绍。
出于安全性考虑,app在校内平台上运行的JS代码并不真正操纵DOM节点,而是使用校内提供的XNJS DOM(由校内开放平台提供的文档对象模型)来运行。XNJS DOM模拟真实的DOM,但一般情况下app的JS代码感觉不到差异。app的JS代码会经过校内平台的解析引擎进行重构,重构成之后的JS代码便能够在XNJS DOM框架下运行。这个重构过程由开放平台自动完成,并不需要开发者关心。
平台的重构过程主要包括将app的JS代码中出现的标识符(变量名,函数名等)加上app ID作为前缀,以在一个独立的名字空间中运行。例如,下面的一段原始代码:
function func1(arg1) {
if (arg1 instanceof Object) {
arg1.prop1 = 'string 123';
}
return arg1;
}
重构之后变为(假设app ID = 1234):
function a1234_func1(a1234_arg1) {
if (a1234_arg1 instanceof Object) {
a1234_arg1.prop1 = 'string 123';
}
return a1234_arg1;
}
此外,平台的解析引擎还负责过滤掉一些危险的代码,以保障用户的权益。
有关各部分更详细的信息请参见本文后面的各章节。
document对象提供了如下方法。除了getRootElement是XNJS新加的方法,其它方法都与普通的JavaScript相同。
一个XNJS DOM对象代表一个页面元素(element),上一节讲到的document.getElementById等方法返回的就是一个XNJS DOM对象。
在通常使用的JavaScript语言中,一个DOM对象拥有若干属性(property),如href,tagName,className等,它们中的大部分代表相应页面元素的相应属性(attribute)。JavaScript允许开发人员通过存取DOM对象的属性(property)来操纵页面元素。
在XNJS中,一个XNJS DOM对象并没有直接提供这些属性,而是通过一些提取函数(getters)和设置函数(setters)来访问这些属性。下面的列表列出了XNJS提供的所有提取函数和设置函数以及它们在普通的JavaScript中对应的属性。
|
JavaScript属性 |
XNJS提取函数(getters) |
XNJS设置函数(setters) |
备注 |
|
parentNode |
getParentNode |
返回父节点对象。若当前节点已经是顶层元素,则返回null。 |
|
|
nextSibling |
getNextSibling |
||
|
previousSibling |
getPreviousSibling |
||
|
firstChild |
getFirstChild |
||
|
lastChild |
getLastChild |
||
|
childNodes |
getChildNodes |
返回当前节点的子节点数组。 |
|
|
getElementsByTagName |
getElementsByTagName |
返回当前节点的所有子孙节点组成的数组。在通常使用的JavaScript中,getElementsByTagName也是一个方法,而不是属性。 |
|
|
form |
getForm |
由表单元素节点获得它所在的<form>对象。 |
|
|
options |
getOptions |
返回<select>对象所包含的所有<option>对象组成的数组。 |
|
|
action |
getAction |
setAction |
用于存取<form>对象的action属性。 |
|
value |
getValue |
setValue |
用于存取各种表单对象的value属性。如果当前对象是<select>对象,则getValue返回当前选中的<option>对象的value属性。如果当前对象是<option>对象且没有定义value属性,则getValue返回该<option>所显示的文字,但如果开发者的目的就是要存取一个<option>元素所显示的文字,则不推荐使用getValue和setValue,而应该使用getOptionText和setOptionText,这样对于浏览器的兼容性更好。 |
|
text |
getOptionText |
setOptionText |
专门用于存取<option>对象所显示的文字值。 |
|
href |
getHref |
setHref |
用于存取<a>对象的href属性,即链接的指向。 |
|
target |
getTarget |
setTarget |
用于存取元素节点的target属性,即目标<frame>或<iframe>的地址。 |
|
src |
getSrc |
setSrc |
用于存取元素节点的src属性。 |
|
className |
getClassName |
setClassName |
用于存取元素节点的class属性。 |
|
判断当前节点是否具有某一class值。 |
|||
|
为当前节点加入一个新的class值。 |
|||
|
为当前节点删除给定的class值。 |
|||
|
根据给定的class值,为当前节点切换class属性,即,如果当前节点包含给定的class值,则删除该值;若不包含,则为当前节点加入该class值。 |
|||
|
tagName |
getTagName |
获得元素节点的标签名称。 |
|
|
id |
getId |
setId |
存取元素节点的ID。 |
|
dir |
getDir |
setDir |
存取元素节点的dir属性,即文字方向,可选的值为'LTR'或'RTL'。 |
|
checked |
getChecked |
setChecked |
读取或设置radio或checkbox被选中的状态。 |
|
offsetWidth |
getOffsetWidth |
获得元素节点的宽度,包含padding和border,但不包含margin。当元素有滚动条时(如用CSS的overflow: scroll来指定),只返回可见内容的宽度,包含垂直滚动条的宽度。结果以象素为单位。 |
|
|
offsetHeight |
getOffsetHeight |
与getOffsetWidth相似,只不过是获得元素节点的高度。包含水平滚动条的宽度。 |
|
|
clientWidth |
getClientWidth |
返回的结果等于getOffsetWidth减去垂直滚动条的宽度。 |
|
|
clientHeight |
getClientHeight |
返回的结果等于getOffsetHeight减去水平滚动条的宽度。 |
|
|
scrollWidth |
getScrollWidth |
返回元素内容的整体宽度,以象素为单位。如果元素有滚动条,则这一宽度值包含元素的不可见部分。 |
|
|
scrollHeight |
getScrollHeight |
返回元素内容的整体高度,以象素为单位。如果元素有滚动条,则这一宽度值包含元素的不可见部分。 |
|
|
scrollLeft |
getScrollLeft |
setScrollLeft |
读取或设置元素节点的水平滚动条的位置。可用于在元素可见区域的坐标和元素整体坐标之间进行横坐标换算。 |
|
scrollTop |
getScrollTop |
setScrollTop |
读取或设置元素节点的垂直滚动条的位置。可用于在元素可见区域的坐标和元素整体坐标之间进行纵坐标换算。 |
|
getAbsoluteLeft |
返回元素节点与页面左端的绝对距离,以象素为单位。处于安全性考虑,XNJS没有提供获得offsetParent属性的方法。getAbsoluteLeft和getAbsoluteTop正是为了弥补这一缺点,使得可以完整精确地计算页面内任一元素的坐标。 |
||
|
getAbsoluteTop |
返回元素节点与页面顶端的绝对距离,以象素为单位。 |
||
|
tabIndex |
存取元素节点的Tab键顺序。 |
||
|
title |
getTitle |
setTitle |
存取元素节点的title属性,通常是鼠标在元素上面停留时显示的提示信息。 |
|
name |
getName |
setName |
存取元素节点的name属性。 |
|
cols |
getCols |
setCols |
存取<textarea>节点的显示列数。 |
|
rows |
getRows |
setRows |
存取<textarea>节点的显示行数。 |
|
accessKey |
存取元素节点的访问键。任何时候按了元素节点的访问键,该元素便成为当前的操作焦点。 |
||
|
disabled |
getDisabled |
setDisabled |
存取元素节点的使能状态。 |
|
readOnly |
getReadOnly |
setReadOnly |
存取元素节点的只读状态。 |
|
type |
getType |
setType |
存取元素节点的type属性。注意,IE不支持setType方法。 |
|
selectedIndex |
getSelectedIndex |
setSelectedIndex |
存取<select>对象当前选中项的索引。 |
|
selected |
getSelected |
setSelected |
读取或设置<option>对象被选中的状态。 |
|
style |
存取元素节点的CSS Style。 |
||
|
method |
getMethod |
setMethod |
存取<form>节点的method属性。 |
|
nodeType |
getNodeType |
返回节点类型。如Node.ELEMENT_NODE(=1),Node.DOCUMENT_NODE(=9)等。 |
|
|
rowSpan |
getRowSpan |
setRowSpan |
读取和设置表格中一个单元格(<td>或<th>)所跨越的行数。 |
|
colSpan |
getColSpan |
setColSpan |
读取和设置表格中一个单元格(<td>或<th>)所跨越的列数。 |
|
maxLength |
getMaxLength |
setMaxLength |
读取和设置<input>输入框的最大输入长度。 |
|
读取和设置<input>和<textarea>中被选中的文字位置信息。 |
|||
|
innerHTML |
getInnerHTML |
读取当前节点的innerHTML属性的内容,返回值是一个字符串。若想设置该属性内容,请使用setTextValue或setInnerXNML。 |
在JavaScript中,通常使用innerHTML来动态地设置元素显示内容。但由于安全性原因,XNJS并没有直接提供这一属性,而是提供了下面的方法来完成同样的功能。
|
函数名 |
备注 |
|
setTextValue |
设置元素的内容为一段文本(不能是HTML或XNML片段),以字符串的形式传入。 |
|
设置元素的内容为一段XNML片段。注意,传入的XNML片段不能是一个普通字符串,要先将XNML片段表示成一个XNML_String对象再传入。 |
|
函数名 |
备注 |
|
appendChild |
为当前节点插入一个子节点,作为最后一个子节点。 |
|
insertBefore |
在当前节点指定的子节点之前插入一个节点。 |
|
removeChild |
删除子节点。 |
|
replaceChild |
替换子节点。 |
|
cloneNode |
克隆一个节点。 |
|
函数名 |
备注 |
|
submit |
提交表单。 |
|
focus |
使当前表单元素成为焦点。 |
|
select |
选中<input>元素中的文字。 |
XNJS的document对象提供了createElement调用,不仅允许创建通常的HTML元素节点对象,还可以创建一些由XNML定义的特殊元素节点。在现在的XNJS实现中允许创建的XNML特殊元素节点类型如下列出(目前只有<xn:swf>)。
XNJS提供了若干函数用于操纵CSS,这些函数在上一节及相应链接中都已经做了介绍,这里重新列出来作为总结。
XNJS同时支持基本事件处理模型(DOM level 0 event model)和高级事件处理模型(DOM level 2 event model)。
基本事件处理模型直接用页面元素的属性(如onclick)来关联事件处理代码。在事件处理代码中,可以用this代表该页面元素本身。
高级事件处理模型使用addEventListener,removeEventListener等函数来注册和删除事件处理函数。XNJS用于管理事件处理的函数包括:
|
函数名 |
备注 |
|
addEventListener(type, func) |
注册处理type事件的处理函数。 |
|
removeEventListener(type, func) |
删除type事件的处理函数func,但元素的"on+type"属性指定的事件处理代码不会受到影响。 |
|
返回type事件的处理函数列表,也包括元素的"on+type"属性指定的事件处理代码。 |
|
|
删除type事件的所有处理函数,包括元素的"on+type"属性指定的事件处理代码也会被删除。 |
注意,上面列出的函数中addEventListener和removeEventListener是JavaScript本来就提供的,而listEventListeners和purgeEventListeners是XNJS加入的函数。另外,在XNJS中,只支持在事件传播的bubbling阶段注册事件处理函数,不支持capturing阶段的事件捕获,即,上面列出的各个函数不存在一个Boolean型的参数useCapture。
在通常的JavaScript中,这种高级的事件处理函数的注册在IE中需要特殊处理,如使用attachEvent和detachEvent注册和删除事件处理函数。但XNJS已经做过了这种特殊处理,所以app的JS代码可以总是使用addEventListener和removeEventListener即可,不用对IE做特殊操作。
由addEventListener注册的事件处理函数func,会接受一个XNJS Event对象作为参数,这个Event对象提供了事件发生的各种信息,拥有如下属性和函数(同样Firefox和IE都适用)。
|
XNJS Event对象的属性 |
描述 |
|
target |
事件发生的元素节点。 |
|
type |
事件类型。 |
|
pageX |
事件发生点的横坐标。 |
|
pageY |
事件发生点的纵坐标。 |
|
keyCode |
按键的编码。 |
|
ctrlKey |
检测Ctrl键是否按下的布尔值。 |
|
metaKey |
检测meta键是否按下的布尔值。 |
|
shiftKey |
检测Shift键是否按下的布尔值。 |
|
altKey |
检测Alt键是否按下的布尔值。 |
|
XNJS Event对象的函数 |
备注 |
|
preventDefault() |
取消元素缺省的行为。 |
|
stopPropagation() |
停止事件继续在DOM树中传播。 |
出于安全性的考虑,XNJS不允许直接将一段XNML片段以字符串的形式传给DOM节点对象的setInnerXNML方法或用来定制Dialog,而是需要先将XNML片段表示成一个XNJS_String对象,才能传给相应的函数。
与校内提供的其它对象不同,XNML_String对象并不允许由开发者通过JS代码来创建,而是通过XNML的xn:js-string的标签来创建,或者通过校内Ajax对象来返回一个XNML_String对象。详细情况参见XNML_String。
XNJS为开发者提供了一套丰富的对话框代码库,功能强大,能够满足开发者对于对话框的各种需求,并允许开发者定制自己的对话框。请点击这里Dialog了解详细信息。
XNJS提供的Button对象,可以动态添加到Dialog,用于灵活地定制对话框,并可以绑定callback函数。请点击这里Button了解详细信息。
校内开放平台为app提供了从前端到app服务器的ajax代理。前端的JS代码为开发者提供了一个Ajax对象,对app提出的ajax请求做了预处理工作,并对返回的应答做了很多善后处理,使app更容易使用ajax功能。
为安全的原因,平台的提供的Ajax对象只支持POST请求。应答的格式在有三种:RAW, JSON和XNML。详细信息参见Ajax。
XNJS通过Animation对象提供了一个CSS效果库,可以使用JS代码实现动画效果,详见Animation。
用于获取跟登陆用户有关的信息。Session对象提供的函数如下表所示。
|
Session对象的函数 |
备注 |
|
Session.getUser() |
返回当前登陆用户的ID。 |
|
Session.isApplicationAdded() |
判断当前登陆用户是否添加app,即是否已经授权。如果没有授权,并且你需要知道当前用户是谁,可调用Session.requireLogin()来引导用户授权。 |
|
Session.isLoggedIn() |
判断当前用户是否已经登陆。在目前的实现中,只有已经登陆并且安装了app的用户才能访问该app,因此此函数总是返回true。 |
|
弹出一个框,询问用户是否愿意授权。当用户授权后,你就可以知道当前用户是谁,并能拿到用户ID和session_key。此方法有两个可选的参数,你可以传入两个JS函数,它们分别会在用户同意授权或取消后被执行。详细描述请点这里 |
用于完成各种数学运算。Math对象提供了一系列函数和数学常量的定义,与通常JavaScript中的Math对象功能相同。
|
Math对象的函数 |
备注 |
|
Math.abs(x) |
计算绝对值。 |
|
Math.floor(x) |
下取整。 |
|
Math.ceil(x) |
上取整。 |
|
Math.round(x) |
四舍五入,返回距离x最近的整数值。 |
|
Math.max(x, y) |
返回两个数的最大值。 |
|
Math.min(x, y) |
返回两个数的最小值。 |
|
Math.sin(x) |
计算正弦值。 |
|
Math.cos(x) |
计算余弦值。 |
|
Math.tan(x) |
计算正切值。 |
|
Math.asin(x) |
计算反正弦值。 |
|
Math.acos(x) |
计算反余弦值。 |
|
Math.atan(x) |
计算反正切值。 |
|
Math.atan2(x, y) |
计算坐标点(x,y)与x轴之间的夹角。 |
|
Math.exp(x) |
计算x的自然对数。 |
|
Math.pow(x, y) |
计算x的y次幂。 |
|
Math.log(x) |
计算x的自然对数。 |
|
Math.random(x) |
返回0~1之间的一个随机值。 |
|
Math.sqrt(x) |
计算x的平方根。 |
|
Math.valueOf() |
返回Math对象的primitive value,实际为Math对象本身。 |
|
Math对象定义的数学常量 |
含义 |
|
Math.E |
自然对数常量e。 |
|
Math.LN2 |
2的自然对数值。 |
|
Math.LN10 |
10的自然对数值。 |
|
Math.LOG2E |
以2为底e的对数。 |
|
Math.PI |
圆周率常量。 |
|
Math.SQRT1_2 |
2的平方根的倒数。 |
|
Math.SQRT2 |
2的平方根。 |
用于日期计算及获取当前时间等。与通常JavaScript中的Date对象功能相同,通常的Date对象所提供的函数也全部提供,故此处略过。但构造函数稍有不同,只支持下面几种格式。
|
Date对象的构造函数 |
备注 |
|
new Date() |
创建一个Date对象,代表当前日期和时间。 |
|
new Date(milliseconds) |
创建一个Date对象,代表参数milliseconds所表示的时间,即从1970年1月1日开始计算的秒数。 |
|
new Date(datestring) |
创建一个Date对象,代表由日期字符串datestring所表示的时间,如"Jul 4, 1998"。 |
|
new Date(year[, month, day]) |
创建一个Date对象,代表指定的年月日。 |
用于正则表达式相关的操作。 通常JavaScript的RegExp对象所提供的函数也全部提供,故此处略过。
用于开发者调试JS代码和显示log之用。如果浏览器安装了调试插件,由console对象输出的信息一般在调试插件的控制台上显示。建议使用Firebug进行调试,对调试功能的支持比较全面。
由于XNJS DOM是由校内开放平台提供的文档对象模型,而不是真正的DOM,因此由console对象输出的信息也与通常情况稍有不同。如果用console对象的方法输出一个XNJS DOM对象,则会看到一个"xn_PRIV_obj"属性,其属性值就是所对应的真实的DOM节点;如果用console对象的方法输出一个由XNJS定义的对象(如Ajax, Dialog等),则会看到一些以"PRIV_"为前缀的属性,这些属性表示该对象的私有属性。
由XNJS console对象提供的方法如下表所示。
|
console对象的函数 |
备注 |
|
console.log(object[, object, ...]) |
在控制台上打印log信息。 |
|
console.error(object[, object, ...]) |
在控制台上打印error信息。 |
|
console.warn(object[, object, ...]) |
在控制台上打印warning信息。 |
|
console.debug(object[, object, ...]) |
在控制台上打印debug信息。 |
|
console.assert(expression[, object, ...]) |
测试表达式expression是否为true,如果不是,则在控制台上打印信息并抛出一个异常。 |
|
console.dir(object) |
在控制台上列出object对象的所有属性,如同在DOM tab上显示的一样。 |
|
console.group(object[, object, ...]) |
开始一个新的消息组,此后打印在控制台上的信息都加上相同的缩进。 |
|
console.groupEnd() |
关闭当前的消息组,回到原来的缩进值。 |
|
console.dirxml(node) |
以XML的格式在控制台上打印节点node的HTML源码,如同在HTML tab上显示的一样。参数node只能是一个XNJS DOM对象,不能是其它对象。 |
更详细信息请参阅Firebug相关文档
XNJS还提供了其它一些重要而常用的全局函数。
|
函数名 |
备注 |
|
setTimeout(func, milliseconds) |
在milliseconds毫秒的延迟后执行func函数。参数func必须是一个函数,而不能是任意的JS代码。 |
|
setInterval(func, milliseconds) |
以milliseconds毫秒为时间区间周期性地执行func函数。参数func必须是一个函数,而不能是任意的JS代码。 |
|
clearTimeout(timeoutId) |
取消由setTimeout调度执行的函数。 |
|
clearInterval(intervalId) |
取消由setInterval调度执行的函数。 |
|
encodeURIComponent(s) |
转义字符串s,使之uri-safe。 |
|
decodeURIComponent(s) |
解码由encodeURIComponent编码过的字符串。 |
|
parseFloat(s) |
将字符串s转成一个浮点数。 |
|
parseInt(s, radix) |
以radix为基数,将字符串s转成一个整数。 |
|
isNaN(x) |
检查参数x是否是NaN。 |
|
isFinite(n) |
检查参数n是否是一个有限的数字。 |
XNJS demo是一个在线的演示程序;其源码见XNJS Demo源码。
由于安全性的要求,开发者需要遵守平台的一些限制和编程规范。
var span_item = document.createElement('span').setTextValue('Hello');
兼容性更好的代码风格是:
var span_item = document.createElement('span');
span_item.setTextValue('Hello');
但XNJS Animation对象的使用不受此限制,可以使用链接表达式,例如:
Animation(this).to('background', '#ffff4b').from('#fff').to('color', '#ff0000').from('#000')
.duration(3000).go();