JavaScript学习总结(一)——ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
一、JavaScript简介
JavaScript是一种解释执行的脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型,它遵循ECMAScript标准。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,主要用来给HTML增加动态功能。
几乎所有主流的语言都可以编译为JavaScript,进而能够在所有平台上的浏览器中执行,这也体现了JavaScript的强大性和在Web开发中的重要性。如Blade:一个Visual Studio扩展,可以将C#代码转换为JavaScript,Ceylon:一个可编译为JavaScript的、模块化的、静态类型JVM语言。
JavaScript是一种可以同时运行在前端与后台的语言,如Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境(类似Java或.NET)。 Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型,使其轻量又高效。
1.1、javascript组成
ECMAScript,描述了该语言的语法和基本对象,如类型、运算、流程控制、面向对象、异常等。
文档对象模型(DOM),描述处理网页内容的方法和接口。
浏览器对象模型(BOM),描述与浏览器进行交互的方法和接口。
JavaScript由对象组成,一切皆为对象。
1.2、JavaScript脚本语言特点
a)、解释型的脚本语言。JavaScript是一种解释型的脚本语言,C、C++等语言先编译后执行,而JavaScript是在程序的运行过程中逐行进行解释。
基于对象。JavaScript是一种基于对象的脚本语言,它不仅可以创建对象,也能使用现有的对象。
b)、简单。JavaScript语言中采用的是弱类型的变量类型,对使用的数据类型未做出严格的要求,是基于Java基本语句和控制的脚本语言,其设计简单紧凑。
c)、动态性。JavaScript是一种采用事件驱动的脚本语言,它不需要经过Web服务器就可以对用户的输入做出响应。在访问一个网页时,鼠标在网页中进行鼠标点击或上下移、窗口移动等操作JavaScript都可直接对这些事件给出相应的响应。
d)、跨平台性。JavaScript脚本语言不依赖于操作系统,仅需要浏览器的支持。因此一个JavaScript脚本在编写后可以带到任意机器上使用,前提上机器上的浏览器支 持JavaScript脚本语言,目前JavaScript已被大多数的浏览器所支持。
二、ECMAScript(JavaScript核心与语法)
2.1、ECMAScript定义
1)、ECMAScript是一个标准(欧洲计算机制造商协会),JavaScript只是它的一个实现,其他实现包括ActionScript(Flash脚本)
2)、ECMAScript可以为不同种类的宿主环境提供核心的脚本编程能力,即ECMAScript不与具体的宿主环境相绑定,如JavaScript的宿主环境是浏览器,AS的宿主环境是Flash。、
3)、ECMAScript描述了以下内容:语法、类型、语句、关键字、保留字、运算符、对象等
2.2、数据类型
在JS中使用var关键词声明变量,变量的类型会根据其所赋值来决定(动态类型)。JS中数据类型分为原始数据类型(5种)和引用数据类型(Object类型)。
1)5种原始数据类型:Undefined、Null、Boolean、Number和String。需要注意的是JS中字符串属于原始数据类型。
2)typeof运算符:查看变量类型,对变量或值调用typeof运算符将返回下列值之一:
- undefined – 如果变量是 Undefined 类型的
- boolean – 如果变量是 Boolean 类型的
- number – 如果变量是 Number 类型的
- string – 如果变量是 String 类型的
- object – 如果变量是一种引用类型或 Null 类型的
3)通过instanceof 运算符解决引用类型判断问题
4)null 被认为是对象的占位符,typeof运算符对于null值返回“object”。
5)原始数据类型和引用数据类型变量在内存中的存放如下:
6)JS中对类型的定义:一组值的集合。如Boolean类型的值有两个:true、false。Undefined和Null 类型都只有一个值,分别是undefined和null。
Null 类型只有一个值,就是 null ; Undefined 类型也只有一个值,即 undefined 。 null 和 undefined 都可以作为字面量(literal)在 JavaScript 代码中直接使用。
null 与对象引用有关系,表示为空或不存在的对象引用。当声明一个变量却没有给它赋值的时候,它的值就是 undefined 。
undefined 的值会出现在如下情况:
从一个对象中获取某个属性,如果该对象及其 prototype 链 中的对象都没有该属性的时候,该属性的值为 undefined 。
一个 function 如果没有显式的通过 return 来返回值给其调用者的话,其返回值就是 undefined 。有一个特例就是在使用new的时候。
JavaScript 中的 function 可以声明任意个形式参数,当该 function 实际被调用的时候,传入的参数的个数如果小于声明的形式参数,那么多余的形式参数的值为 undefined 。
示例:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
</head> <body>
<script>
//js对象
var user = {
name: "张学友",
address: "中国香港"
};
console.log(user.age); //访问对象中的属性,未定义 var i;
console.log(i); //变量未赋值 function f(n1){
console.log(n1);
}
var result=f(); //参数未赋值 console.log(result); //当函数没有返回值时为undefined </script>
</body> </html>
结果:
关于 null 和 undefined 有一些有趣的特性:
如果对值为 null 的变量使用 typeof 操作符的话,得到的结果是 object ;
而对 undefined 的值使用 typeof,得到的结果是 undefined 。
如 typeof null === "object" //true; typeof undefined === "undefined" //true null == undefined //true,但是 null !== undefined //true
示例:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title></title>
</head> <body>
<script>
//js对象
var user = {
name: "张学友",
address: "中国香港"
};
console.log(typeof(user));
console.log(typeof(null));
console.log(typeof(undefined));
console.log(user.name);
console.log(user.age); if(user.age){
console.log(user.age);
}else{
console.log("没有age属性");
}
//为false的情况
var i;
console.log(!!"");
console.log(!!0);
console.log(!!+0);
console.log(!!-0);
console.log(!!NaN);
console.log(!!null);
console.log(!!undefined);
console.log(typeof(i));
console.log(!!i);
console.log(false);
//是否不为数字,is Not a Number
console.log(isNaN("Five"));
console.log(isNaN("5"));
</script>
</body> </html>
结果:
7)、 boolean类型的特殊性
8)、== 与 ===
JavaScript 中有两个判断值是否相等的操作符,== 与 === 。两者相比,== 会做一定的类型转换;而 === 不做类型转换,所接受的相等条件更加严格。
===比较时会比较类型
当然与之对应的就是!=与!==
尽量使用===而不要使用==
console.log("5"==5); //true
console.log("5"===5); //false
console.log("5"!=5); //false
console.log("5"!==5); //true
2.3、局部变量和全局变量
在函数中声明的变量只能在函数中使用,当你退出函数时,变量就会被释放,这种变量被称为局部变量。因为每个局部变量只在各自的函数中有效,所以你可以在不同的函数中使用名称相同的变量。
如果在函数之外声明变量,那么页面中所有的函数都可以使用它。在全局变量被声明后,它们就开始生效了。在网页被关闭后,变量才会失效。
注意:JS语言中,在代码块中声明的变量属于全局变量。
JavaScript是一种对数据类型变量要求不太严格的语言,所以不必声明每一个变量的类型,变量声明尽管不是必须的,但在使用变量之前先进行声明是一种好的习惯。可以使用 var 语句来进行变量声明。如:var men = true; // men 中存储的值为 Boolean 类型。
变量命名
JavaScript 是一种区分大小写的语言,因此将一个变量命名为best和将其命名为Best是不一样的。
另外,变量名称的长度是任意的,但必须遵循以下规则:
- 1.第一个字符必须是一个字母(大小写均可)、或一个下划线(_)或一个美元符 ($)。
- 2.后续的字符可以是字母、数字、下划线或美元符。
- 3.变量名称不能是保留字。
可以不使用var定义变量,但这样定义的变量是全局变量。
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script>
function a(){
var n1=1;
n2=2; //声明n2时未使用var,所以n2是全局变量,尽量避免
console.log(n1+","+n2);
}
a();
console.log(n2);
console.log(window.n2);
console.log(window.n1);
console.log(n1);
</script>
</body> </html>
结果:
2.4、数组(Array)
①js中,数组元素类型可以不一致。
②js中,数组长度可以动态改变。
③接着上述代码,typeof arr 和 arr instanceof Array 分别输出object和true。
console.log(typeof(names)); //object
console.log(names instanceof Array); //true
console.log("" instanceof String); //false 不是对象类型
console.log(true instanceof Boolean); //false
数组对象与方法
Array 对数组的内部支持
Array.concat( ) 连接数组
Array.join( ) 将数组元素连接起来以构建一个字符串
Array.length 数组的大小
Array.pop( ) 删除并返回数组的最后一个元素
Array.push( ) 给数组添加元素
Array.reverse( ) 颠倒数组中元素的顺序
Array.shift( ) 将元素移出数组
Array.slice( ) 返回数组的一部分
Array.sort( ) 对数组元素进行排序
Array.splice( ) 插入、删除或替换数组的元素
Array.toLocaleString( ) 把数组转换成局部字符串
Array.toString( ) 将数组转换成一个字符串
Array.unshift( ) 在数组头部插入一个元素
2.4.1、创建
var arrayObj = new Array();
var arrayObj = new Array([size]);
var arrayObj = new Array([element0[, element1[, ...[, elementN]]]]);
示例:
var array11 = new Array(); //空数组
var array12 = new Array(5); //指定长度,可越界
var array13 = new Array("a","b","c",1,2,3,true,false); //定义并赋值
var array14=[]; //空数组,语法糖
var array15=[1,2,3,"x","y"]; //定义并赋值
2.4.2、访问与修改
var testGetArrValue=arrayObj[1];
arrayObj[1]= "值";
//4.2、访问与修改
array12[8]="hello array12"; //赋值或修改
console.log(array12[8]); //取值
//遍历
for (var i = 0; i < array13.length; i++) {
console.log("arrayl3["+i+"]="+array13[i]);
}
//枚举
for(var i in array15){
console.log(i+"="+array15[i]); //此处的i是下标
}
结果:
2.4.3、添加元素
将一个或多个新元素添加到数组未尾,并返回数组新长度
arrayObj. push([item1 [item2 [. . . [itemN ]]]]);
将一个或多个新元素添加到数组开始,数组中的元素自动后移,返回数组新长度
arrayObj.unshift([item1 [item2 [. . . [itemN ]]]]);
将一个或多个新元素插入到数组的指定位置,插入位置的元素自动后移,返回被删除元素数组,deleteCount要删除的元素个数
arrayObj.splice(insertPos,deleteCount,[item1[, item2[, . . . [,itemN]]]])
示例代码:
//4.3、添加元素
var array31=[5,8];
//添加到末尾
array31.push(9);
var len=array31.push(10,11);
console.log("长度为:"+len+"——"+array31);
//添加到开始
array31.unshift(4);
var len=array31.unshift(1,2,3);
console.log("长度为:"+len+"——"+array31);
//添加到中间
var len=array31.splice(5,1,6,7); //从第5位开始插入,删除第5位后的1个元素,返回被删除元素
console.log("被删除:"+len+"——"+array31);
运行结果:
2.4.4、删除
移除最后一个元素并返回该元素值
arrayObj.pop();
移除最前一个元素并返回该元素值,数组中元素自动前移
arrayObj.shift();
删除从指定位置deletePos开始的指定数量deleteCount的元素,数组形式返回所移除的元素
arrayObj.splice(deletePos,deleteCount);
示例:
//4.4、删除
var array41=[1,2,3,4,5,6,7,8];
console.log("array41:"+array41);
//删除最后一个元素,并返回
var e=array41.pop();
console.log("被删除:"+e+"——"+array41);
//删除首部元素,并返回
var e=array41.shift();
console.log("被删除:"+e+"——"+array41);
//删除指定位置与个数
var e=array41.splice(1,4); //从索引1开始删除4个
console.log("被删除:"+e+"——"+array41);
结果:
2.4.5、截取和合并
以数组的形式返回数组的一部分,注意不包括 end 对应的元素,如果省略 end 将复制 start 之后的所有元素
arrayObj.slice(start, [end]);
将多个数组(也可以是字符串,或者是数组和字符串的混合)连接为一个数组,返回连接好的新的数组
arrayObj.concat([item1[, item2[, . . . [,itemN]]]]);
示例:
//4.5、截取和合并
var array51=[1,2,3,4,5,6];
var array52=[7,8,9,0,"a","b","c"];
//截取,切片
var array53=array51.slice(2); //从第3个元素开始截取到最后
console.log("被截取:"+array53+"——"+array51);
var array54=array51.slice(1,4); //从第3个元素开始截取到索引号为3的元素
console.log("被截取:"+array54+"——"+array51);
//合并
var array55=array51.concat(array52,["d","e"],"f","g");
console.log("合并后:"+array55);
结果:
2.4.6、拷贝
返回数组的拷贝数组,注意是一个新的数组,不是指向
arrayObj.slice(0);
返回数组的拷贝数组,注意是一个新的数组,不是指向
arrayObj.concat();
因为数组是引用数据类型,直接赋值并没有达到真正实现拷贝,地址引用,我们需要的是深拷贝。
2.4.7、排序
反转元素(最前的排到最后、最后的排到最前),返回数组地址
arrayObj.reverse();
对数组元素排序,返回数组地址
arrayObj.sort();
arrayObj.sort(function(obj1,obj2){});
示例:
var array71=[4,5,6,1,2,3];
array71.sort();
console.log("排序后:"+array71);
var array72=[{name:"tom",age:19},{name:"jack",age:20},{name:"lucy",age:18}];
array72.sort(function(user1,user2){
return user1.age<user2.age;
});
console.log("排序后:");
for(var i in array72) console.log(array72[i].name+","+array72[i].age);
结果:
2.4.8、合并成字符
返回字符串,这个字符串将数组的每一个元素值连接在一起,中间用 separator 隔开。
arrayObj.join(separator);
示例代码:
//4.8、合并成字符与将字符拆分成数组
var array81=[1,3,5,7,9];
var ids=array81.join(",");
console.log(ids); //拆分成数组
var text="hello nodejs and angular";
var array82=text.split(" ");
console.log(array82);
运行结果:
所有代码:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title>数组操作</title>
</head> <body>
<script type="text/javascript">
//4.1、创建
var array11 = new Array(); //空数组
var array12 = new Array(5); //指定长度,可越界
var array13 = new Array("a","b","c",1,2,3,true,false); //定义并赋值
var array14=[]; //空数组,语法糖
var array15=[1,2,3,"x","y"]; //定义并赋值 //4.2、访问与修改
array12[8]="hello array12"; //赋值或修改
console.log(array12[8]); //取值
//遍历
for (var i = 0; i < array13.length; i++) {
//console.log("arrayl3["+i+"]="+array13[i]);
}
//枚举
for(var i in array15){
//console.log(i+"="+array15[i]); //此处的i是下标
} //4.3、添加元素
var array31=[5,8];
//添加到末尾
array31.push(9);
var len=array31.push(10,11);
console.log("长度为:"+len+"——"+array31);
//添加到开始
array31.unshift(4);
var len=array31.unshift(1,2,3);
console.log("长度为:"+len+"——"+array31);
//添加到中间
var len=array31.splice(5,1,6,7); //从第5位开始插入,删除第5位后的1个元素,返回被删除元素
console.log("被删除:"+len+"——"+array31); //4.4、删除
var array41=[1,2,3,4,5,6,7,8];
console.log("array41:"+array41);
//删除最后一个元素,并返回
var e=array41.pop();
console.log("被删除:"+e+"——"+array41);
//删除首部元素,并返回
var e=array41.shift();
console.log("被删除:"+e+"——"+array41);
//删除指定位置与个数
var e=array41.splice(1,4); //从索引1开始删除4个
console.log("被删除:"+e+"——"+array41); //4.5、截取和合并
var array51=[1,2,3,4,5,6];
var array52=[7,8,9,0,"a","b","c"];
//截取,切片
var array53=array51.slice(2); //从第3个元素开始截取到最后
console.log("被截取:"+array53+"——"+array51);
var array54=array51.slice(1,4); //从第3个元素开始截取到索引号为3的元素
console.log("被截取:"+array54+"——"+array51);
//合并
var array55=array51.concat(array52,["d","e"],"f","g");
console.log("合并后:"+array55); //4.7、排序
var array71=[4,5,6,1,2,3];
array71.sort();
console.log("排序后:"+array71);
var array72=[{name:"tom",age:19},{name:"jack",age:20},{name:"lucy",age:18}];
array72.sort(function(user1,user2){
return user1.age<user2.age;
});
console.log("排序后:");
for(var i in array72) console.log(array72[i].name+","+array72[i].age); //4.8、合并成字符与将字符拆分成数组
var array81=[1,3,5,7,9];
var ids=array81.join(",");
console.log(ids); //拆分成数组
var text="hello nodejs and angular";
var array82=text.split(" ");
console.log(array82); </script>
</body> </html>
2.5、正则表达式RegExp
RegExp 对象表示正则表达式,它是对字符串执行模式匹配的强大工具。
RegExp对象:该对象代表正则表达式,用于字符串匹配
① 两种RegExp对象创建方式:
方式一,new 一个RegExp对象:var regExp = new RegExp(“[a-zA-Z0-9]{3,8}”);
方式二,通过字面量赋值:var regExp = /^[a-zA-Z0-9]{3,8}$/;
② 正则表达式的具体写法使用时查询文档。
③ 常用方法:test(string),返回true或false。
直接量语法
/pattern/attributes
创建 RegExp 对象的语法:
new RegExp(pattern, attributes);
参数
参数 pattern 是一个字符串,指定了正则表达式的模式或其他正则表达式。
参数 attributes 是一个可选的字符串,包含属性 "g"、"i" 和 "m",分别用于指定全局匹配、区分大小写的匹配和多行匹配。ECMAScript 标准化之前,不支持 m 属性。如果 pattern 是正则表达式,而不是字符串,则必须省略该参数。
返回值
一个新的 RegExp 对象,具有指定的模式和标志。如果参数 pattern 是正则表达式而不是字符串,那么 RegExp() 构造函数将用与指定的 RegExp 相同的模式和标志创建一个新的 RegExp 对象。
如果不用 new 运算符,而将 RegExp() 作为函数调用,那么它的行为与用 new 运算符调用时一样,只是当 pattern 是正则表达式时,它只返回 pattern,而不再创建一个新的 RegExp 对象。
抛出
SyntaxError - 如果 pattern 不是合法的正则表达式,或 attributes 含有 "g"、"i" 和 "m" 之外的字符,抛出该异常。
TypeError - 如果 pattern 是 RegExp 对象,但没有省略 attributes 参数,抛出该异常。
关于全局匹配所有的正则表达式都有一个lastIndex属性,用于记录上一次匹配结束的位置。如果不是全局匹配模式,那lastIndex的值始终为0,在匹配过一次后,将会停止匹配。
正则表达式的全局匹配模式,就是在创建正则表达式的时候使用g标识符或者将global属性设置为true,在全局匹配模式下,正则表达式会对指定要查找的字符串执行多次匹配。每次匹配使用当前正则对象的lastIndex属性的值作为在目标字符串中开始查找的起始位置。如果找不到匹配的项lastIndex的值会被重新设置为0。
var regex = /abc/g;
var str = '123#abc';
console.log(regex.lastIndex); //
console.log(regex.test(str)); // true
console.log(regex.lastIndex); //
console.log(regex.test(str)); // false
console.log(regex.lastIndex); //
console.log(regex.test(str)); // true
console.log(regex.lastIndex); //
console.log(regex.test(str)); // false
方括号
方括号用于查找某个范围内的字符:
表达式 | 描述 |
---|---|
[abc] | 查找方括号之间的任何字符。 |
[^abc] | 查找任何不在方括号之间的字符。 |
[0-9] | 查找任何从 0 至 9 的数字。 |
[a-z] | 查找任何从小写 a 到小写 z 的字符。 |
[A-Z] | 查找任何从大写 A 到大写 Z 的字符。 |
[A-z] | 查找任何从大写 A 到小写 z 的字符。 |
[adgk] | 查找给定集合内的任何字符。 |
[^adgk] | 查找给定集合外的任何字符。 |
(red|blue|green) | 查找任何指定的选项。 |
元字符
元字符(Metacharacter)是拥有特殊含义的字符:
元字符 | 描述 |
---|---|
. | 查找单个字符,除了换行和行结束符。 |
\w | 查找单词字符。 |
\W | 查找非单词字符。 |
\d | 查找数字。 |
\D | 查找非数字字符。 |
\s | 查找空白字符。 |
\S | 查找非空白字符。 |
\b | 匹配单词边界。 |
\B | 匹配非单词边界。 |
\0 | 查找 NUL 字符。 |
\n | 查找换行符。 |
\f | 查找换页符。 |
\r | 查找回车符。 |
\t | 查找制表符。 |
\v | 查找垂直制表符。 |
\xxx | 查找以八进制数 xxx 规定的字符。 |
\xdd | 查找以十六进制数 dd 规定的字符。 |
\uxxxx | 查找以十六进制数 xxxx 规定的 Unicode 字符。 |
量词
量词 | 描述 |
---|---|
n+ | 匹配任何包含至少一个 n 的字符串。 |
n* | 匹配任何包含零个或多个 n 的字符串。 |
n? | 匹配任何包含零个或一个 n 的字符串。 |
n{X} | 匹配包含 X 个 n 的序列的字符串。 |
n{X,Y} | 匹配包含 X 至 Y 个 n 的序列的字符串。 |
n{X,} | 匹配包含至少 X 个 n 的序列的字符串。 |
n$ | 匹配任何结尾为 n 的字符串。 |
^n | 匹配任何开头为 n 的字符串。 |
?=n | 匹配任何其后紧接指定字符串 n 的字符串。 |
?!n | 匹配任何其后没有紧接指定字符串 n 的字符串。 |
RegExp 对象属性
属性 | 描述 | FF | IE |
---|---|---|---|
global | RegExp 对象是否具有标志 g。 | 1 | 4 |
ignoreCase | RegExp 对象是否具有标志 i。 | 1 | 4 |
lastIndex | 一个整数,标示开始下一次匹配的字符位置。 | 1 | 4 |
multiline | RegExp 对象是否具有标志 m。 | 1 | 4 |
source | 正则表达式的源文本。 | 1 | 4 |
RegExp 对象方法
方法 | 描述 | FF | IE |
---|---|---|---|
compile | 编译正则表达式。 | 1 | 4 |
exec | 检索字符串中指定的值。返回找到的值,并确定其位置。 | 1 | 4 |
test | 检索字符串中指定的值。返回 true 或 false。 | 1 | 4 |
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script type="text/javascript">
var reg1=/\d{2}/igm; //定义正则
var reg2=new RegExp("\D{2}","igm"); //定义正则 //验证邮政编码
var reg3=/^\d{6}$/igm;
console.log(reg3.test("519000")); //true
console.log(reg3.test("abc123")); //false //查找同时出现3个字母的索引
var reg4=new RegExp("[A-Za-z]{3}","igm");
console.log(reg4.exec("ab1cd2efg3lw3sd032kjsdljkf23sdlk"));
//["efg", index: 6, input: "ab1cd2efg3lw3sd032kjsdljkf23sdlk"] //身份证
//411081199004235955 41108119900423595x 41108119900423595X //邮箱
//zhangguo123@qq.com zhangguo@sina.com.cn
</script>
</body>
</html>
结果:
支持正则表达式的 String 对象的方法
方法 | 描述 | FF | IE |
---|---|---|---|
search | 检索与正则表达式相匹配的值。 | 1 | 4 |
match | 找到一个或多个正则表达式的匹配。 | 1 | 4 |
replace | 替换与正则表达式匹配的子串。 | 1 | 4 |
split | 把字符串分割为字符串数组。 | 1 | 4 |
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script type="text/javascript">
var reg1=/\d{2}/igm;
console.log("kjds23sd9we23sdoi1we230we12sd".search(reg1)); //4 第一次匹配成功的索引
console.log("kjds23sd9we56sdoi1we780we98sd".match(reg1)); //["23", "56", "78", "98"] //删除所有数字
console.log("kjds23sd9we56sdoi1we780we98sd".replace(/\d/igm,"")); //kjdssdwesdoiwewesd //所有数字增加大括号,反向引用 $组号 括号用于分组
console.log("kjds23sd9we56sdoi1we780we98sd".replace(/(\d+)/igm,"\{$1\}")); //kjds{23}sd{9}we{56}sdoi{1}we{780}we{98}sd //拆分
console.log("kjds23sd9we56sdoi1we780we98sd".split(/[w\d]+/)); //["kjds", "sd", "e", "sdoi", "e", "e", "sd"] //ID (虚拟的)
//411081197104235955 411081198600423595x 41108119880423595X
//^\d{17}[xX0-9]{1}$ //Email
//zhangguo123@qq.com zhangguo@sina.com.cn
//\w+@\w+\.\w{2,5}(\.\w{2,5})?
</script>
</body>
</html>
结果:
2.6、字符串对象String
字符串是 JavaScript 的一种基本的数据类型。
String 对象的 length 属性声明了该字符串中的字符数。
String 类定义了大量操作字符串的方法,例如从字符串中提取字符或子串,或者检索字符或子串。
需要注意的是,JavaScript 的字符串是不可变的(immutable),String 类定义的方法都不能改变字符串的内容。像 String.toUpperCase() 这样的方法,返回的是全新的字符串,而不是修改原始字符串。
String 对象属性
属性 | 描述 |
---|---|
constructor | 对创建该对象的函数的引用 |
length | 字符串的长度 |
prototype | 允许您向对象添加属性和方法 |
String 对象方法
方法 | 描述 |
---|---|
anchor() | 创建 HTML 锚。 |
big() | 用大号字体显示字符串。 |
blink() | 显示闪动字符串。 |
bold() | 使用粗体显示字符串。 |
charAt() | 返回在指定位置的字符。 |
charCodeAt() | 返回在指定的位置的字符的 Unicode 编码。 |
concat() | 连接字符串。 |
fixed() | 以打字机文本显示字符串。 |
fontcolor() | 使用指定的颜色来显示字符串。 |
fontsize() | 使用指定的尺寸来显示字符串。 |
fromCharCode() | 从字符编码创建一个字符串。 |
indexOf() | 检索字符串。 |
italics() | 使用斜体显示字符串。 |
lastIndexOf() | 从后向前搜索字符串。 |
link() | 将字符串显示为链接。 |
localeCompare() | 用本地特定的顺序来比较两个字符串。 |
match() | 找到一个或多个正则表达式的匹配。 |
replace() | 替换与正则表达式匹配的子串。 |
search() | 检索与正则表达式相匹配的值。 |
slice() | 提取字符串的片断,并在新的字符串中返回被提取的部分。 |
small() | 使用小字号来显示字符串。 |
split() | 把字符串分割为字符串数组。 |
strike() | 使用删除线来显示字符串。 |
sub() | 把字符串显示为下标。 |
substr() | 从起始索引号提取字符串中指定数目的字符。 |
substring() | 提取字符串中两个指定的索引号之间的字符。 |
sup() | 把字符串显示为上标。 |
toLocaleLowerCase() | 把字符串转换为小写。 |
toLocaleUpperCase() | 把字符串转换为大写。 |
toLowerCase() | 把字符串转换为小写。 |
toUpperCase() | 把字符串转换为大写。 |
toSource() | 代表对象的源代码。 |
toString() | 返回字符串。 |
valueOf() | 返回某个字符串对象的原始值。 |
2.7、时间日期对象Date
Date 对象用于处理日期和时间。
创建 Date 对象的语法:
var myDate=new Date();
注释:Date 对象会自动把当前日期和时间保存为其初始值。
Date 对象属性
属性 | 描述 |
---|---|
constructor | 返回对创建此对象的 Date 函数的引用。 |
prototype | 使您有能力向对象添加属性和方法。 |
Date 对象方法
方法 | 描述 |
---|---|
Date() | 返回当日的日期和时间。 |
getDate() | 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 |
getDay() | 从 Date 对象返回一周中的某一天 (0 ~ 6)。 |
getMonth() | 从 Date 对象返回月份 (0 ~ 11)。 |
getFullYear() | 从 Date 对象以四位数字返回年份。 |
getYear() | 请使用 getFullYear() 方法代替。 |
getHours() | 返回 Date 对象的小时 (0 ~ 23)。 |
getMinutes() | 返回 Date 对象的分钟 (0 ~ 59)。 |
getSeconds() | 返回 Date 对象的秒数 (0 ~ 59)。 |
getMilliseconds() | 返回 Date 对象的毫秒(0 ~ 999)。 |
getTime() | 返回 1970 年 1 月 1 日至今的毫秒数。 |
getTimezoneOffset() | 返回本地时间与格林威治标准时间 (GMT) 的分钟差。 |
getUTCDate() | 根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。 |
getUTCDay() | 根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。 |
getUTCMonth() | 根据世界时从 Date 对象返回月份 (0 ~ 11)。 |
getUTCFullYear() | 根据世界时从 Date 对象返回四位数的年份。 |
getUTCHours() | 根据世界时返回 Date 对象的小时 (0 ~ 23)。 |
getUTCMinutes() | 根据世界时返回 Date 对象的分钟 (0 ~ 59)。 |
getUTCSeconds() | 根据世界时返回 Date 对象的秒钟 (0 ~ 59)。 |
getUTCMilliseconds() | 根据世界时返回 Date 对象的毫秒(0 ~ 999)。 |
parse() | 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。 |
setDate() | 设置 Date 对象中月的某一天 (1 ~ 31)。 |
setMonth() | 设置 Date 对象中月份 (0 ~ 11)。 |
setFullYear() | 设置 Date 对象中的年份(四位数字)。 |
setYear() | 请使用 setFullYear() 方法代替。 |
setHours() | 设置 Date 对象中的小时 (0 ~ 23)。 |
setMinutes() | 设置 Date 对象中的分钟 (0 ~ 59)。 |
setSeconds() | 设置 Date 对象中的秒钟 (0 ~ 59)。 |
setMilliseconds() | 设置 Date 对象中的毫秒 (0 ~ 999)。 |
setTime() | 以毫秒设置 Date 对象。 |
setUTCDate() | 根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。 |
setUTCMonth() | 根据世界时设置 Date 对象中的月份 (0 ~ 11)。 |
setUTCFullYear() | 根据世界时设置 Date 对象中的年份(四位数字)。 |
setUTCHours() | 根据世界时设置 Date 对象中的小时 (0 ~ 23)。 |
setUTCMinutes() | 根据世界时设置 Date 对象中的分钟 (0 ~ 59)。 |
setUTCSeconds() | 根据世界时设置 Date 对象中的秒钟 (0 ~ 59)。 |
setUTCMilliseconds() | 根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。 |
toSource() | 返回该对象的源代码。 |
toString() | 把 Date 对象转换为字符串。 |
toTimeString() | 把 Date 对象的时间部分转换为字符串。 |
toDateString() | 把 Date 对象的日期部分转换为字符串。 |
toGMTString() | 请使用 toUTCString() 方法代替。 |
toUTCString() | 根据世界时,把 Date 对象转换为字符串。 |
toLocaleString() | 根据本地时间格式,把 Date 对象转换为字符串。 |
toLocaleTimeString() | 根据本地时间格式,把 Date 对象的时间部分转换为字符串。 |
toLocaleDateString() | 根据本地时间格式,把 Date 对象的日期部分转换为字符串。 |
UTC() | 根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。 |
valueOf() | 返回 Date 对象的原始值。 |
2.8、数学对象Math
Math 对象并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math(),像 Math.sin() 这样的函数只是函数,不是某个对象的方法。您无需创建它,通过把 Math 作为对象使用就可以调用其所有属性和方法。
var pi_value=Math.PI;
var sqrt_value=Math.sqrt(15);
Math 对象属性
属性 | 描述 |
---|---|
E | 返回算术常量 e,即自然对数的底数(约等于2.718)。 |
LN2 | 返回 2 的自然对数(约等于0.693)。 |
LN10 | 返回 10 的自然对数(约等于2.302)。 |
LOG2E | 返回以 2 为底的 e 的对数(约等于 1.414)。 |
LOG10E | 返回以 10 为底的 e 的对数(约等于0.434)。 |
PI | 返回圆周率(约等于3.14159)。 |
SQRT1_2 | 返回返回 2 的平方根的倒数(约等于 0.707)。 |
SQRT2 | 返回 2 的平方根(约等于 1.414)。 |
Math 对象方法
方法 | 描述 |
---|---|
abs(x) | 返回数的绝对值。 |
acos(x) | 返回数的反余弦值。 |
asin(x) | 返回数的反正弦值。 |
atan(x) | 以介于 -PI/2 与 PI/2 弧度之间的数值来返回 x 的反正切值。 |
atan2(y,x) | 返回从 x 轴到点 (x,y) 的角度(介于 -PI/2 与 PI/2 弧度之间)。 |
ceil(x) | 对数进行上舍入。 |
cos(x) | 返回数的余弦。 |
exp(x) | 返回 e 的指数。 |
floor(x) | 对数进行下舍入。 |
log(x) | 返回数的自然对数(底为e)。 |
max(x,y) | 返回 x 和 y 中的最高值。 |
min(x,y) | 返回 x 和 y 中的最低值。 |
pow(x,y) | 返回 x 的 y 次幂。 |
random() | 返回 0 ~ 1 之间的随机数。 |
round(x) | 把数四舍五入为最接近的整数。 |
sin(x) | 返回数的正弦。 |
sqrt(x) | 返回数的平方根。 |
tan(x) | 返回角的正切。 |
toSource() | 返回该对象的源代码。 |
valueOf() | 返回 Math 对象的原始值。 |
2.9、JavaScript 全局对象
全局属性和函数可用于所有内建的 JavaScript 对象。
全局对象是预定义的对象,作为 JavaScript 的全局函数和全局属性的占位符。通过使用全局对象,可以访问所有其他所有预定义的对象、函数和属性。全局对象不是任何对象的属性,所以它没有名称。
在顶层 JavaScript 代码中,可以用关键字 this 引用全局对象。但通常不必用这种方式引用全局对象,因为全局对象是作用域链的头,这意味着所有非限定性的变量和函数名都会作为该对象的属性来查询。例如,当JavaScript 代码引用 parseInt() 函数时,它引用的是全局对象的 parseInt 属性。全局对象是作用域链的头,还意味着在顶层 JavaScript 代码中声明的所有变量都将成为全局对象的属性。
全局对象只是一个对象,而不是类。既没有构造函数,也无法实例化一个新的全局对象。
在 JavaScript 代码嵌入一个特殊环境中时,全局对象通常具有环境特定的属性。实际上,ECMAScript 标准没有规定全局对象的类型,JavaScript 的实现或嵌入的 JavaScript 都可以把任意类型的对象作为全局对象,只要该对象定义了这里列出的基本属性和函数。例如,在允许通过 LiveConnect 或相关的技术来脚本化 Java 的 JavaScript 实现中,全局对象被赋予了这里列出的 java 和 Package 属性以及 getClass() 方法。而在客户端 JavaScript 中,全局对象就是 Window 对象,表示允许 JavaScript 代码的 Web 浏览器窗口。
顶层函数(全局函数)
函数 | 描述 |
---|---|
decodeURI() | 解码某个编码的 URI。 |
decodeURIComponent() | 解码一个编码的 URI 组件。 |
encodeURI() | 把字符串编码为 URI。 |
encodeURIComponent() | 把字符串编码为 URI 组件。 |
escape() | 对字符串进行编码。 |
eval() | 计算 JavaScript 字符串,并把它作为脚本代码来执行。 |
getClass() | 返回一个 JavaObject 的 JavaClass。 |
isFinite() | 检查某个值是否为有穷大的数。 |
isNaN() | 检查某个值是否是数字。 |
Number() | 把对象的值转换为数字。 |
parseFloat() | 解析一个字符串并返回一个浮点数。 |
parseInt() | 解析一个字符串并返回一个整数。 |
String() | 把对象的值转换为字符串。 |
unescape() | 对由 escape() 编码的字符串进行解码。 |
顶层属性(全局属性)
方法 | 描述 |
---|---|
Infinity | 代表正的无穷大的数值。 |
java | 代表 java.* 包层级的一个 JavaPackage。 |
NaN | 指示某个值是不是数字值。 |
Packages | 根 JavaPackage 对象。 |
undefined | 指示未定义的值。 |
在 JavaScript 核心语言中,全局对象的预定义属性都是不可枚举的,所有可以用 for/in 循环列出所有隐式或显式声明的全局变量,如下所示:
var variables = "";
for (var name in this)
{
variables += name + "、";
}
document.write(variables);
结果:
2.10、JavaScript避免使用的语法
1)、 ==
Javascript有两组相等运算符,一组是==和!=,另一组是===和!==。前者只比较值的相等,后者除了值以外,还比较类型是否相同。
请尽量不要使用前一组,永远只使用===和!==。因为==默认会进行类型转换,规则十分难记。如果你不相信的话,请回答下面五个判断式的值是true还是false:
false == 'false'
false == undefined
false == null
null == undefined
0 == ''
前三个是false,后两个是true。
答案
2)、with
with的本意是减少键盘输入。比如
obj.a = obj.b;
obj.c = obj.d;
可以简写成
with(obj) {
a = b;
c = d;
}
但是,在实际运行时,解释器会首先判断obj.b和obj.d是否存在,如果不存在的话,再判断全局变量b和d是否存在。这样就导致了低效率,而且可能会导致意外,因此最好不要使用with语句。
3)、eval
eval用来直接执行一个字符串。这条语句也是不应该使用的,因为它有性能和安全性的问题,并且使得代码更难阅读。
eval能够做到的事情,不用它也能做到。比如
eval("myValue = myObject." + myKey + ";");
可以直接写成
myValue = myObject[myKey];
至于ajax操作返回的json字符串,可以使用官方网站提供的解析器json_parse.js运行。
4)、 continue
这条命令的作用是返回到循环的头部,但是循环本来就会返回到头部。所以通过适当的构造,完全可以避免使用这条命令,使得效率得到改善。
5)、switch 贯穿
switch结构中的case语句,默认是顺序执行,除非遇到break,return和throw。有的程序员喜欢利用这个特点,比如
switch(n) {
case 1:
case 2:
break;
}
这样写容易出错,而且难以发现。因此建议避免switch贯穿,凡是有case的地方,一律加上break。
switch(n) {
case 1:
break;
case 2:
break;
}
6)、单行的块结构
if、while、do和for,都是块结构语句,但是也可以接受单行命令。比如
if (ok) t = true;
甚至写成
if (ok)
t = true;
这样不利于阅读代码,而且将来添加语句时非常容易出错。建议不管是否只有一行命令,都一律加上大括号。
if (ok){
t = true;
}
7)、 ++和--
递增运算符++和递减运算符--,直接来自C语言,表面上可以让代码变得很紧凑,但是实际上会让代码看上去更复杂和更晦涩。因此为了代码的整洁性和易读性,不用为好。
8)、位运算符
Javascript完全套用了Java的位运算符,包括按位与&、按位或|、按位异或^、按位非~、左移<<、带符号的右移>>和用0补足的右移>>>。
这套运算符针对的是整数,所以对Javascript完全无用,因为Javascript内部,所有数字都保存为双精度浮点数。如果使用它们的话,Javascript不得不将运算数先转为整数,然后再进行运算,这样就降低了速度。而且"按位与运算符"&同"逻辑与运算符"&&,很容易混淆。
9)、function语句
在Javascript中定义一个函数,有两种写法:
function foo() { }
和
var foo = function () { }
两种写法完全等价。但是在解析的时候,前一种写法会被解析器自动提升到代码的头部,因此违背了函数应该先定义后使用的要求,所以建议定义函数时,全部采用后一种写法。
10)、基本数据类型的包装对象
Javascript的基本数据类型包括字符串、数字、布尔值,它们都有对应的包装对象String、Number和Boolean。所以,有人会这样定义相关值:
new String("Hello World");
new Number(2000);
new Boolean(false);
这样写完全没有必要,而且非常费解,因此建议不要使用。
另外,new Object和new Array也不建议使用,可以用{}和[]代替。
11)、new语句
Javascript是世界上第一个被大量使用的支持Lambda函数的语言,本质上属于与Lisp同类的函数式编程语言。但是当前世界,90%以上的程序员都是使用面向对象编程。为了靠近主流,Javascript做出了妥协,采纳了类的概念,允许根据类生成对象。
类是这样定义的:
var Cat = function (name) {
this.name = name;
this.saying = 'meow' ;
}
然后,再生成一个对象
var myCat = new Cat('mimi');
这种利用函数生成类、利用new生成对象的语法,其实非常奇怪,一点都不符合直觉。而且,使用的时候,很容易忘记加上new,就会变成执行函数,然后莫名其妙多出几个全局变量。所以,建议不要这样创建对象,而采用一种变通方法。
Douglas Crockford给出了一个函数:
Object.beget = function (o) {
var F = function (o) {};
F.prototype = o ;
return new F;
};
创建对象时就利用这个函数,对原型对象进行操作:
var Cat = {
name:'',
saying:'meow'
}; var myCat = Object.beget(Cat);
对象生成后,可以自行对相关属性进行赋值:
myCat.name = 'mimi';
12)、void
在大多数语言中,void都是一种类型,表示没有值。但是在Javascript中,void是一个运算符,接受一个运算数,并返回undefined。
void 0; // undefined
这个命令没什么用,而且很令人困惑,建议避免使用。
三、BOM
3.1、BOM概要
BOM(Browser Object Model) 即浏览器对象模型,主要是指一些浏览器内置对象如:window、location、navigator、screen、history等对象,用于完成一些操作浏览器的特定API。
用于描述这种对象与对象之间层次关系的模型,浏览器对象模型提供了独立于内容的、可以与浏览器窗口进行互动的对象结构。BOM由多个对象组成,其中代表浏览器窗口的Window对象是BOM的顶层对象,其他对象都是该对象的子对象。
- BOM是browser object model的缩写,简称浏览器对象模型
- BOM提供了独立于内容而与浏览器窗口进行交互的对象
- 由于BOM主要用于管理窗口与窗口之间的通讯,因此其核心对象是window
- BOM由一系列相关的对象构成,并且每个对象都提供了很多方法与属性
- BOM缺乏标准,JavaScript语法的标准化组织是ECMA,DOM的标准化组织是W3C
- BOM最初是Netscape浏览器标准的一部分
BOM结构
从上图可以看出:DOM是属于BOM的一个属性。
window对象是BOM的顶层(核心)对象,所有对象都是通过它延伸出来的,也可以称为window的子对象。
由于window是顶层对象,因此调用它的子对象时可以不显示的指明window对象。
以下两种写法均可:
document.write("best.cnblogs.com");
window.document.write("best.cnblogs.com");
3.2、BOM导图
BOM部分主要是针对浏览器的内容,其中常用的就是window对象和location
window是全局对象很多关于浏览器的脚本设置都是通过它。
location则是与地址栏内容相关,比如想要跳转到某个页面,或者通过URL获取一定的内容。
navigator中有很多浏览器相关的内容,通常判断浏览器类型都是通过这个对象。
screen常常用来判断屏幕的高度宽度等。
history访问浏览器的历史记录,如前进、后台、跳转到指定位置。
3.3、window对象
window对象在浏览器中具有双重角色:它既是ECMAscript规定的全局global对象,又是javascript访问浏览器窗口的一个接口。
moveBy() 函数
moveTo() 函数
resizeBy() 函数
resizeTo() 函数
scrollTo() 函数
scrollBy() 函数
focus() 函数
blur() 函数
open() 函数
close() 函数
opener 属性
alert() 函数
confirm() 函数
prompt() 函数
defaultStatus 属性
status 属性
setTimeout() 函数
clearTimeout() 函数
setInterval() 函数
clearInterval() 函数
1、获取窗口相对于屏幕左上角的位置
window.onresize = function() {
var leftPos = (typeof window.screenLeft === 'number') ? window.screenLeft : window.screenX;
var topPos = (typeof window.screenLeft === 'number') ? window.screenTop : window. screenY;
document.write(leftPos+","+topPos);
console.log(leftPos+","+topPos);
}
需要注意的一点是,在IE,opera中,screenTop保存的是页面可见区域距离屏幕左侧的距离,而chrome,firefox,safari中,screenTop/screenY保存的则是整个浏览器区域距离屏幕左侧的距离。也就是说,二者差了一个浏览器工具栏的像素高度。
2、移动窗口,调整窗口大小
window.moveTo(0,0)
window.moveBy(20,10)
window.resizeTo(100,100);
window.resizeBy(100,100);
注意,这几个方法在浏览器中很可能会被禁用。
3、获得浏览器页面视口的大小
var pageWith=document.documentElement.clientWidth||document.body.clientWidth;
var pageHeight=document.documentElement.clientHeight||document.body.clientHeight;
4、导航和打开窗口
window.open()既可以导航到特定的URL,也可以打开一个新的浏览器窗口,其接收四个参数,要加载的url,窗口目标(可以是关键字_self,_parent,_top,_blank),一个特性字符串,以及一个表示新页面是否取代浏览器历史记录中当前加载页面的布尔值。通常只需要传递第一个参数。注意,在很多浏览器中,都是阻止弹出窗口的。
5、定时器
setTimeout(code,millisec)
setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。
code 必需,要调用的函数后要执行的 JavaScript 代码串。=
millisec 必需,在执行代码前需等待的毫秒数。
clearTimeout(对象) 清除已设置的setTimeout对象
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button type="button" id="btnClear">清除</button>
<script>
var btnClear=document.getElementById("btnClear");
//5秒后禁用按钮
var timer1=setTimeout(function(){
btnClear.setAttribute("disabled","disabled");
},5000); btnClear.onclick=function(){
clearTimeout(timer1); //清除定时器
alert("定时器已停止工作,已清除");
} //递归,不推荐
function setTitle(){
document.title+="->";
setTimeout(setTitle,500);
}
setTimeout(setTitle,500);
</script>
</body>
</html>
结果:
setInterval(code,millisec[,"lang"])
setInterval() 方法可按照指定的周期(以毫秒计)来调用函数或计算表达式
code 必需,要调用的函数或要执行的代码串。
millisec 必需,周期性执行或调用code之间的时间间隔,以毫秒计。
clearInterval(对象) 清除已设置的setInterval对象
6.系统对话框,这些对话框外观由操作系统/浏览器设置决定,css不起作用,所以很多时候可能需要自定义对话框
alert():带有一个确定按钮
confirm():带有一个确定和取消按钮
prompt():显示OK和Cancel按钮之外,还会显示一个文本输入域
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<button type="button" id="btnClear" style="width: 100px;">清除</button>
<script>
var btnClear=document.getElementById("btnClear");
//每隔5秒后禁用按钮
var timer1=setInterval(function(){
btnClear.style.width=(parseInt(btnClear.style.width||0)+10)+"px";
},500); btnClear.onclick=function(){
clearInterval(timer1); //清除定时器
alert("定时器已停止工作,已清除");
} function setTitle(){
document.title+="->";
}
setInterval(setTitle,500);
</script>
</body>
</html>
结果:
6、scroll系列方法
scrollHeight和scrollWidth 对象内部的实际内容的高度/宽度(不包括border)
scrollTop和scrollLeft 被卷去部分的顶部/左侧 到 可视区域 顶部/左侧 的距离
onscroll事件 滚动条滚动触发的事件
页面滚动坐标:
var scrollTop = window.pageYoffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
3.4、document 对象
请参考DOM一节的内容
write() 函数
writeln() 函数
document.open() 函数
document.close() 函数
3.5、location对象
location对象提供了当前窗口加载的文档的相关信息,还提供了一些导航功能。事实上,这是一个很特殊的对象,location既是window对象的属性,又是document对象的属性。
location.hash #contents 返回url中的hash,如果不包含#后面的内容,则返回空字符串
location.host best.cnblogs.com:80 返回服务器名称和端口号
location.port 80 返回端口号
location.hostname best.cnblogs.com 返回服务器名称
location.href http://best.cnblogs.com 返回当前加载页面的完整url
location.pathname /index.html 返回url中的目录和文件名
location.protocol http 返回页面使用的协议
location.search ?q=javascript 返回url中的查询字符串
改变浏览器的位置:location.href=http://www.baidu.com
如果使用location.replace('http://www.baidu.com'),不会在历史记录中生成新纪录,用户不能回到前一个页面。
location.reload():重置当前页面,可能从缓存,也可能从服务器;如果强制从服务器取得,传入true参数
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<script type="text/javascript">
console.log(location.href);
console.log(location.port);
console.log(location.search);
//location.href=location.href; //刷新
//location.reload(true); //强制加载,不加true则从缓存中刷新
</script>
</body>
</html>
结果:
3.6、history对象
history对象保存着用户上网的历史记录,使用go()实现在用户的浏览记录中跳转:
history.go(-1) 等价于history.back() history.go(1) 等价于 history.forward() history.go(1) //前进两页 history.go('cnblogs.com')
3.7、navigator对象
这个对象代表浏览器实例,其属性很多,但常用的不太多。如下:
navigator.userAgent:用户代理字符串,用于浏览器监测中、
navigator.plugins:浏览器插件数组,用于插件监测
navigator.registerContentHandler 注册处理程序,如提供RSS阅读器等在线处理程序。
示例代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Title</title>
</head>
<body>
<SCRIPT>
document.write("<br/>浏览器名称");
document.write(navigator.appCodeName);
document.write("<br/>次版本信息");
document.write(navigator.appMinorVersion);
document.write("<br/>完整的浏览器名称");
document.write(navigator.appName);
document.write("<br/>浏览器版本");
document.write(navigator.appVersion);
document.write("<br/>浏览器编译版本");
document.write(navigator.buildID);
document.write("<br/>是否启用cookie");
document.write(navigator.cookieEnabled);
document.write("<br/>客户端计算机CPU类型");
document.write(navigator.cpuClass);
document.write("<br/>浏览器是否启用java");
document.write(navigator.javaEnabled());
document.write("<br/>浏览器主语言");
document.write(navigator.language);
document.write("<br/>浏览器中注册的MIME类型数组");
document.write(navigator.mimeTypes);
document.write("<br/>是否连接到网络");
document.write(navigator.onLine);
document.write("<br/>客户端计算机操作系统或者CPU");
document.write(navigator.oscpu);
document.write("<br/>浏览器所在的系统平台");
document.write(navigator.platform);
document.write("<br/>浏览器中插件信息数组");
document.write(navigator.plugins);
document.write("<br/>用户的首选项");
// document.write(navigator.preference());
document.write("<br/>产品名称");
document.write(navigator.product);
document.write("<br/>产品的次要信息");
document.write(navigator.productSub);
document.write("<br/>操作系统的语言");
document.write(navigator.systemLanguage);
document.write("<br/>浏览器的用户代理字符串");
document.write(navigator. userAgent);
document.write("<br/>操作系统默认语言");
document.write(navigator.userLanguage);
document.write("<br/>用户个人信息对象");
document.write(navigator.userProfile);
document.write("<br/>浏览器品牌");
document.write(navigator.vendor);
document.write("<br/>浏览器供应商次要信息");
document.write(navigator.vendorSub);
</SCRIPT>
</body>
</html>
运行结果:
/*
浏览器名称Mozilla
次版本信息undefined
完整的浏览器名称Netscape
浏览器版本5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
浏览器编译版本undefined
是否启用cookietrue
客户端计算机CPU类型undefined
浏览器是否启用javafalse
浏览器主语言zh-CN
浏览器中注册的MIME类型数组[object MimeTypeArray]
是否连接到网络true
客户端计算机操作系统或者CPUundefined
浏览器所在的系统平台Win32
浏览器中插件信息数组[object PluginArray]
用户的首选项
产品名称Gecko
产品的次要信息20030107
操作系统的语言undefined
浏览器的用户代理字符串Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
操作系统默认语言undefined
用户个人信息对象undefined
浏览器品牌Google Inc.
浏览器供应商次要信息
*/
四、DOM
DOM(文档对象模型)是针对HTML和XML文档的一个API,通过DOM可以去改变文档。
DOM模型将整个文档(XML文档和HTML文档)看成一个树形结构,并用document对象表示该文档。
DOM规定文档中的每个成分都是一个节点(Node):
文档节点(Document):代表整个文档
元素节点(Element):文档中的一个标记
文本节点(Text):标记中的文本
属性节点(Attr):代表一个属性,元素才有属性
4.1、节点类型
12中节点类型都有NodeType属性来表明节点类型
节点类型 | 描述 | |
---|---|---|
1 | Element | 代表元素 |
2 | Attr | 代表属性 |
3 | Text | 代表元素或属性中的文本内容。 |
4 | CDATASection | 代表文档中的 CDATA 部分(不会由解析器解析的文本)。 |
5 | EntityReference | 代表实体引用。 |
6 | Entity | 代表实体。 |
7 | ProcessingInstruction | 代表处理指令。 |
8 | Comment | 代表注释。 |
9 | Document | 代表整个文档(DOM 树的根节点)。 |
10 | DocumentType | 向为文档定义的实体提供接口 |
11 | DocumentFragment | 代表轻量级的 Document 对象,能够容纳文档的某个部分 |
12 | Notation | 代表 DTD 中声明的符号。 |
示例:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title>DOM</title>
</head> <body>
<div id="div1"></div>
<script type="text/javascript">
var div1 = document.getElementById("div1");
console.log(div1.nodeType); //结点类型 1 Element 代表元素
console.log(div1.nodeName); //DIV 结点名称
var id = div1.getAttributeNode("id"); //获得div1的属性结点id
console.log(id.nodeType); //2 Attr 代表属性
console.log(id.nodeName); //id 结点名称
</script>
</body> </html>
结果:
4.2、节点关系
nodeType | 返回节点类型的数字值(1~12) |
nodeName | 元素节点:标签名称(大写)、属性节点:属性名称、文本节点:#text、文档节点:#document |
nodeValue | 文本节点:包含文本、属性节点:包含属性、元素节点和文档节点:null |
parentNode | 父节点 |
parentElement | 父节点标签元素 |
childNodes | 所有子节点 |
children | 第一层子节点 |
firstChild | 第一个子节点,Node 对象形式 |
firstElementChild | 第一个子标签元素 |
lastChild | 最后一个子节点 |
lastElementChild | 最后一个子标签元素 |
previousSibling | 上一个兄弟节点 |
previousElementSibling | 上一个兄弟标签元素 |
nextSibling | 下一个兄弟节点 |
nextElementSibling | 下一个兄弟标签元素 |
childElementCount | 第一层子元素的个数(不包括文本节点和注释) |
ownerDocument | 指向整个文档的文档节点 |
节点关系方法:
hasChildNodes() 包含一个或多个节点时返回true
contains() 如果是后代节点返回true
isSameNode()、isEqualNode() 传入节点与引用节点的引用为同一个对象返回true
compareDocumentPostion() 确定节点之间的各种关系
示例:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title>DOM</title>
</head> <body>
<div id="div1">
<p id="p1">p1</p>
<p id="p2">p2</p>
<p id="p3">p3</p>
</div>
<script type="text/javascript">
var div1 = document.getElementById("div1");
console.log(div1.firstChild); //换行
console.log(div1.firstElementChild); //p1结点
var childs=div1.childNodes; //所有子节点
for(var i=0;i<childs.length;i++){
console.log(childs[i]);
}
console.log(div1.hasChildNodes());
</script>
</body>
</html>
结果:
4.3、选择器
getElementById() |
一个参数:元素标签的ID |
getElementsByTagName() | 一个参数:元素标签名 |
getElementsByName() | 一个参数:name属性名 |
getElementsByClassName() | 一个参数:包含一个或多个类名的字符串 |
classList |
返回所有类名的数组
|
querySelector() | 接收CSS选择符,返回匹配到的第一个元素,没有则null |
querySelectorAll() | 接收CSS选择符,返回一个数组,没有则返回[] |
示例:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title>DOM</title>
<style type="text/css">
.red {
color: red;
} .blue {
color: blue;
}
</style>
</head> <body>
<div id="div1" class="c1 c2 red">
<p id="p1">p1</p>
<p id="p2">p2</p>
<p id="p3">p3</p>
</div>
<script type="text/javascript">
var ps = document.getElementsByTagName("p");
console.log(ps); var div1 = document.querySelector("#div1");
console.log(div1.classList);
div1.classList.add("blue"); //增加新式
div1.classList.toggle("green"); //有就删除,没有就加
div1.classList.toggle("red");
console.log(div1.classList);
</script>
</body> </html>
结果:
4.4、样式操作方法style
style.cssText | 可对style中的代码进行读写 |
style.item() | 返回给定位置的CSS属性的名称 |
style.length | style代码块中参数个数 |
style.getPropertyValue() | 返回给定属性的字符串值 |
style.getPropertyPriority() | 检测给定属性是否设置了!important,设置了返回"important";否则返回空字符串 |
style.removeProperty() | 删除指定属性 |
style.setProperty() | 设置属性,可三个参数:设置属性名,设置属性值,是否设置为"important"(可不写或写"") |
代码:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title>DOM</title>
<style type="text/css">
.#div1{
background-color: red;
}
</style>
</head> <body>
<div id="div1" class="c1 c2 red">
<p id="p1">p1</p>
<p id="p2">p2</p>
<p id="p3">p3</p>
</div>
<script type="text/javascript">
var div1=document.getElementById("div1");
div1.style.backgroundColor="lightgreen"; //background-color 去-变Camel命令
</script>
</body> </html>
结果:
4.5、元素节点ELEMENT
nodeName | 访问元素的标签名 |
tagName | 访问元素的标签名 |
createElement() | 创建节点 |
appendChild() | 末尾添加节点,并返回新增节点 |
insertBefore() | 参照节点之前插入节点,两个参数:要插入的节点和参照节点 |
insertAfter() | 参照节点之后插入节点,两个参数:要插入的节点和参照节点 |
replaceChild() | 替换节点,两个参数:要插入的节点和要替换的节点(被移除) |
removeChild() | 移除节点 |
cloneNode() | 克隆,一个布尔值参数,true为深拷贝,false为浅拷贝 |
importNode() | 从文档中复制一个节点,两个参数:要复制的节点和布尔值(是否复制子节点) |
insertAdjacentHTML() |
插入文本,两个参数:插入的位置和要插入文本
|
示例:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title>DOM</title>
</head> <body>
<script type="text/javascript">
var data = [{
id: 1,
name: "tom"
}, {
id: 2,
name: "rose"
}, {
id: 3,
name: "mark"
}, {
id: 4,
name: "jack"
}, {
id: 5,
"name": "lucy"
}]; var ul = document.createElement("ul");
for(var i = 0; i < data.length; i++) {
var li = document.createElement("li");
li.innerHTML = data[i].name; var span=document.createElement("span");
span.innerText=" 删除";
span.setAttribute("data-id",data[i].id);
li.appendChild(span); span.onclick=function(){
var id=this.getAttribute("data-id");
for(var i=0;i<data.length;i++){
if(data[i].id==id){
data.splice(i,1); //从data数组的第i位置开始删除1个元素
}
}
this.parentNode.parentNode.removeChild(this.parentNode);
console.log("还有:"+data.length+"个对象"+JSON.stringify(data));
} ul.appendChild(li);
}
document.body.appendChild(ul);
</script>
</body> </html>
结果:
4.6、属性节点attributes
attributes |
获取所有标签属性 |
getAttribute() | 获取指定标签属性 |
setAttribute() | 设置指定标签属 |
removeAttribute() | 移除指定标签属 |
var s = document.createAttribute("age") s.nodeValue = "18" |
创建age属性 设置属性值为18 |
示例:
<!DOCTYPE html>
<html> <head>
<meta charset="UTF-8">
<title>DOM</title>
</head> <body>
<input id="txtName" type="text" />
<script>
var txtName=document.getElementById("txtName");
txtName.setAttribute("title","这是txtName"); //设置属性
console.log(txtName.getAttribute("title")); //获得属性 //创建一个属性
var placeholder=document.createAttribute("placeholder");
placeholder.nodeValue="请输入姓名"; //设置属性值
txtName.setAttributeNode(placeholder); //添加属性
</script>
</body> </html>
结果:
4.7、文本节点TEXT
innerText | 所有的纯文本内容,包括子标签中的文本 |
outerText | 与innerText类似 |
innerHTML | 所有子节点(包括元素、注释和文本节点) |
outerHTML | 返回自身节点与所有子节点 |
textContent | 与innerText类似,返回的内容带样式 |
data | 文本内容 |
length | 文本长度 |
createTextNode() | 创建文本 |
normalize() | 删除文本与文本之间的空白 |
splitText() | 分割 |
appendData() | 追加 |
deleteData(offset,count) | 从offset指定的位置开始删除count个字符 |
insertData(offset,text) | 在offset指定的位置插入text |
replaceData(offset,count,text) | 替换,从offset开始到offscount处的文本被text替换 |
substringData(offset,count) | 提取从ffset开始到offscount处的文本 |
4.8、文档节点 Document
document.documentElement | 代表页面中的<html>元素 |
document.body | 代表页面中的<body>元素 |
document.doctype | 代表<!DOCTYPE>标签 |
document.head | 代表页面中的<head>元素 |
document.title | 代表<title>元素的文本,可修改 |
document.URL | 当前页面的URL地址 |
document.domain | 当前页面的域名 |
document.charset | 当前页面使用的字符集 |
document.defaultView | 返回当前 document 对象所关联的 window 对象,没有返回 null |
document.anchors | 文档中所有带name属性的<a>元素 |
document.links | 文档中所有带href属性的<a>元素 |
document.forms | 文档中所有的<form>元素 |
document.images | 文档中所有的<img>元素 |
document.readyState | 两个值:loading(正在加载文档)、complete(已经加载完文档) |
document.compatMode |
两个值:BackCompat:标准兼容模式关闭、CSS1Compat:标准兼容模式开启 |
write()、writeln()、 open()、close() |
write()文本原样输出到屏幕、writeln()输出后加换行符、 open()清空内容并打开新文档、close()关闭当前文档,下次写是新文档 |
示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>DOM</title>
</head>
<body>
<script type="text/javascript">
console.log("标题" + document.title);
console.log("地址" + document.URL);
console.log("域名" + document.domain);
console.log("编码" + document.charset);
document.open
</script>
</body>
</html>
结果:
五、学习资料
深入理解JavaScript系列(1):编写高质量JavaScript代码的基本要点
深入理解JavaScript系列(3):全面解析Module模式
深入理解JavaScript系列(4):立即调用的函数表达式
深入理解JavaScript系列(6):S.O.L.I.D五大原则之单一职责SRP
深入理解JavaScript系列(7):S.O.L.I.D五大原则之开闭原则OCP
深入理解JavaScript系列(8):S.O.L.I.D五大原则之里氏替换原则LSP
深入理解JavaScript系列(9):根本没有“JSON对象”这回事!
深入理解JavaScript系列(10):JavaScript核心(晋级高手必读篇)
深入理解JavaScript系列(11):执行上下文(Execution Contexts)
深入理解JavaScript系列(12):变量对象(Variable Object)
深入理解JavaScript系列(13):This? Yes, this!
深入理解JavaScript系列(14):作用域链(Scope Chain)
深入理解JavaScript系列(15):函数(Functions)
深入理解JavaScript系列(16):闭包(Closures)
深入理解JavaScript系列(17):面向对象编程之一般理论
深入理解JavaScript系列(18):面向对象编程之ECMAScript实现
深入理解JavaScript系列(20):《你真懂JavaScript吗?》答案详解
深入理解JavaScript系列(21):S.O.L.I.D五大原则之接口隔离原则ISP
深入理解JavaScript系列(22):S.O.L.I.D五大原则之依赖倒置原则DIP
深入理解JavaScript系列(23):JavaScript与DOM(上)——也适用于新手
深入理解JavaScript系列(24):JavaScript与DOM(下)
深入理解JavaScript系列(25):设计模式之单例模式
深入理解JavaScript系列(26):设计模式之构造函数模式
深入理解JavaScript系列(27):设计模式之建造者模式
深入理解JavaScript系列(28):设计模式之工厂模式
深入理解JavaScript系列(29):设计模式之装饰者模式
深入理解JavaScript系列(30):设计模式之外观模式
深入理解JavaScript系列(31):设计模式之代理模式
深入理解JavaScript系列(32):设计模式之观察者模式
深入理解JavaScript系列(33):设计模式之策略模式
深入理解JavaScript系列(34):设计模式之命令模式
深入理解JavaScript系列(35):设计模式之迭代器模式
深入理解JavaScript系列(36):设计模式之中介者模式
深入理解JavaScript系列(37):设计模式之享元模式
深入理解JavaScript系列(38):设计模式之职责链模式
深入理解JavaScript系列(39):设计模式之适配器模式
深入理解JavaScript系列(40):设计模式之组合模式
深入理解JavaScript系列(41):设计模式之模板方法
深入理解JavaScript系列(42):设计模式之原型模式
深入理解JavaScript系列(43):设计模式之状态模式
深入理解JavaScript系列(44):设计模式之桥接模式
深入理解JavaScript系列(45):代码复用模式(避免篇)
深入理解JavaScript系列(46):代码复用模式(推荐篇)
深入理解JavaScript系列(47):对象创建模式(上篇)
深入理解JavaScript系列(48):对象创建模式(下篇)
深入理解JavaScript系列(49):Function模式(上篇)
深入理解JavaScript系列(50):Function模式(下篇)
六、作业
6.1)、尽量多的输出javascript中为false的情况
6.2)、尽量多的输出javascript中为undefined的情况
6.3)、用示例说明未定义全局变量,特别是没有使用var关键字时
6.4)、请定对照“数组”一节的内容,练习数组定义与每一个已列出的数组方法
6.5)、请使用纯JavaScript(不允许使用任何三方库,如jQuery)完成下列功能:
要求:
- 全选、反选、子项全部选项时父项被选择
- 完成所有功能
- 鼠标移动到每一行上时高亮显示(js)
- 尽量使用弹出窗口完成增加、修改、详细功能
- 删除时提示
- 使用正则验证
- 封装代码,最终运行的代码只有一个对象,只对外暴露一个对象
- 越漂亮越好
6.6)、请写出以下两个正则表达式并使用两个文本框模拟用户提交数据时验证:
//身份证
//411081199004235955 41108119900423595x 41108119900423595X
//邮箱
//zhangguo123@qq.com zhangguo@sina.com.cn
6.7)、请写一个javascript方法getQuery(key)用于根据key获得url中的参值,如果不指定参数则返回一个数组返回所有参数,如:
url: http://127.0.0.1?id=1&name=tom
getQuery("id") 返回 1
getQuery() 返回[{key:id,value:1},{key:name,value:tom}] //思考一个如果有多个想同的key时怎样处理
翻转任务:
6.8、请完成一个TaskList(任务列表)
1、使用DOM+数组完成上述功能
2、列表、添加、修改、删除、多删除
3、状态切换
4、不使用jQuery
5、不需要后台,全选,反选,子项联动父项
6、任务只能是2-20位的合法字符,中文,英文,数字
七、示例下载
https://git.coding.net/zhangguo5/javascript_01.git
https://git.dev.tencent.com/zhangguo5/javascriptpro.git
八、视频
http://www.bilibili.com/video/av17173253/
参考与引用 :http://www.w3school.com.cn/
JavaScript学习总结(一)——ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)的更多相关文章
- JavaScript学习总结(一)DOM文档对象模型
一.文档(D) 一个网页运行在浏览器中,他就是一个文档对象. 二.对象(O) "对象"是一种自足的数据集合.与某个特定对象相关联的变量被称为这个对象的属性,只能通过某个对象调用的函 ...
- 【转】了解nodejs、javascript间的关系!bom&dom&ecmascript
地址:https://www.cnblogs.com/JetpropelledSnake/p/9450810.html bom&dom:https://www.cnblogs.com/wang ...
- JavaScript学习06(操作BOM和表单)
操作BOM window 所有浏览器都支持 window 对象.它代表浏览器的窗口. 所有全局 JavaScript 对象,函数和变量自动成为 window 对象的成员. 全局变量是 window 对 ...
- 高性能javascript学习总结(2)--DOM编程
我们知道,对DOM的操作都是非常的耗性能的,那么为什么会耗性能呢? 文档对象模型(DOM)是一个独立于语言的,使用 XML和 HTML 文档操作的应用程序接口(API).在浏览器中,主要与 ...
- JavaScript学习笔记 - 进阶篇(7)- 浏览器对象
window对象 window对象是BOM的核心,window对象指当前的浏览器窗口. window对象方法: 注意:在JavaScript基础篇中,已讲解了部分属性,window对象重点讲解计时器. ...
- JavaScript学习笔记(四)——DOM
第五章 网页交互——文本对象模型[Document object model] 1 简单介绍DOM,dom是将html与javascript进行交互的工具. [使用innerHTML时注意:html中 ...
- JavaScript学习——BOM对象
1.BOM 对象:浏览器对象模型(操作与浏览器相关的内容) 2.Window 对象 Window 对象表示浏览器中打开的窗口 setInterval():它有一个返回值,主要是提供给 clearInt ...
- Javascript学习笔记1 javascript的特点
..对于网页而言,Javascript无处不在,对于英语不好的人它简直是噩梦般的存在,但形式所逼,今天开始着手学习!希望自己能坚持下去.从什么地方着手,我的目标是从大处着眼,从应用着眼,不抠细节,反正 ...
- JavaScript 基础第七天(DOM的开始)
一.引言 JavaScript的内容分为三个部分,这三个部分分别是ECMAScript.DOM.BOM三个部分组成.所谓ECMAScript就是JavaScript和核心基础语法,DOM是文档对象模型 ...
随机推荐
- .2-Vue源码起步(2)
接着第一节开始继续吧(GoGoGo) 上一节把mergeOptions函数弄完了,最后返回一个options赋给了vm.$options. 这一节继续跑代码: function initMixin(V ...
- 使用OpenCV训练Haar like+Adaboost分类器的常见问题
<FAQ:OpenCV Haartraining>——使用OpenCV训练Haar like+Adaboost分类器的常见问题 最近使用OpenCV训练Haar like+Adaboost ...
- 初探 ELK - 每天5分钟玩转 Docker 容器技术(89)
在开源的日志管理方案中,最出名的莫过于 ELK 了.ELK 是三个软件的合称:Elasticsearch.Logstash.Kibana. Elasticsearch一个近乎实时查询的全文搜索引擎.E ...
- Travel
Travel Time Limit: 10000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submi ...
- zabbix 2.2.20 安装详解(Centos6.9)
环境说明 [root@centos ~]# cat /etc/redhat-release CentOS release 6.9 (Final) [root@centos ~]# uname -a L ...
- Azkaban 2.5.0 搭建和一些小问题
安装环境: 系统环境: ubuntu-12.04.2-server-amd64 安装目录: /usr/local/ae/ankaban JDK 安装目录: export JAVA_HOME=/usr/ ...
- 0_Simple__simpleCallback
学习回调函数的基本概念,并在CUDA的任务流中插入基于CPU的主机函数,作为回调函数使用. ▶ 源代码:没有用到的部分被注释起来了 /*multithreading.h*/ #ifndef MULTI ...
- 算法:javascript截取字符串
题目: Given a string, find the length of the longest substring without repeating characters. Examples: ...
- 实现基于Keepalived高可用集群网站架构的多种方法
实现基于Keepalived高可用集群网站架构 随着业务的发展,网站的访问量越来越大,网站访问量已经从原来的1000QPS,变为3000QPS,目前业务已经通过集群LVS架构可做到随时拓展,后端节点已 ...
- 关于帧动画steps属性的理解
CSS3的Animation有八个属性 animation-name animation-duration animation-delay animation-iteration-count anim ...