JavaScript是一种基于对象的脚本编程语言,是浏览器上的程序语言。当web容器输出内容到浏览器时,这个内容是包含js源代码的,此时,JavaScript可以操作浏览器上的一切内容,在浏览器上提供用户交互,页面美化,增加页面的智能性。
JavaScript是一种基于对象的语言,通过 JavaScript代码来操作对象――访问或者设置对象的属性,编写对象的特定的事件(方法)代码。
JavaScript中的对象是由属性(properties)和方法(methods)两个基本的元素的构成的。前者是对象在实施其所需要行为的过程中,实现信息的装载单位,从而与变量相关联;后者是指对象能够按照设计者的意图而被执行,从而与特定的函数相联。
对象从哪里来?JavaScript可以操作的对象有下列三个来源:
1.浏览器环境和 HTML标签语句所构成的现成对象(链接、图像、插件、HTML表单元素、浏览器细节等);
2.通过 JavaScript的内置类所创建的对象,比如 Data(日期)和 Number(数值);
3.通过 JavaScript编程,用户自己创建的对象;
a. JavaScript的代码的加入,通过在Web页中直接写入:
<Script Language="JavaScript">
//JavaScript语言代码;
//JavaScript 语言代码;
//…
</Script>
通过标识<Script> </Script>指明其中包含的是Script脚本代码;
通过Language ="JavaScript"说明标识中使用的语言,这里是JavaScript语言;
可将<Script></Script>标识放入<Head>...</Head>或<Body>...</Body>之间。将 JavaScript标识放置<Head>...</Head>在头部之间,使之在页面文档主体和其余部分代码之前装载。尤其是一些函数的代码,建议读者将这些代码放在<Head>... </Head>在头部之间。
也可以将 JavaScript标识放置在<Body>... </Body>主体之间以实现某些部分动态地创建文档
b. onclick=’javascript:函数名称()’ 直接编写代码或调用代码
c. 使用库函数<script src="指定的Js 文件位置"></script>
把一些 JavaScript代码(尤其是用户自己编写的对象的类文件)组织成可以反复使用的库,具有下列好处:
◆ 减少错误,减少 Web页面的内容。JavaScript库经过严格测试后,可以放心的反复调用,相对于通过拷贝和粘贴把 JavaScript函数插入到每个想要调用它的HTML文件而言。同时也使 HTML文件看起来清楚易读。
◆ 减少网络流量,提高响应速度。当一个 JavaScript库的第一次下载到内存,无论多少页引用该库,浏览器都能访问它。不需要再次下载。
考虑JavaScript 脚本的位置,要注意下列两点:
◆Web 内容在浏览器中是从上到下的顺序解释的。放在 HTML 的<head></head>之间脚本比插入Web 的<body></body>的脚本先处理。比较好的做法是将包含所有预定义函数的脚本放在 Web的<head></head>之间。这样,浏览器在前面遇到这些函数,确保 Web 的<body></body>中的语句能够识别这些函数。同样的道理,在一些网页下载到浏览器中,就会执行的脚本(比如Web页的onload 事件关联的脚本代码),如果这些脚本要访问 HTML 标签所定义的对象,那么要确保这些对象先于脚本执行,否则会出现“对象不存在”的错误。建议设置 IE的浏览器的高级属性中启用脚本调试,可以发现错误存在的地方。
◆ 应用外部脚本库
<script language="JavaScript"src="menu_data.js"></script>,浏览器会在该HTML文件所在的目录下查找 menu_data.js 文件,如果把js 文件存放在别的目录中,则SRC 属性值必须反映出那个目录,也就是必须确保该HTML 文件能够找到 js 文件。
JS中 常见的 陷阱 转
变量名和函数名都是区分大小写的。就像配错的引号一样,这些大家都知道。但是,由于错误是不作声的,所以这是一个提醒。为自己选择一个命名规则,并坚持它。而且,记住JavaScript中的原生函数和CSS属性都是骆驼拼写(camelCase)。
getElementBy
Id(’myId’) != getElementBy
ID(’myId’); //它
应该
是
“Id”而不是“ID”
getElementById(’my
Id‘) != getElementById(’my
ID‘); // “Id”也不等于“ID”
document.getElementById('myId').style.
Color; //返回 "undefined"
避免陷入不匹配的引号、圆括号或花括号陷阱的最好方式是编码时一直同时写出打开和关闭这两个元素符号,然后在其中间加入代码。开始:
var myString = ""; //在
输
入字符串
值
之前写入
这对
引号
function myFunction(){
if(){//
关闭每
个打
开
的括弧
}
}
//
统计
所有的左括号和右括号数量,并且确保它
们
相等
alert(parseInt(var1)*(parseInt(var2)+parseInt(var3))); //
关闭每
个打
开
的
圆
括号
每当你打开一个元素,请关闭它。 当你添加了关闭圆括号后,你再把函数的参数放进圆括号中。 如果有一串圆括号,统计所有打开的圆括号和所有关闭的圆括号,并且确保这两个数字相等。
3.条件语句(3个陷阱)
if(var1 == var2){//statement}
if(var1 = var2){} // 返回true。把var2赋值给var1
4. var myVar = 5;
5. if(myVar == '5'){ //返回true,因为JavaScript是弱类型
6. alert("hi"); //这个alert将执行,因为JavaScript通常不在意数据类型
7. }
8. switch(myVar){
9. case '5':
10. alert("hi"); //这个alert将不会执行,因为数据类型不匹配
11.}
当心JavaScript中的硬换行。换行被解释为表示行结束的分号。即使在字符串中,如果在引号中包括了一个硬换行,那么你会得到一个解析错误(未结束的字符串)。
var bad = '<ul id="myId">
<li>some text</li>
<li>more text</li>
</ul>'; // 未
结
束的字符串
错误
var good = '<ul id="myId">' +
‘<li>some text</li>‘ +
‘<li>more text</li>‘ +
‘</ul>’; // 正确
前面讨论过的换行被解释为分号的规则并不适用于控制结构这种情况:条件语句关闭圆括号后的换行并不是给其一个分号。
一直使用分号和圆括号,那么你不会因换行而出错,你的代码易于阅读,且除了那些不使用分号的怪异源码外你会少一些顾虑:所以当移动代码且最终导致两个语句在一行时,你无需担心第一个语句是否正确结束。
在任何JavaScript对象定义中,最后一个属性决不能以一个逗号结尾。Firefox不会出错,而IE会报语法错误。
var theObj = {
city : "Boston",
state : "MA",//IE6和IE7中有“缺少
标识
符、字符串或数字
”的
错误
,
IE8 beta2修正了它
}
JavaScript DOM绑定(JavaScript DOM bindings)允许通过HTML id索引。在JavaScript中函数和属性共享同一个名字空间。所以,当在HTML中的一个id和函数或属性有相同的名字时,你会得到难以跟踪的逻辑错误。然而这更多是一个CSS最佳实践的问题,当你不能解决你的JavaScript问题时,想起它是很重要的。
<ul>
<li id="length">1</li>
<li id="thisLength">2</li>
<li id="thatLength">3</li>
</ul>
<script>
var listitems = document.getElementsByTagName('li');
var liCount = listitems.length; //IE下返回的是<li id="length">1</li>
这
个
节
点而不是所有
<li的数量
var thisLength = document.getElementById('thisLength');
thatLength = document.getElementById('thatLength');
//IE下会出
现
“
对
象不支持此属性和方法
”的
错误
,
IE8 beta2下首次加
载页
面会出
错
,刷新
页
面
则
不会
//在IE中thisLength和thatLength直接表示以其
为
id
值
的
DOM
节
点,
//所以
赋值时
会出
错
,当有
var声明
时
,
IE会把其当着
变
量,
这
个
时
候就正常了。
</script>
如果你要标记(X)HTML,绝不要使用JavaScript方法或属性名作为id的值。并且,当你写JavaScript时,避免使用(X)HTML中的id值作为变量名。
JavaScript中的许多问题都来自于变量作用域:要么认为局部变量是全局的,要么用函数中的局部变量覆盖了全局变量。为了避免这些问题,最佳方案是根本没有任何全局变量。但是,如果你有一堆,那么你应该知道这些陷阱。
不用var关键字声明的变量是全局的。记住使用var关键字声明变量,防止变量具有全局作用域。在下面例子中,在函数中声明的变量具有全局变量,因为没有使用var关键字声明:
anonymousFuntion1 = function(){
globalvar= 'global scope'; //全局声明,因
为
“var”
遗
漏了
return globalvar;
}();
alert(globalvar); //
弹
出
“global scope”,因
为
函数中的
变
量是全局声明
anonymousFuntion2 = function(){
var localvar = 'local scope'; //使用“var”局部声明
return localvar;
}();
alert(localvar); //
错误
“localvar未定
义
”。
没有全局定
义
localvar
作为参数引进到函数的变量名是局部的。如果参数名也是一个全局变量的名字,像参数变量一样有局部作用域,这没有冲突。如果你想在函数中改变一个全局变量,这个函数有一个参数复制于这个全局变量名,记住所有全局变量都是window对象的属性。
var myscope = "global";
function showScope(myscope){
return myscope; //局部作用域,即使有一个相同名字的全局
变
量
}
alert(showScope('local'));
function globalScope(myscope){
myscope =
window.myscope; //全局作用域
return myscope;
}
alert(globalScope(’local’));
你甚至可以在循环中声明变量:
for(var i = 0; i < myarray.length; i++){}
当你不止一次的声明一个函数时,这个函数的最后一次声明将覆盖掉该函数的所有前面版本且不会抛出任何错误或警告。这不同于其他的编程语言,像Java,你能用相同的名字有多重函数,只要它们有不同的参数:调用函数重载。在JavaScript中没有重载。这使得不能在代码中使用JavaScript核心部分的名字极其重要。也要当心包含的多个JavaScript文件,像一个包含的脚本文件可能覆盖另一个脚本文件中的函数。请使用匿名函数和名字空间。
(function(){
// creation of my namespace
创
建我的名字空
间
if(!window.MYNAMESPACE) {
window['MYNAMESPACE'] = {};
}
//如果名字空
间
不存在,就
创
建它
//
这
个函数
仅
能在匿名函数中
访问
function myFunction(var1, var2){
//内部的函数代
码
在
这
儿
}
// 把内部函数
连
接到名字空
间
上,使它通
过
使用名字空
间
能
访问
匿名函数的外面
window['MYNAMESPACE']['myFunction'] = myFunction;
})(); //
圆
括号
= 立即
执
行
// 包含所有代
码
的
圆
括号使函数匿名
这个例子正式为了实现解决上一个陷阱“变量作用域”的最佳方案。匿名函数详细内容请看《Javascript的匿名函数》。YUI整个库只有YAHOO和YAHOO_config两个全局变量,它正是大量应用匿名函数和命名空间的方法来实现,具体请看《Javascript的一种模块模式》。
一个常见错误是假设字符串替换方法的行为会对所有可能匹配都产生影响。实际上,JavaScript字符串替换只改变了第一次发生的地方。为了替换所有发生的地方,你需要设置全局标识。同时需要记住String.replace()的第一个参数是一个正则表达式。
var myString = "this is my string";
myString = myString.replace("","%20"); // "this%20is my string"
myString = myString.replace(/ /,"%20"); // "this%20is my string"
myString = myString.replace(/ /g,"%20"); // "this%20is%20my%20string"
在JavaScript得到整数的最常见错误是假设parseInt返回的整数是基于10进制的。别忘记第二个参数基数,它能是从2到36之间的任何值。为了确保你不会弄错,请一直包含第二个参数。
parseInt('09/10/08'); //0
parseInt(‘09/10/08’,10); //9, 它最可能是你想从一个日期中得到的
值
如果parseInt没有提供第二个参数,则前缀为 ‘0x’ 的字符串被当作十六进制,前缀为 ‘0′ 的字符串被当作八进制。所有其它字符串都被当作是十进制的。如果 numString 的前缀不能解释为整数,则返回 NaN(而不是数字)。
parseInt("10"); //返回 10
parseInt("19",10); //返回 19 (10+9)
parseInt("11",2); //返回 3 (10+9)
parseInt("17",8); //返回 15 (8+7)
parseInt("1f",16); //返回 31 (16+15)
parseInt("010"); //未定:返回8
第二个参数表示进制十进制 二进制 八进制 十六进制
另一个常见的错误是忘记使用“this”。在JavaScript对象中定义的函数访问这个对象的属性,但没有使用引用标识符“this”。例如,下面是错误的:
function myFunction() {
var myObject = {
objProperty: "some text",
objMethod: function() {
alert(objProperty);
}
};
myObject.objMethod();
}
function myFunction() {
var myObject = {
objProperty: "some text",
objMethod: function() {
alert(this.objProperty);
}
};
myObject.objMethod();
}
有一篇AList Apart文章用通俗易懂的英文表达了this绑定的问题。
对this使用最大的陷阱是this在使用过程中其引用会发生改变:
<input type="button" value="Gotcha!" id="MyButton">
<script>
var MyObject = function () {
this.alertMessage = "Javascript rules";
this.ClickHandler = function() {
alert(this.alertMessage );
//返回
结
果不是
”JavaScript rules”,
执
行
MyObject.ClickHandler
时
,
//this的引用
实际
上指向的是
document.getElementById("theText")的引用
}
}();
document.getElementById(”theText”).onclick = MyObject.ClickHandler
</script>
其解决方案是:
var MyObject = function () {
var self = this;
this.alertMessage = “Javascript rules”;
this.OnClick = function() {
alert(self.value);
}
}();
类似问题的更多细节和解决方案请看《JavaScript作用域的问题》。
当给函数增加一个参数时,一个常见的错误是忘记更新这个函数的所有调用。如果你需要在已经被调用的函数中增加一个参数来处理一个特殊情况下的调用,请给这个函数中的这个参数设置默认值,以防万一在众多脚本中的众多调用中的一个忘记更新。
function addressFunction(address, city, state, country){
country = country || “US”; //如果没有
传
入
country,假
设
“US”
span>//剩下代
码
}
你也能通过获取arguments来解决。但是在这篇文章我们的注意力在陷阱上。同时在《Javascript风格要素(2)》也介绍了||巧妙应用。
在JavaScript中关键字for有两种使用方式,一个是for语句,一个是for/in语句。for/in语句将遍历所有的对象属性(attribute),包括方法和属性(property)。决不能使用for/in来遍历数组:仅在当需要遍历对象属性和方法时才使用for/in。
为了解决这个问题,大体上你可以对对象使用 for … in,对数组使用for循环:
listItems = document.getElementsByTagName('li');
for (var listitem in listItems){
//这里将遍历这个对象的所有属性和方法,包括原生的方法和属性,但不遍历这个数组:出错了!
}
//因为你要循环的是数组对象,所用for循环
for ( var i = 0; i < listItems.length; i++) {
//这是真正你想要的
}
对象的有些属性以相同的方式标记成只读的、永久的或不可列举的,这些属性for/in无法枚举。实际上,for/in循环
会遍历所有对象的所有可能属性,包括函数和原型中的属性。所有修改原型属性可能对for/in循环带来致命的危害,所以需要采用hasOwnProperty和typeof做一些必要的过滤,最好是用for来代替for/in。
EstelleWeyl写了一篇switchstatement quirks,其要点是:
null是一个对象,undefined是一个属性、方法或变量。存在null是因为对象被定义。如果对象没有被定义,而测试它是否是null,但因为没有被定义,它无法测试到,而且会抛出错误。
if(myObject !== null && typeof(myObject) !== 'undefined') {
//如果myObject是undefined,它不能
测试
是否
为
null,而且
还
会抛出
错误
}
if(typeof(myObject) !== 'undefined' && myObject !== null) {
//
处
理
myObject的代
码
}
HarishMallipeddi对undefined和null有一个说明。
刚接触事件处理时最常见的写法就是类似:
window.onclick = MyOnClickMethod
这种做法不仅非常容易出现后面的window.onclick事件覆盖掉前面的事件,还可能导致大名顶顶的IE内存泄露问题。为了解决类似问题,4年前Simon Willison就写出了很流行的addLoadEvent():
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
}else {
window.onload = function() {
oldonload();
unc();
}
}
}
addEvent(window,'load',func1,false);
addEvent(window,'load',func2,false);
addEvent(window,'load',func3,false);
当然在JavaScript库盛行的现在,使用封装好的事件处理机制是一个很好的选择,比如在YUI中就可以这样写:
YAHOO.util.Event.addListener(window, "click", MyOnClickMethod);
来自:
http://dancewithnet.com/2008/10/27/javascript-gotchas/
Figure 3: JavaScript 文档对象模型图
◆ 分析代码行 var Userid =document.forms[0].UserId.value;
该语句的功能是将 Web页面上的名称为 UserId的 Text对象的值赋给一个变量 Userid。JavaScirpt访问HTML上标签所定义的对象,最常常采用的是一种层层限定的逐步收缩法。
在 JavaScript的文档对象模型(DOM)中,窗口(Window)是对象模型的顶端对象,通常来说窗口就是你的浏览器。HTML页面文档是在浏览器的窗口中显示的。目前我们假设页面不包含帧结构,这里假设浏览器窗口中只显示一个 Web页的情景。
浏览器的窗口(Window)有它的属性,比如它显示的页面,窗口(Window)底部的状态条上的文字等等;它也有方法,比如打开和关闭。通常来说,因为窗口在 JavaScript的文档对象模型(DOM)对象层次的顶层,JavaScript就假设 Window已经存在了,你不必去在 JavaScript程序中刻意写上它,也就是说 “window.location”和“location”的作用是相同的。窗口里是 Web页面,它的对象层次从文档(document)开始。可以用 Window.document来引用它,或者就是简单的 document,这同我们在国内邮件通信时,地址一般都不写“中国”。每个窗口只有一个文档(document)的时候
一般情况下,有收集用户输入信息的文档(document)包含至少一个表单(form),但是可以包含多个。可以通过 document.forms[0]来访问第一个表单。当然表单一般都有名称(Name)属性,也可以通过表单的名称来访问,比如:上面的一句 JavaScript也可以写成
var Userid =document.InputForm.UserId.value;
在Microsoft的 IE浏览器环境下,可以不指明表单,还是直接用 all替代(作者建议尽量不要采用这种办法),如:
var Userid =document.all.UserId.value;
表单中当中会包含很多 Input对象,比如单行文本输入框(类型为 Text)、文本区域(类型为TextArea)、普通按钮(类型为 Button)、提交按钮(类型为 Submit)、重置按钮(类型为 Reset)、选择框(类型为 Select)等等。
要访问例子中的用户名称录入的文本框 UserId的 value属性,可以通过
document.InputForm.UserId.value;
如果要将鼠标焦点停留该文本输入框中,可以通过该对象的 focus方法:
document.InputForm.UserId.focus();
比如图 2-2中“调用提交按钮”的 onclick事件所关联的函数的语句为:
document.forms[0].BtnSubmit.click();
含义是:访问到 document(文档)下的forms[0](表单)下的BtnSubmit按钮,调用该按钮的 Click事件。
◆ 分析代码 document.forms[0].reset();
关于表单中的 Submit和 Reset类型的按钮: HTML的表单有个 Action属性,该属性的值为某个页面的地址,当表单提交后,表单当中的用户输入内容将发送给 Action所指定的页面,该页面做相应的处理,比如获得用户的输入,存入到数据库系统中去。
对于表单对象来说,有下列两个方法 submit()和 reset()方法。前者对应表单的提交,后者对应表单内容的复位(初始状态),以便重新录入。图 2中的“重写”按钮所关联的函数的代码document.forms[0].reset();就是调用表单的 Reset()方法;
表单中的 Input对象有两种特别的按钮对象:类型为 Submit的按钮对象和类型为 Reset的按钮对象,点击这种按钮,它的动作就是触发表单的 submit()事件或者reset()事件。在图 2的例子中,我们采用类型为 Button的普通按钮对象来完成这种功能。比如图 2的“重写”按钮如果要用 Reset类型的按钮替代的话,只需要直接<input type="Reset"name="Reset" value="重写">,不需要写它的 Onclick事件代码函数,因为这种按钮的动作默认就是表单 reset()事件。
顺便提一下,尽管我们常常采用逐步收缩的方法来访问 HTML标签所定义的对象。有时候我们也可以采用下列方法:通过对象的 ID或者对象的名称来获得该对象。比如:在图 2中的用户名称的输入框 Text的名称为UserId,它的 ID为 txtUserId,那么可以通过
var UserId=document.getElementById("txtUserId").value;
或者
var UserId =document.getElementByName("UserId").value
来取得该对象的 Value的值。
使用单选钮 (Radio)和多选钮 (Checkbox)的例子:
function Select_check(objName){
varobj=document.getElementsByName(objName);
var selArray = new Array();
for(var i=0;i<obj.length;i++){
if(obj[i].checked){
selArray[i]=obj[i].value;
}
}
return selArray;
}
对于相关成组单选钮和多选钮,在 Web上总是以同名的一组对象出现,在函数中,遍历对象组的每个元素,如果该元素的是否Checked,如果是,则把该元素的值存入到数组selArray中,最后,函数返回值为数组selArray。
3.4.1 字符串对象
创建字符串对象,一般可以通过: varstrTemp =”This is a string”
请看下列检测用户浏览器信息的例子:
function dispBrowser(){
var userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf("msie 6.0")==-1){
alert("你的浏览器不是 IE6.0的,本网页需要 IE6.0才能得到理想显示效果!");
}
}
简要注释:
如果用户的浏览器为 IE6.0的版本,通过
var userAgent = navigator.userAgent.toLowerCase();
可以得到变量 userAgent的值为“mozilla/4.0 (compatible; msie 6.0;windows nt 5.0; i-navfourf)”,通过toLowercase()方法,将字符串转化为小写字母,有助于下面的判断字符串是否包含“msie 6.0”,不需要考虑大小写的问题。navigator对象是浏览器环境所构成的对象。
检查用户字符串是否是为整数:
if (isNaN(strTemp)) {
alert("包含有非数字字符!");
return false;
}
对这种应用,还有一个办法就是,在用户输入的时候就限制用户只能输入数字字符(“事先预防机制”比“事后审核机制”是否更好一些呢?通过 JavaScript来对用户录入进行有效性验证,对 Web服务器来说,也是“事先预防机制”,防止不符要求,不完整的数据信息提交到服务器端),可以采用下面的 Input对象:
<input type="text" name="PageNum"
onkeypress="var k=event.keyCode; returnk>=48&&k<=57||k==46"
onpaste="return !clipboardData.getData('text').match(/\D/)"
ondragenter="return false"
style="ime-mode:Disabled"
/>
JavaScript onpaste事件,禁止粘贴,如果你想像支付宝的注册页面,整个表单都是禁止粘贴的话可以在body标签上加onpaste=”return false”;
oncopy="return false;" oncut="return false;" 防止复制和剪切
3.4.2 日期对象
JavaScript提供了特殊的内部对象――Date对象。创建日期类型的对象的方法有:
1。 vard_today = new Date(); 创建一个包含当前时间和日期的 Data对象;
2。通过 vard_time = new Date(2004,2,14,20,30,01) 表示创建一个 d_time的 Data对象,它的值为 2004年2月 14号 20点30分 01秒。其中的有些参数如果省略的话,JavaScript会自动以零值补充。
日期对象的常用方法例举:
getDate() 根据当地时间,返回指定日期的天
getDay() 根据当地时间,返回指定日期的星期几
getHours() 根据当地时间,返回指定日期的小时
getMonth() 根据当地时间,返回指定日期的月份
getMinutes() 根据当地时间,返回指定日期的分钟
getYear() 根据当地时间,返回指定日期的年份
setDate() 根据当地时间,设置日期变量的天
setHours() 根据当地时间,设置日期变量的小时
var isnMonths=newinitArray("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月")
var isnDays=new initArray("星期日","星期一","星期二","星期三","星期四","星期五","星期六","星期日");
isnMonths[today.getMonth()] getMonth()坐标从零开始
isnDays[today.getDay()] getDay() 坐标星期三返回3,星期日在最前面
函数initArray()用来构造一个数组,该函数使用了JavaScript的 Arguments对象,Arguments对象可以获得一个函数的所有参数集。
★桢结构和框架窗口 (Frame,IFrame)
3.5.1 了解链接的Target属性
<frameset name=framesetnamecols="180,*" FRAMEBORDER=no border="0"
framespacing="0">
<frame name="Directory" src="left.htm"SCROLLING=AUTO
NORESIZE=yes MarginHeight=0 MarginWidth=0
leftMargin=0 target="right">
<frame name="Content" src="right.htm" SCROLLING=AUTO
NORESIZE=yes>
</frameset>
从上面代码可以看出,HTML语句中定义了两个框架窗口,一个名称为 Directory,它对应于文件left.htm,另一个框架窗口为 Content,它对应于文件 right.htm (该文件源代码不包含任何内容,为一张“空白”的 Web页面)。
上图左边的帧 Directory的 Src指向的 Left.htm页面的源文件如下:
<HTML><head>
<STYLE type=text/css>
BODY {FONT: 14px 宋体;}
a {color:#ffffff}
</style>
</head>
<bodybgcolor="#000000"><br>
<a href="Js_1.htm"target="Content">1.JavaScritp概述</a><br>
<ahref="Js_2.htm" target="Content">2.JS对象的简单介绍</a><br>
<ahref="JsTest2.htm" target="Content">3.验证用户输入</a><br>
<inputtype="text" name="DispInfo">
</body>
</HTML>
注释:
在HTML中,链接的HTML标签有Target属性,该属性用来确定该链接的响应的位置。Target属性的有效值可以是当前浏览器显示内容的任何框架窗口(Frame或者 Iframe)的名称,本例子中,表示链接在名称为Content的帧中显示。
3.5.2 由JavaScript,在不同的桢 (窗口 )间访问对象
如果一个浏览器显示内容包含多个(帧)Frame,在不同的(帧)Frame中的Web页如何通过JavaScript访问其他帧中的 Web页的对象呢?
假设右边页面中有个按钮,该按钮onclick的所关联的JavaScript代码为:
top.Directory.document.forms[0].DispInfo.value="测试测试";
实际上,上述内容也是层层限定的逐步收缩法。对于处于帧 Content页面,top代表浏览器的根窗口,该窗口中包含有 Directory和 Content窗口,top.Directory.document表示:浏览器根窗口下的帧 Directory所定义的窗口中的文档。
对于不包含帧或者 Iframe的窗口,我们往往直接通过 document来作为对象访问的顶部层次,这意味着“当前窗口下的当前文档”。当浏览器窗口中包含有帧(或者 Iframe时),而且需要从一个窗口访问另外一个帧所定义的窗口中的对象时,我们就需要在 document之前,来限定究竟是访问哪个框架(Frame或者
IFrame)下的文档。
Iframe比帧结构集更加灵活,我们可以在一个 Web页面的任何位置,加入 Iframe,在标签中设置参数(从设定大小,到指定边框样式等等),通过 SRC的值来指定连接到某个 Web页面。
4.正则表达式和模式匹配
正则表达式描述了字符串的一个模式,可以用来验证用户输入数据的格式。正则表达式可以让用户通过使用一系列的特殊字符构建匹配模式,然后把匹配模式与数据文件、程序输入以及 WEB 页面的表单输入等目标对象进行比较,根据比较对象中是否包含匹配模式,执行相应的程序。
4.1 定义正则表达式
类似于字符串被定义在引号内,正则表达式被定义在一对“/”中间。
varfilter =/m$/
该句创建了一个正则表达式,可以匹配任意以字母 m 结尾的字符串。其中位于“/”定界符之间的部分就是将要在目标对象中进行匹配的模式。用户只要把希望查找匹配对象的模式内容放入“/”定界符之间即可。为了能够使用户更加灵活的定制模式内容,正则表达式提供了专门的“元字符”。所谓元字符就是指那些在正则表达式中具有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象中的出现模式。
较为常用的元字符包括:“+”,“*”,以及“?”。其中,“+”元字符规定其前导字符必须在目标对象中连续出现一次或多次,“*”元字符规定其前导字符必须在目标对象中出现零次或连续多次,而“?”元字符规定其前导对象必须在目标对象中连续出现零次或一次。
除了元字符之外,用户还可以精确指定模式在匹配对象中出现的频率。例如,
/jim{2,6}/
上述正则表达式规定字符 m 可以在匹配对象中连续出现 2-6 次,因此,上述正则表达式可以同jimmy或jimmmmmy 等字符串相匹配。
对如何使用正则表达式有了初步了解之后,我们来看一下其它几个重要的元字符的使用方式。
\s:用于匹配单个空格符,包括 tab 键和换行符;
\S:用于匹配除单个空格符之外的所有字符;
\d:用于匹配从 0 到 9 的数字;
\w:用于匹配字母,数字或下划线字符;
\W:用于匹配所有与\w 不匹配的字符;
(说明:我们可以把\s 和\S 以及\w 和\W 看作互为逆运算)
除了我们以上所介绍的元字符之外,正则表达式中还具有另外一种较为独特的专用字符,即定位符。定位符用于规定匹配模式在目标对象中的出现位置。
较为常用的定位符包括:“^”, “$”, “\b” 以及 “\B”。其中,“^”定位符规定匹配模式必须出现在目标字符串的开头,“$”定位符规定匹配模式必须出现在目标对象的结尾,\b定位符规定匹配模式必须出现在目标字符串的开头或结尾的两个边界之一,而“\B”定位符则规定匹配对象必须位于目标字符串的开头和结尾两个边界之内,即匹配对象既不能作为目标字符串的开头,也不能作为目标字符串的结尾。同样,我们也可以把“^”和“$”以及“\b”和“\B”看作是互为逆运算的两组定位符。
/\bbom/
因为上述正则表达式模式以“\b”定位符开头,所以可以与目标对象中以 “bomb”, 或 “bom”开头的字符串相匹配。
/man\b/
因为上述正则表达式模式以“\b”定位符结尾,所以可以与目标对象中以“human”,“woman”或“man”结尾的字符串相匹配。
4.2 字符类
字符类是括在方括号中的文字字符组合。因此,正则表达式/[xyz]/可以匹配任意包括 x、y、z 中一个字符。在字符类中经常出现下列符号“^”、“-”、“|”符号。如下例子:
/[^A-C]/
上述字符串将会与目标对象中除 A,B,和 C 之外的任何字符相匹配。一般来说,当“^”出现在 “[]”内时就被视做否定运算符;而当“^”位于“[]”之外,或没有“[]”时,则应当被视做定位符。
/Th\*/
上述正则表达式将会与目标对象中的“Th*”而非“The”等相匹配。反斜杠“\”表示转义字符序列,比如“\*”表示字符*,“\n”表示换行。
下列式子表示可以匹配3 个数字或者4 个小写字母:
varfilter =/\d{3}|[a-z]{4}/;
4.2 正则表达式的应用例子
我们可以使用正则表达式的test 或者 search 方法来发现字符中是否符合某个模式。比如:
varResultFlag = forms[0].UserName.value.search(/[a-z]|[A-Z]/);
if(ResultFlag==-1){alert(表单中的UserName 没有包含任何字符!)};
下列为一个检查用户邮件地址格式的例子
<scriptlanguage="Javascript">
<!--
functionvertifyMailAddress(obj){
varemail = obj.email.value;
var pattern =
/^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/;
flag =pattern.test(email);
if(flag){
alert("恭喜!邮件地址输入正确,表单将提交!");return true;
}else{
alert("失败!邮件地址格式不正确!表单不会提交"); return false;
}
}
--></script>
<body>
<formonSubmit="return vertifyMailAddress(this);">
<inputname="email" type="text">
<inputtype="submit">
</form>
</body>