JavaScript
网页统分为三大部分:结构(HTML)、表现(CSS)和行为(JavaScript)。
JavaScript
JavaScript简介
JavaScript是解释型语言,有着类似C和Java的语法结构,动态语言,基于原型的面向对象。
一个完整的JavaScript实现应该由以下三个部分构成:ECMAScript、DOM、BOM。
代码的位置
在HTML中,JS代码可以编写在<script>中。
1 | <script type="text/javascript"> |
可以内联到<button>标签的onclick属性中。
1 | <button onclick="alert('Hello world!');">点我!</button> |
可以内联到<a>标签的href属性中。
1 | <a href="javascript:alert('Hello world!');">点我!</a> |
可以使用专门的js文件,然后引入。此时<script>标签内部的代码被忽略。
1 | <script src="./demo.js"></script> |
输出
弹出警告框。
1 | alert(); |
弹出带有文本框的提示框,函数返回用户输入的字符串。
1 | var input = prompt("请输入密码"); |
带有消息和确认取消按钮的提示框。
1 | var flag = confirm("确认提交?"); |
文档输出,向<body>中写入内容。
1 | document.write(); |
控制台输出。
1 | console.log(); |
JavaScript基本语法
字面量和变量
字面量都是不可改变的值,如1,2,"Hello"。
变量可以用来保存值。
1 | var hello = "Hello world!"; |
标识符由字母、数字、下划线、美元符组成;不能以数字开头;不能是关键字或保留字;一般使用小驼峰规则。变量名可以使用中文,但不要使用。
数据类型
数据类型指的是字面量的类型。
- String 字符串
- Number 数值
- Boolean 布尔值
- Null 空值
- Undefined 未定义
- Object 对象
Object是引用数据类型。
typeof用于查看类型。
字符串使用双引号或单引号,不能嵌套,可以使用\转义。Unicode使用\u转义。
所有数值,包括整数和浮点数都使用Number。
Number型的最大值Number.MAX_VALUE约为$1.79769\times 10^{308}$,超过后认为Infinity;最小值Number.MIN_VALUE约为$5\times10^{-324}$。
NaN表示不是数字,如字符串乘字符串。
十六进制以0x开头,八进制以0开头,二进制以0b开头(兼容性不好)。
布尔值只有true和false。
Undefined类型值只有undefined,表示未定义的变量。
Null类型值只有null,专门用来表示为空的对象,类型为Object。
类型转换
- 转换为String:
.toString()方法,不能转换null和undefined。String()函数,底层实现是检测和调用.toString()方法。+""加空串会转换为字符串。
- 转换为Number:
Number()函数- 若不能转换给出
NaN。 undefined转换为NaN。- 空串
""或空白串" ","\t"转换为0。 true转换为1,false转换为0。null转换为0。
- 若不能转换给出
parseInt()和parseFloat()转换字符串- 将有效字符串转换为Number,遇到非数字停止。
parseFloat()可以转换科学计数法。- 非有效返回
NaN。 - 其他数据类型先转换为String再转换,所以给出
NaN。 070这种字符串可能转换错误,可以使用parseInt("070",10)表示以十进制转换。
-0,*1,/1除了加号以外的算术运算符.+正号
- 转换为Boolean
Boolean()函数0和NaN为false,其余都为true。- 空串
""为false,其余都为true。 null和undefined为false,其余对象为true。!!
运算符
typeof是运算符,可以获取数据类型,返回字符串。+,-,*,/,%- 除了字符串拼接,非Number类型值会先转换为Number。
- 任何值和
NaN运算都是NaN。 - 两个字符串相加视为拼接。
- 任何值和字符串相加视为字符串拼接。
+正号,-负号- 对于非Number,先转换为Number。
++自增,--自减- 无论是前置
++和后置++,都会让变量立即自增,但返回的值不同。
- 无论是前置
&&与,||或,!非- 与和或均为短路运算。
- 非
Boolean会先转换为Boolean,但会返回短路时的原值:与运算如果第一个值为true返回第二个值,如果第一个值为false返回第一个值;或运算如果第一个值为false返回第二个值,如果第一个值为true返回第二个值。
=赋值,+=,-=,*=,/=,%=>,<,>=,<=- 除了字符串比较,非数值会先转换为数值。
- 任何值和
NaN比较总会得到false。 - 两个字符串比较会进行字符串比较,使用Unicode。
==,!=- 一般来讲会转换为Number进行相等比较。
null == 0 // falseundefined衍生自null,undefined == null //trueNaN的相等比较总会给出false。可以通过isNaN()判断是否为NaN。!=取值为==取反。
===全等,!==不全等- 全等和不全等不会做类型转换。
?:条件运算符,逗号运算符
运算符优先级
.,[],new()++,--!,~,+,-,typeof,void,delete%,*,/+,-<<,>>,>>><,<=,>,>===,!=,===&|&&||?:=,+=,-=,*=,/=,%=,<<=,>>=,>>>=,&=,^=,|=,
语句
1 | if(exp){ |
面向对象
- 内建对象由ES标准定义,如Math,String,Number,Boolean,Function,Object等。
- 宿主对象由JS的运行环境提供,如BOM,DOM等。console和document就是宿主对象。
- 自建对象由开发人员创建。
对象基本操作
对象通过new创建,对象属性用.创建,用delete删除。
1 | var obj = new Object();//创建对象 |
对象的属性的本质是键值对,键为字符串,可以用[]控制。
1 | //属性名可以用任意字符串,但特殊的字符串需要使用[],此时甚至可以传入变量 |
可以通过in运算符检查对象是否拥有指定的属性。
1 | if("age" in obj){ } |
可以使用foreach来枚举对象的全部属性。
1 | for(var n in obj){ |
对象是引用数据类型,==比较的是是否为同一对象。
当直接打印对象时,使用对象的toString()方法,定义在Object的原型之中,可以重写这个方法。
对象字面量
{}为对象字面量,可以在创建对象的同时添加属性,属性名可以加引号。
1 | var obj = {}; |
函数对象
函数也是对象,具有普通对象的功能,函数中可以封装代码,在需要时执行功能。
可以在构造函数时将代码以字符串的形式传递给构造函数。
1 | var fun = new Function("console.log('Hello world');"); |
一般使用函数声明来创建函数。
1 | function fun(){ |
也可以使用函数表达式创建函数。
1 | var fun = function(){ |
可以在函数中使用参数。调用时多余参数会被忽略,不足的参数为undefined。
1 | function sum(x,y){ |
可以立即执行声明的匿名函数。
1 | (function(){ alert("Hello world!";) })(); |
对象的属性也可以是函数,此时称为方法。
函数在调用时会传递this,即调用函数的对象还会传递arguments,即传递的参数,argument是一个伪数组。
arguments有一个属性callee,对应调用的函数。
对函数对象调用call()和apply()会调用函数,传入的参数将会作为this,但apply()要求将参数封装为数组。
1 | func.call(obj, arg...);//obj.func(arg...); |
作用域
JS中的作用域分为全局作用域和函数作用域。
全局作用域:
- 编写在
<script>中的变量拥有全局作用域,在页面打开时创建,在页面关闭时销毁。 - 在全局作用域中有一个全局对象
window,代表浏览器的窗口。全局作用域中的所有变量都作为window的属性储存,所有函数都作为window的方法储存。 var关键字声明的变量,会在所有的代码执行之前被声明。- 使用
function声明的函数,会在所有的代码执行之前被声明及定义。
函数作用域
- 调用函数时创建函数作用域,函数执行完毕后作用域销毁。
- 函数作用域中可以访问全局作用域。
- 函数作用域中的重名变量就近使用。
var关键字声明的变量,会在函数中所有的代码执行之前被声明。- 定义的形参相当于在函数作用域中定义的变量。
- 不用
var关键字声明的变量,都会是全局变量。 - 使用
function声明的函数,会在函数中所有的代码执行之前被声明及定义。
闭包
为了让函数外部可以访问函数作用域的变量,可以使用闭包。
1 | fuction f(){ |
构造函数
使用工厂方法来统一创建对象
1 | function createObj(name, age){ |
可以声明构造函数。调用构造函数时会立刻创建新的对象,将新建的对象设置为函数中的this,执行函数中的代码,并把对象作为返回值返回。使用同一个构造函数创建的对象称为同一类对象,将构造函数称为一个类。
1 | function Person(name, age){ |
instanceof运算符检查一个对象是否是一个类的实例。
1 | var steve = new Person("steve", 11); |
原型对象
每创建一个函数,解析器都会向函数添加一个属性prototype,这个属性对应着一个对象,称为原型对象。
如果函数作为普通函数调用,原型对象不起作用。当函数作为构造函数调用,他所创建的对象都有一个隐含属性指向原型对象,可以通过__proto__访问。
原型对象相当于公共区域,可以将对象所共有的内容统一设置到原型对象中,如类方法。当访问对象的属性或方法时,如果没有在自身范围内找到,则会在原型对象中寻找。
原型对象也是对象,原型对象也有原型对象,直到Object的原型对象。Object对象的原型对象没有原型对象,对应null。
1 | Person.prototype.sayName = function(){ |
使用in检查属性时,也会包括原型对象。可以使用hasOwnProperty()检查对象自身是否拥有该属性。
JSON
Javascript Object Notation用字符串表示一个对象。对象用{}表示,数组用[]表示。
JSON工具类用于转换JSON。(IE8+)
1 | var obj = JSON.parse(json); |
IE7解决案:
1 | var obj = eval("(" + str + ")"); |
不过还是引入一个JSON库比较好。
内建对象
Array
数组也是对象。使用数字索引作为属性名存储元素。数组的存储性能要比普通对象要好。typeof检查数组对象会给出object。
1 | var arr = new Array();//创建数组 |
数组方法
1 | arr.push(obj);//向数组末尾添加一个或多个元素,返回长度 |
数组遍历使用forEach(),需要传入回调函数,回调函数的三个参数分别代表当前元素、索引和数组。IE8及以下不支持。
1 | arr.forEach(function(value, index, array){ |
Date
1 | var d = new Date();//默认当前时间 |
Math
Math不是构造函数,不用创建对象,是一个工具类。属性为数学常量,方法为数学函数。
1 | Math.PI; |
包装类
可以将基本数据类型包装为对象,开发中不常用。浏览器会临时使用包装类处理基本数据类型调用的方法。
1 | var str = new String("Hello wrold!"); |
String
String类的底层实现是字符数组。
1 | var str = "Hello world"; |
正则表达式
匹配模式包括"i"和"g",指忽略大小写和全局匹配模式,可以多个匹配。
1 | var r = new RegExp("正则表达式","匹配模式"); |
基本语法
/a/含有a/ab/含有ab/a|b/含有a或b/[ab]/含有a或b/[a-z]/含有小写字母/[A-z]/含有任意字母/[0-9]/含有任意数字/a[bcd]z/含有abz或acz或adz/[^0-9]/含有非数字的字符
量词
/a{3}/含有aaa/ab{3}/含有abbb/(ab){3}/含有ababab/a{1,3}/含有a或aa或aaa/a{3,}/含有aaa或aaaa或aaaaa…/ab+c/含有abc或abbc或abbbc…/ab*c/含有ac或abc或abbc或abbbc…/ab?c/含有ac或abc
开头结尾
/^a/以a开头/a$/以a结尾/^a$/只匹配a
元字符
.除了换行和结束的任意字符\.匹配”.”\w任意字母、数字、下划线\W非字母、数字、下划线\d任意数字\D非数字\s空格\S非空格\b单词边界,如\bchild\b查找单词child\B非单词边界
例子
1 | var phoneReg = /^1[3-9][0-9]{9}$/; |
支持正则表达式的String类方法
1 | str.split(reg);//以正则表达式拆分字符串,默认全局匹配拆分 |
DOM
文档对象模型,文档指整个网页,网页中的所有元素都转换为对象。
节点
常用节点:
- 文档节点:整个HTML文档
- 元素节点:HTML标签
- 属性节点:元素属性
- 文本节点:标签中的文本内容
| nodeName | nodeType | nodeValue | |
|---|---|---|---|
| 文档节点 | #document | 9 | null |
| 元素节点 | 标签名 | 1 | null |
| 属性节点 | 属性名 | 2 | 属性值 |
| 文本节点 | #text | 3 | 文本内容 |
对象
1 | <button id="btn" class="butn">我是一个按钮</button> |
元素的属性可以直接用对象的属性获取,除了class需要使用className。
innerHTML获取内部HTML代码innerText获取内部文本
事件
响应函数
可以在HTML标签中使用事件。
1 | <button id="btn" onclick="alert('Ouch!');">我是一个按钮</button> |
应该在JS中处理事件,这时调用的回调函数称为响应函数。
1 | var btn = document.getElementById("btn"); |
响应函数需要在对象加载后再绑定,否则无法获取到对象。
冒泡
当后代的事件触发时,祖先的元素相同事件会依次触发,称为冒泡。可以用event.cancelBubble = true取消冒泡。
将事件绑定给元素的共同的祖先,这样当后代元素上的事件触发时会一直冒泡到祖先,称为事件的委派。
事件触发时,如果事件由内向外触发,称为事件冒泡,而事件从外向内的过程是捕获阶段。默认在捕获阶段不会触发事件,捕获结束后才开始触发冒泡。可以设置在捕获阶段就触发。
绑定响应函数
addEventListener()也可以绑定响应函数(IE9+)。事件以字符串传入,不需要”on”。第三个参数表示是否在捕获阶段触发事件。可以绑定多个事件,先绑定者先执行。IE8使用attachEvent(),后绑定者先执行,且函数中的this表示window。
1 | function bind(obj, eventStr, func){ |
事件对象
当事件的响应函数被触发时,浏览器会将事件对象传入响应函数(IE9+),事件对象中封装了事件的信息。事件对象也会作为window的event属性保存(火狐除外)。
1 | div.onmousemove = function(event){ |
事件
onload表示加载完成,响应函数会在页面加载完成后调用。1
2window.onload = function(){
}onsroll滚动条滚动。onmousewheel鼠标滚轮滚动。- 火狐不支持,需要用
addEventListener()加入DOMMouseScroll。 - 浏览器若有滚动条也会一起滚,要设置
return false。 addEventListener()绑定的事件无法用return false取消默认行为,可以用event.preventDefault()。- IE8不支持
event.preventDefault()。1
2obj.onmousewheel = func;
bind(obj, "DOMMouseScroll", obj.onmousewheel);
- 火狐不支持,需要用
onmousemove鼠标移动。onmousedown鼠标按下。- 浏览器会默认在搜索引擎中搜索内容,可以用
return false取消这一默认行为(IE9+)。 - 在IE8可以使用只有IE支持的
setCapture()。其将下一次的任意鼠标按下事件变为对自身的按下事件。releaseCapture()释放捕获。1
2obj.setCapture && obj.setCapture();
obj.releaseCapture && obj.releaseCapture();
- 浏览器会默认在搜索引擎中搜索内容,可以用
onmouseup鼠标松开。
1 | function drag(obj) {//构建一个可以拖拽元素的函数 |
onkeydown键盘按下。- 一般绑定给可以获取焦点的对象或document。
- 一直按会一直触发。
- 默认行为是给文本框中输入字符。
onkeyup键盘弹起。
在<a>的onclick事件中,如果返回false,则不会跳转。
event属性
button鼠标按下的键。clientX鼠标横坐标,相对于视口,下同。clientY鼠标纵坐标pageX鼠标横坐标,相对于页面,下同。(IE9+)pageY鼠标纵坐标target触发事件的节点wheelDelta鼠标滚轮方向,向上为正。火狐使用detail, 向上为负。alyKey是否按下Alt。ctrlKey是否按下Ctrl。shiftKey是否按下Shift。metaKey是否按下meta。keyCode按键的编码。
DOM查找方法
- 文档节点
getElementById()通过id获取一个元素节点对象getElementsByTagName()通过标签名获取一组对象getElementsByName()通过name属性获取一组对象getElementsByClassName()通过类名获取一组对象(IE9+)body<body>标签document<html>标签all所有元素getElementsByTagName("*")同上querySelector()根据CSS选择器查询一个元素节点对象(IE8+)querySelectorAll()根据CSS选择器查询一组元素节点对象(IE8+)
- 元素节点
getElementdByTagName()通过标签名获取后代节点childNodes所有子节点,包括文本节点。HTML中标签间的空白也被算在内(IE8及以下不算空白)children所有子元素firstChild第一个子节点firstElementChild第一个元素节点(IE9+)lastChild最后一个子节点parentNode父节点previousSibling前一个兄弟节点previousElementSibling前一个兄弟元素节点(IE9+)nextSibling后一个兄弟节点
DOM修改方法
appendChild()把新的子节点添加到指定节点removeChild()删除子节点replaceChild()替换子节点insertBefore()在指定子节点前插入子节点createElement()创建元素节点createTextNode()创建文本节点
1 | var nli = document.createElement("li"); |
DOM操作CSS
使用元素.style.样式。所有样式需要使用驼峰命名。这种修改和读取的是内联样式。
元素.currentStyle.样式,获取的是当前样式。只有IE支持,返回值可能是auto。
在其他浏览器(IE9+)中使用,总会返回具体数值:
1 | var style = getComputedStyle(obj, null);//第二个参数可传递伪元素 |
通用写法
1 | function getStyle(obj, name) |
clientHeight可见高度,不带px,包括内容区和内边距,下同。clientWidth可见宽度offsetHeight包括内容区,内边距和边框,下同。offsetHeightoffsetParent获取用于定位的父元素offsetLeft左偏移量offsetTop上偏移量scrollHeight滚动区域的完全高度。scrollWidth滚动区域的完全宽度。scrollTop滚动条的垂直位置。- 当
scrollTop == scrollHeight - clientHeight时滚动条就滚动到底部了。 - 火狐等浏览器认为页面的滚动条属于
<html>;旧版Chrome认为页面滚动条属于<body>。
- 当
scrollLeft滚动条的水平位置。
应该用切换类的方式切换CSS样式,使得行为与样式分离。
BOM
浏览器对象模型。
- window 浏览器窗口
- navigator 浏览器信息
- history 历史记录,只能向前和向后翻页
- location 地址栏
- screen 屏幕
所有其他对象都是window的属性。
Navigator
由于历史原因,navigator中大部分信息已经没用了。一般只用userAgent返回的字符串来判断浏览器信息。
IE11
- Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729; rv:11.0) like Gecko
IE10
- Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
IE8
- Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)
Chrome
- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36
Edge
- Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.18363
可以用浏览器特有对象来判断。
IE : window.ActiveXObject 但这个对象在IE11转布尔会返回false,所以要用"ActiveXObject" in window。
Histroy
length浏览器中保存的URL数量。back()回退。forward()前进。go()跳转到指定页面,正数向前跳,负数向后跳。
Lacation
直接打印location可以得到地址栏的完整页面。修改时会直接跳转,生成相应的历史记录。
assign()加载新的文档,跳转到新的页面。reload()重新加载当前页面,相当于F5。可传入true,强制清空浏览器缓存,相当于ctrl+F5。replace()使用新的页面替代本页面,不会生成历史记录。
Window定时器
setInterval(func, time)开启定时器,将函数每隔一段时间执行一次,单位毫秒。返回定时器的标志。clearInterval(n)关闭定时器,传入标志。setTimeout()延迟调用。clearTimeout()关闭延迟调用。
article_txt