JavaScript简史
DOM
可以给文档增加交互能力。
ECMAScript
对javascript进行了标准化。
JavaScript
为了蹭当时红极一时的Java的流量故而叫做javascript。
DOM
是文档对象模型,它是一种API,程序和脚本可以通过这个接口动态地访问和修改文档的内容、结构和样式。
JavaScript语法
使用js的两种方式
- 将js代码放入
<head>
标签中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script> </script> </head> <body> </body> </html>
|
- 将js代码放入一个单独的js文件中,在html中用
<script>
标签引入。
1 2 3 4 5 6 7 8 9 10 11 12
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="js/main.js"></script> </head> <body> </body> </html>
|
- 将2中的
<script>
放入</body>
之前,以快速加载网页。
1 2 3 4 5 6 7 8 9 10 11 12 13
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <script src="js/main.js"></script> </body> </html>
|
<script>
标签中没必要写type="text/javascript"
属性
语法
注释
变量
赋值:mood = 'happy';
声明:var mood;
声明并赋值:var mood = 'happy';
一次声明并赋值多个变量:var mood = 'happy', age = 33;
变量名命名:字母、数字、美元符号、下划线,第一个字符不允许为数字,可以适当在变量名中间插入下划线一边阅读或者使用驼峰式。但是通常命名函数名、方法名、对象属性名用驼峰式。
js是弱类型语言
数据类型
- 字符串
- 数值
- 布尔值
- 数组
- 对象
条件语句
if语句
1 2 3 4 5 6 7
| if () { } else if () { } else { }
|
比较操作符
1 2 3 4 5 6 7 8 9
| > < >= <=
== === != !==
|
使用===
和!==
逻辑操作符
循环
while
do…while
至少执行一次
for
1 2 3
| for (var i = 0; i < 10; i++) { }
|
函数
调用
例子1:将两个数相乘并返回结果
1 2 3 4
| function multiply(num1,num2) { var total = num1 * num2; return total; }
|
例子2:华氏摄氏度转换
1 2 3 4 5
| function convertToCelsius(temp) { var result = temp -32; result = result /1.8; return result; }
|
命名变量名用下划线分割单词,命名函数用驼峰式
1 2 3 4
| var crew_name = 'wang'; function getCrewsInfo() { }
|
变量作用域
全局变量声明在js脚本中,作用域是整个js文件。
局部变量,也就是声明在函数内部,作用域就是这个函数内部。
1 2 3 4 5 6 7 8
| function square(num) { total = num * num; return total; } var total = 50; var number = square(20); alert(number);
|
需要用var声明局部变量:
1 2 3 4
| function square(num) { var total = num * num; return total; }
|
注意,函数内部变量一定要用var声明以避免二义性。
对象
对象是键值对
比如Person对象的属性和方法的调用:
1 2
| Person.age; Person.eat();
|
创建一个Person实例:
1 2 3
| var mason = new Person; mason.age; mason.mood;
|
内置对象,比如Array
对象
1 2
| var arr = new Array(5); arr.length;
|
还有宿主对象,比如浏览器提供的对象。
DOM
D:文档
O:对象
M:模型
文档中的每一个节点都是一个对象。
DOM就是将网页文档转化为一棵以<html>
为根的树。
DOM由节点构成,有些节点可以包含其他的节点,节点有三种:元素节点,文本节点,属性节点。
元素节点
可以包含其他节点。
文本节点
总是被元素节点包含。
属性节点
总是被元素节点包含。
例子:
1
| <p title="p_title">标题</p>
|
DOM:元素节点p里面包含了一个title属性子节点和一个“标题”文本子节点。
获取元素
getElementById
getElementsByTagName
取得文档所有元素节点:
1
| var nodes = getElementsByTagName('*');
|
以上的DOM方法还可以在任意一个节点对象上调用:
1 2
| var temp1 = document.getElementById('header'); var temp2 = temp1.getElementsByTagName('div');
|
getElementsByClassName
获取带有多个类名的元素:
1
| document.getElementsByClassName('div p');
|
通过以上DOM方法取得节点后赋值给变量再进行其他操作。
获取设置属性
获取元素后可以获取其属性和设置其属性。
getAttribute
只能在元素节点上调用
1 2 3 4 5
| var temp = getElementById('header'); var t = temp.getAttribute('title'); if (t) { alert(t); }
|
setAttribute
1 2
| var temp = getElementById('header'); temp.setAttribute('title','这里是标题');
|
案例:javascript图片库
图库demo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>图片库</title> <style> body { padding: 0; margin: 0; } </style> <script> function showPic(whichpic) { var placeholder = document.getElementById('placeholder'); var source = whichpic.getAttribute('href'); placeholder.setAttribute('src',source); var text = whichpic.getAttribute('title'); var description = document.getElementById('description'); description.firstChild.nodeValue = text; } function countBodyChildren() { var body_element = document.getElementsByTagName('body')[0]; console.log(body_element.childNodes.length); } window.onload = countBodyChildren; </script> </head>
<body> <h1>snapshots</h1> <ol> <li><a title="title1" href="img/1.jpg" onclick="showPic(this);return false;">img 1</a></li> <li><a title="title2" href="img/2.jpg" onclick="showPic(this);return false;">img 2</a></li> <li><a title="title3" href="img/3.jpg" onclick="showPic(this);return false;">img 3</a></li> <li><a title="title4" href="img/4.jpg" onclick="showPic(this);return false;">img 4</a></li> </ol> <img id="placeholder" src="img/placeholder.jpg" alt="" height="666px"> <p id="description">标题</p> </body>
</html>
|
nodeType
元素节点的nodeType为1
属性节点的nodeType为2
文本节点的nodeType为3
这里发现了vscode的go live插件不能正确显示改变后的title,垃圾
最佳实践
平稳退化
1
| window.open(url,name,features);
|
1
| window.open('https://www.baidu.com','baidu','width: 400,height: 150');
|
伪协议
1 2 3
| function pop(website){ window.open(website,'baidu','width: 400,height: 150'); }
|
1
| <a href="javascript:pop('https://baidu.com');">link</a>
|
尽量不用伪协议调用js代码。
window.onload = func;
向后兼容
对象检测:
1 2 3
| if (document.getElementById) { }
|
兼容:
1 2 3 4
| window.onload = function() { if (!document.getElementById) return false; }
|
性能考虑
- 尽量少访问DOM,尽量减少标记
- 合并脚本,并放在
</body>
之前
- 压缩脚本
案例:图片库改进版
1 2 3
| window.onload = function() { }
|
1 2 3 4 5 6 7 8 9 10 11
| function addloadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { oldonload(); func(); } } }
|
现在再添加函数只需要:addloadEvent(firstFunc)
onkeypress
动态创建标记
传统技术:document.write
innerHTML
DOM方法:createElement
createTextNode
appendChild
insertBefore
document.body
parentNode
firstChild
lastChild
insertBefore
nextSibling
编写insertAfter
函数:
1 2 3 4 5 6 7 8
| function insertAfter(newElement,targetElement) { var parent = targetElement.parentNode; if (parent.lastChild == targetElement) { parent.appendChild(newElement); } else { parent.insertBefore(newElement,targetElement.nextSibling); } }
|
Ajax
局部更新页面而不同刷新
XMLHttpRequest对象
创建对象:
ie:
1
| var request = new ActiveXObject('Msxml2.XMLHTTP.3.0');
|
其他浏览器:
1
| var request = new XMLHttpRequest();
|
编写getHTTPObject.js文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| function getHTTPObject() { if (typeof XMLHttpRequest == 'undefined') XMLHttpRequest = function () { try {return new ActiveXObject("Msxml2.XMLHTTP.6.0");} catch (e) {} try {return new ActiveXObject("Msxml2.XMLHTTP.3.0");} catch (e) {} try {return new ActiveXObject("Msxml2.XMLHTTP");} catch (e) {} return false; } return new XMLHttpRequest(); }
|
var request = new getHTTPObject();
返回一个XMLHttpRequest对象。
XMLHttpRequest对象的方法:
open
GET
,POST
,SEND
是否异步
编写getNewContent.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| function getNewContent() { var request = getHTTPObject(); if (request) { request.open('GET','example.txt',true); request.onreadystatechange = function() { if (request.readyState == 4) { var para = document.createElement('p'); var txt = document.createTextNode(request.responseText); para.appendChild(txt); document.getElementById('new').appendChild(para); } }; request.send(null); } else { alert('sorry,your browser dont support XMLHttpRequest'); } } addLoadEvent(getNewContent);
|
充实文档的内容
CSS-DOM
element.style
是一个对象
element.style.property
引用节点属性,如果属性名是用连字符的则改写为驼峰式。
但是以上只能返回行内样式,不能用来操作外部样式。
通过用DOM去修改元素的className
来达到切换样式的目的。
1
| element.className = value;
|
addClass
函数:
1 2 3 4 5 6 7 8
| function addClass(element,value) { if (!element.className) { element.className = value; } else { newClassName = element.className + ' ' + value; element.className = newClassName; } }
|
用js实现动画效果
var variable = setTimeout(func,delay);
clearTimeout(variable);
parseInt()
parseFloat()
html5
canvas
<video>
controls
addEventListener
综合示例
js库
jQuery
prototype
etc
常用代码
addClass
addClass()
用于为节点对象添加新类名。
参数:元素节点,新类名。
1 2 3 4 5 6 7 8 9 10
| function addClass(element,value) { if (!element.className) { element.className = value; } else { newClassName = element.className; newClassName += ' '; newClassName += value; element.className = newClassName; } }
|
insertAfter
insertAfter()
用于将新节点插到目标节点后面。
参数:新节点,目标节点。
1 2 3 4 5 6 7 8
| function insertAfter(newElement,targetElement) { var parent = targetElement.parentNode; if (parent.lastChild == targetElement) { parent.appendChild(newElement); } else { parent.insertBefore(newElement,targetElement.nextSibling); } }
|
addLoadEvent
用于添加页面onload后立刻执行的函数。
参数为需要立刻执行的函数。
1 2 3 4 5 6 7 8 9 10 11
| function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { oldonload(); func(); } } }
|
调用: