前端之JavaScript
前端三大块
- HTML:页面结构
- CSS:页面表现:元素大小、颜色、位置、隐藏或显示、部分动画效果
- JavaScript:页面行为:部分动画效果、页面与用户的交互、页面功能
1. JS概述
- JavaScript,浏览器内置了JavaScript语言的解释器
- JavaScript代码在浏览器上就可以运行
- DOM,(Document Object Model)文档对象模型
- 通过它可以操作HTML文档的相关功能,例如:对标签内容进行删除和替换等
- BOM,(Browser Object Model)浏览器对象模型
- 通过它可以操作浏览器相关的功能,例如:浏览器设置定时器,浏览器定时刷新页面
JavaScript是编程语言,DOM 和 BOM 是两个模块,利用JavaScript语言再结合DOM、BOM模块可以让我们的页面出现动态的效果。
2. JavaScript
2.1 js代码的存在形式
1)Script代码块,只能在当前页面使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JS学习</title> <script type="text/javascript"> // 内部编写JavaScript代码 </script> </head> <body> </body> </html>
2)独立js文件,可以被引入之后使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JS学习</title> <script type="text/javascript" src="JavaScript文件路径"></script> </head> <body> </body> </html>
3)推荐的位置
- 推荐把js代码都放在body标签的底部
- 因为JS放在下面可以让用户快速看到页面上的 HTML和CSS效果,但JS的效果必须还要等耗时操作处理完才能用
2.2 变量&注释
1)变量
- JavaScript 是一种弱类型语言,javascript的变量类型由它的值来决定
- 局部变量必须一个 var 开头,如果未使用 var,则默认表示声明的是全局变量
<script type="text/javascript"> // 全局变量 name = 'hgzero'; function func(){ // 局部变量 var age = 21; // 全局变量 gender = "男" } //同时定义多个变量可以用","隔开,公用一个‘var’关键字 var c = 45,d='qwe',f='68'; func(); console.log(gender); // 男 console.log(name); // hgzero console.log(age); // 报错:age是fun的局部变量,外部无法获取 </script>
2)注释
一条javascript语句应该以“;”结尾
- js中单行注释用
//
- 多行注释用
/* */
<script type="text/javascript"> // 单行注释 var a = 123; /* 多行注释 1、... 2、... */ var b = 'str'; </script>
2.3 数据类型——数字(Number)
1)JavaScript中的数据类型
- 5种基本数据类型:
- number、string、boolean、undefined、null
- 1种复合类型:
- object
2)数据类型(Number)
- JavaScript中不区分整数值和浮点数值,JavaScript中所有数字均用浮点数值表示
- 可以用 typeof(“xx”) 查看数据类型
// 声明 var page = 111; var age = Number(18); var a1 = 1,a2 = 2, a3 = 3;
// 转换 parseInt("1.2"); // 将某值转换成数字,不成功则NaN parseFloat("1.2"); // 将某值转换成浮点数,不成功则NaN
/* NaN,非数字。可使用 isNaN(num) 来判断。 Infinity,无穷大。可使用 isFinite(num) 来判断。 */
2.4 数据类型——字符串(String)
1)字符串的声明
// 声明 var name = "hgzero"; var name = String("hgzero"); var age_str = String(21);
2)字符串常用方法
// 常用方法 var name = "hgzero"; var value = names[0] // 索引 var value = name.length // 获取字符串长度 var value = name.trim() // 去除空白 var value = name.charAt(index) // 根据索引获取字符 var value = name.substring(start,end) // 根据索引获取子序列 var value = name.split('') // 把一个字符串分隔成字符串组成的数组
parseInt() // 将数字字符串转化为整数
parseFloat() // 将数字字符串转化为小数
toUpperCase() // 字符串转大写
toLowerCase() // 字符串转小写
// 字符串的反转 var str = 'asdfj12jlsdkf098'; var str2 = str.split('').reverse().join(''); alert(str2);
3)示例:标题跑马灯
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>真人比例充气xxx</title> </head> <body> <h1>HTML标签和样式</h1> <script type="text/javascript"> setInterval(function () { // 从HTML文档的title标签中获取标题文字 var title = document.title; var lastChar = title.charAt(title.length - 1); var preString = title.substring(0, title.length - 1); var newTitle = lastChar + preString; // 新字符串赋值到HTML文档的title标签中。 document.title = newTitle; }, 1000); </script> </body> </html>
2.5 数据类型——布尔类型(Boolean)
- 布尔类型仅包含真假
- 其首字母小写
var status = true; var status = false; /* 在js中进行比较时,需要注意: == 比较值相等 != 不等于 === 比较值和类型相等 !=== 不等于 || 或 && 且 */
2.6 数据类型——数组(Array)
1)数组的声明
// 声明 var names = ['hgzero', 'zero', 'stu'] var names = Array('hgzero', 'zero', 'stu')
2)数组的常用方法
// 常见方法 var names = ['hgzero', 'zero', 'stu'] names[0] // 索引 name.length // 获取数组的长度 name.indexOf("zero") // 返回数组中第一次出现的索引 names.push(ele) // 尾部追加元素 var ele = names.obj.pop() // 尾部移除一个元素 names.unshift(ele) // 头部插入元素 var ele = obj.shift() // 头部移除一个元素 names.splice(index,0,ele) // 在指定索引位置插入元素 names.splice(index,1,ele) // 指定索引位置替换元素 names.splice(index,1) // 指定位置删除元素 names.slice(start,end) // 切片 names.reverse() // 原数组反转 names.join(sep) // 将数组元素连接起来以构建一个字符串 names.concat(val,..) // 连接数组 names.sort() // 对原数组进行排序
2.7 数据类型——字典(对象Object)
1)字典的使用
- JavaScript中其实没有字典类型,字典是通过对象object构造出来的
// 声明 info = { name:'hgzero', "age":18 }
// 常用方法 var val = info['name'] // 获取 info['age'] = 20 // 修改 info['gender'] = 'male' // 新增 delete info['age'] // 删除
2)示例:动态表格
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>JavaScript学习</title> <style> table{ /*边框合并*/ border-collapse: collapse; } table th,table td{ border: 1px solid #ddd; padding: 8px; } table th{ font-weight: bold; } </style> </head> <body> <table> <thead> <tr> <th>学号</th> <th>姓名</th> <th>性别</th> </tr> </thead> <tbody id="body"> </tbody> </table> <script type="text/javascript"> var userList = [ {id:1,name:'hgzero',gender:'男'}, {id:2,name:'吴老板',gender:'男'}, {id:3,name:'肖老板',gender:'男'} ]; // 笨方法 for(var i in userList){ var row = userList[i]; var trNode = document.createElement('tr'); var tdNodeId = document.createElement('td'); tdNodeId.innerText = row.id; trNode.appendChild(tdNodeId); var tdNodeName = document.createElement('td'); tdNodeName.innerText = row.name; trNode.appendChild(tdNodeName); var tdNodeGender = document.createElement('td'); tdNodeGender.innerText = row.gender; trNode.appendChild(tdNodeGender); var bodyNode = document.getElementById('body'); bodyNode.appendChild(trNode); } // 简便方法 /* for(var i in userList){ var row = userList[i]; var trNode = document.createElement('tr'); for(var key in row){ var tdNode = document.createElement('td'); tdNode.innerText = row[key]; trNode.appendChild(tdNode); } var bodyNode = document.getElementById('body'); bodyNode.appendChild(trNode); } */ </script> </body> </html>
2.8 数据类型(null,undefine)
- null是JavaScript语言的关键字,它表示一个特殊值,常用来描述“空值”,相当于Python的None
- undefined是一个特殊值,表示只是声明而变量未定义
- Undedfine类型只有一个值,即 undefine
- 当声明的变量未初始时,该变量的默认值为 undefine
- 当函数无明确返回值时,返回的也是值 undefine
var name; console.log(typeof(name));
2.9 条件判断
1)if,else 用于判断
var age = 18; if(age <18){ }else if(age>=18 and 1 == 1){ }else if(age>=30){ }else{ }
2)switch,case 用户判断等于某些值
var num = 18; switch(num){ case 10: console.log('未成年'); break; case 18: console.log('成年'); break; case 35: console.log('油腻老男人'); break; case 100: console.log('....'); break; default: console.log('太大了'); }
2.10 循环语句
JavaScript中循环有两种写法:
for(var i in ['stu1','stu2','stu3'])
- 默认生成索引,适用于:字符串、元组、字典。
for(var i=0;i<10;i++)
- 自定义索引并设置增加步长,适用于:字符串、元组。
- 字典索引非有序
// 第一种方式 var names = ['stu1', 'stu2', 'stu3'] for(var index in names){ console.log(index, names[index]) } // 第二种方式 var names = ['stu1', 'stu2', 'stu3'] for(var i=0;i<names.lenght;i++){ console.log(i, names[i]) }
2.11 异常处理
在JavaScript的异常处理中有两个注意事项:
- 主动抛异常 throw “xx” 或 throw Error({code:1000,error:’错了’})
- catch只能捕获一次,如果想要对异常精细化处理可以在catch代码块中再做类型判断。
try { //这段代码从上往下运行,其中任何一个语句抛出异常该代码块就结束运行 var name = '' } catch (e) { // 如果try代码块中抛出了异常,catch代码块中的代码就会被执行 // e是一个局部变量,用来指向Error对象或者其他抛出的对象 } finally { // 无论try中代码是否有异常抛出(甚至是try代码块中有return语句),finally代码块中始终会被执行。 }
2.12 函数
1)变量与函数的预解析
- JavaScript解析过程分为两个阶段,先是编译阶段,然后执行阶段,在编译阶段会将function定义的函数提前,并且将var定义的变量声明提前,将它赋值为undefined
2)函数类型
// 1.普通函数 function func(arg){ return arg + 1; } // 2.匿名函数 // 定义的函数可以不给名称,这个叫做匿名函数 // 可以将匿名函数直接赋值给元素绑定的事件来完成匿名函数的调用 <script type="text/javascript"> window.onload = function(){ var oBtn = document.getElementById('btn1'); /* oBtn.onclick = myalert; function myalert(){ alert('ok!'); } */ // 直接将匿名函数赋值给绑定的事件 oBtn.onclick = function (){ alert('ok!'); } } </script> // 3.自执行函数 (function(arg){ console.log(arg); })('hgzero')
3)函数return关键字
- 函数return关键字的作用:
- 返回函数执行的结果
- 结束函数的运行
- 阻止默认行为
<script type="text/javascript"> function add(a,b){ var c = a + b; return c; alert('here!'); } var d = add(3,4); alert(d); //弹出7 </script>
2.13 json序列化
- json序列化功能,即:将对象和字符串之间进行转换
- 网络中数据传输本质上是基于字符串进行,如果想要把一个js的对象通过网络发送到某个网站,就需要对对象进行序列化然后发送
1)JSON.stringify(object) ,序列化
var info = {name:'alex',age:19,girls:['钢弹','铁锤']} var infoStr = JSON.stringify(info) console.log(infoStr) # 输出结果为: '{"name":"alex","age":19,"girls":["钢弹","铁锤"]}'
2)JSON.parse(str),反序列化
var infoStr = '{"name":"alex","age":19,"girls":["钢弹","铁锤"]}' var info = JSON.parse(infoStr) console.log(info)
3. DOM
- 文档对象模型(Document Object Model,DOM)是一种用于HTML编程接口
- DOM相当于是一个模块,提供了关于HTML文档中对标签进行操作的功能,JavaScript结合DOM可以对HTML中的标签进行操作
3.1 节点自身属性
console.log(ele.nodeName); // 节点名称 console.log(ele.nodeType); // 节点类型 console.log(ele.nodeValue); // 节点值 console.log(ele.innerHTML); // 节点中的文本,包括标签 console.log(ele.innerText); // 只获取节点中的文本信息
3.2 查找节点
1)直接查找
document.getElementById(arg) // 根据ID获取一个标签对象 document.getElementsByClassName(arg) // 根据class属性获取标签对象集合 document.getElementsByName(arg) // 根据name属性值获取标签对象集合 document.getElementsByTagName(arg) // 根据标签名获取标签对象集合
2)间接查找
var tag = document.getElementById(arg); tag.parentElement // 找当前标签对象的父标签对象 tag.children // 找当前标签对象的所有子标签对象 tag.firstElementChild // 找当前标签对象的第一个子标签对象 tag.lastElementChild // 找当前标签对象最后一个子标签对象 tag.nextElementtSibling // 找当前标签对象下一个兄弟标签对象 tag.previousElementSibling // 找当前标签对象上一个兄弟标签对象
3.3 操作元素属性
1)属性写法
- html的属性和js里面属性写法一样
- “class” 属性写成 “className”
- “style” 属性里面的属性,有横杠的改成驼峰式,比如:“font-size”,改成”style.fontSize”
2)操作属性的方法
- “.” 操作,缺点:无法引入变量
<script type="text/javascript"> window.onload = function(){ var oInput = document.getElementById('input1'); var oA = document.getElementById('link1'); // 读取属性值 var val = oInput.value; var typ = oInput.type; var nam = oInput.name; var links = oA.href; // 写(设置)属性 oA.style.color = 'red'; oA.style.fontSize = val; } </script> ... <input type="text" name="setsize" id="input1" value="20px"> <a href="http://cnblogs.com/hgzero" id="link1">Pray</a>
- “[ ]”操作,优点:可以引入变量
<script type="text/javascript"> window.onload = function(){ var oInput1 = document.getElementById('input1'); var oInput2 = document.getElementById('input2'); var oA = document.getElementById('link1'); // 读取属性 var val1 = oInput1.value; var val2 = oInput2.value; // 写(设置)属性 // oA.style.val1 = val2; 没反应,因为点 . 方式无法引入变量 oA.style[val1] = val2; } </script> ... <input type="text" name="setattr" id="input1" value="fontSize"> <input type="text" name="setnum" id="input2" value="30px"> <a href="http://cnblogs.com/hgzero" id="link1">Pray</a>
3.4 文本操作
对标签内部文本进行操作时,可以通过 innerText 和 innerHTML来进行:
- innerText
标签对象.innerText
,读取标签内容(仅文本)。标签对象.innerText="wu"
,修改标签内容(仅文本)。
- innerHTML
标签对象.innerHTML
,读取标签内容(含标签)。标签对象.innerHTML="<a href='#'>wu</a>"
,修改标签内容(标签、和文本)
3.5 class属性操作
DOM中主要提供了三个帮助操作class属性值的功能:
标签对象.className
- class属性对应的值直接操作
标签对象.classList.remove(cls)
- class属性对应值删除某个样式
标签对象.classList.add(cls)
- class属性中添加样式
3.6 事件
DOM中可以为标签设置事件,给指定标签绑定事件之后,只要对应事件被触发,就会执行对应代码
常见的事件:
onclick
,单击时触发事件ondblclick
,双击触发事件onchange
,内容修改时触发事件onfocus
,获取焦点时触发事件onblur
,失去焦点触发事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script> window.onload = function () { // 这里的window.onload代表等页面全部加载完毕后才加载这里的函数 var ele = document.getElementsByClassName("div1")[0]; console.log(ele.innerHTML); } </script> </head> <body> <body onload="f1()"> <!-- 这样也可以等页面全部加载完毕后再执行这里的f函数 --> <input type="text" id="search" value="请输入用户名" onfocus="f1()" onblur="f2()"> <!-- 获取焦点和失去焦点 --> <script> var ele = document.getElementById("search"); function f1() { if(ele.value=="请输入用户名"){ ele.value=""; } } function f2() { if(!ele.value.trim()){ ele.value = "请输入用户名"; } var ele = document.getElementById("p1"); ele.onclick = function () { alert(123); } } // 注意:JavaScript中的this代指的是标签本身, 如 onclick = func(this) ,将这个点击事件的标签本身传入到函数中 </script> </body> </html>
3.7 DOM节点的增删改查
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .div1,.div2,.div3,.div4{ width: 300px; height: 250px; } .div1{ background-color: green; } .div2{ background-color: red; } .div3{ background-color: yellow; } .div4{ background-color: blue; } </style> </head> <body> <div class="div1"> <button onclick="add()">add</button> hello div1 </div> <div class="div2"> <button onclick="del()">del</button> hello div2 </div> <div class="div3"> <button onclick="change()">change</button> <p>hello div3</p> </div> <div class="div4">hello div4</div> <script> function add() { var ele = document.createElement("p"); // 创建一个p标签 ele.innerHTML="hello p"; var father=document.getElementsByClassName("div1"); father.appendChild(ele); } function del() { var father = document.getElementsByClassName("div1")[0]; var sons = father.getElementsByTagName("p")[0]; father.removeChild(sons); // 删除一个子标签(是通过父节点来调用的) } function change() { var img = document.createElement("img"); // 创建一个img标签 img.setAttribute("src" , "image.jpg"); // 这是DOM下的语法,设置src为image.jpg,同下 img.src = "image.jpg"; // 设置这个img标签的路径 var ele = document.getElementsByTagName("p")[0]; // 找到div3中的p标签 ele.style.color = "red"; // js来改变css参数 var father = document.getElementsByClassName("div3")[0]; father.replaceChild(img, ele); // 将ele替换成img } var ele = document.getElementsByName("div")[0]; console.log(ele.className); console.log(ele.classList[0]); // 取出ele节点的class名字的列表 console.log(ele.className[1]); console.log(ele.className); </script> </body> </html>
4. BOM
- BOM(Browser Object Model)是指浏览器对象模型,通过它,可以操作浏览器相关的功能
- BOM相当于是一个模块,提供了关于浏览器操作的功能
4.1 提示框
alert
,提示框confirm
,确认框
<!DOCTYPE html> <html> <head> <meta charset='utf-8'/> <title>BOM</title> </head> <body> <input type="button" value="提示框" onclick="showAlert();"> <input type="button" value="确认框" onclick="showConfirm();"> <script type="text/javascript"> function showAlert() { alert('震惊了..'); } function showConfirm() { // 显示确认框 // result为true,意味着点击了确认 // result为false,意味着点击了取消 var result = confirm('请确认是否删除?'); console.log(result); } </script> </body> </html>
4.2 浏览器URL
location.href
- 获取当前浏览器URL
location.href = "url"
- 设置URL,即:重定向
location.reload()
- 重新加载,即:刷新页面
<!DOCTYPE html> <html> <head> <meta charset='utf-8'/> <title>BOM</title> </head> <body> <input type="button" value="获取当前URL" onclick="getUrl();"> <input type="button" value="重新加载页面" onclick="reloadPage();"> <input type="button" value="重定向到百度" onclick="redirectToBaidu();"> <script type="text/javascript"> function getUrl() { console.log(location.href); } function reloadPage() { location.reload(); } function redirectToBaidu() { location.href = "http://www.baidu.com"; } </script> </body> </html>
4.3 定时器
setInterval(function(){},1000)
- 创建多次定时器
clearInterval(定时器对象)
- 删除多次定时器
setTimeout(function(){},1000)
- 创建单次定时器
clearTimeout(定时器对象)
- 删除单次定时器
<!DOCTYPE html> <html> <head> <meta charset='utf-8'/> <title>BOM</title> </head> <body> <h1>计时器:<span id="time"></span></h1> <input type="button" value="开始计时" onclick="start();"> <input type="button" value="停止计时" onclick="stop();"> <script type="text/javascript"> var time; function start() { time = 0; document.getElementById('time').innerText = time; interval = setInterval(function () { time += 1; document.getElementById('time').innerText = time; }, 1000); } function stop() { clearInterval(interval) } </script> </body> </html>
5. 封闭函数&闭包
- 封闭函数是javascript中匿名函数的另外一种写法,创建一个一开始就执行而不用命名的函数
5.1 封闭函数的定义和执行
1)一般函数的定义和执行
function changecolor(){ var oDiv = document.getElementById('div1'); oDiv.style.color = 'red'; } changecolor();
2)封闭函数
(function(){ var oDiv = document.getElementById('div1'); oDiv.style.color = 'red'; })();
3)还可以在函数定义前加上“~”和“!”等符号来定义匿名函数
!function(){ var oDiv = document.getElementById('div1'); oDiv.style.color = 'red'; }()
5.2 什么是闭包
- 函数嵌套函数,内部函数可以引用外部函数的参数和变量,参数和变量不会被垃圾回收机制收回
function aaa(a){ var b = 5; function bbb(){ a++; b++; alert(a); alert(b); } return bbb; } var ccc = aaa(2); ccc(); ccc();
5.3 闭包的作用
1)将一个变量长期驻扎在内存当中,可用于循环中存索引值
<script type="text/javascript"> window.onload = function(){ var aLi = document.getElementsByTagName('li'); for(var i=0;i<aLi.length;i++) { (function(i){ aLi[i].onclick = function(){ alert(i); } })(i); } } </script> ...... <ul> <li>111</li> <li>222</li> <li>333</li> <li>444</li> <li>555</li> </ul>
2)私有变量计数器,外部无法访问,避免全局变量的污染
<script type="text/javascript"> window.onload = function(){ var aLi = document.getElementsByTagName('li'); for(var i=0;i<aLi.length;i++) { (function(i){ aLi[i].onclick = function(){ alert(i); } })(i); } } </script> ...... <ul> <li>111</li> <li>222</li> <li>333</li> <li>444</li> <li>555</li> </ul>
6. 面向对象
6.1 面向过程与面向对象编程
- 面向过程:
- 所有的工作都是现写现用
- 面向对象:
- 是一种编程思想,许多功能事先已经编写好了,在使用时,只需要关注功能的运用,而不需要这个功能的具体实现过程
6.2 JavaScript对象
- 将相关的变量和函数组合成一个整体,这个整体叫做对象,对象中的变量叫做属性,变量中的函数叫做方法
- javascript中的对象类似字典
6.3 创建对象的方法
1)单体
<script type="text/javascript"> var Tom = { name : 'tom', age : 18, showname : function(){ alert('我的名字叫'+this.name); }, showage : function(){ alert('我今年'+this.age+'岁'); } } </script>
2)工厂模式
<script type="text/javascript">
function Person(name,age,job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.showname = function(){ alert('我的名字叫'+this.name); }; o.showage = function(){ alert('我今年'+this.age+'岁'); }; o.showjob = function(){ alert('我的工作是'+this.job); }; return o; } var tom = Person('tom',18,'程序员'); tom.showname(); </script>
3)构造函数
<script type="text/javascript"> function Person(name,age,job){ this.name = name; this.age = age; this.job = job; this.showname = function(){ alert('我的名字叫'+this.name); }; this.showage = function(){ alert('我今年'+this.age+'岁'); }; this.showjob = function(){ alert('我的工作是'+this.job); }; } var tom = new Person('tom',18,'程序员'); var jack = new Person('jack',19,'销售'); alert(tom.showjob==jack.showjob); </script>
4)原型模式
<script type="text/javascript"> function Person(name,age,job){ this.name = name; this.age = age; this.job = job; } Person.prototype.showname = function(){ alert('我的名字叫'+this.name); }; Person.prototype.showage = function(){ alert('我今年'+this.age+'岁'); }; Person.prototype.showjob = function(){ alert('我的工作是'+this.job); }; var tom = new Person('tom',18,'程序员'); var jack = new Person('jack',19,'销售'); alert(tom.showjob==jack.showjob); </script>
5)继承
<script type="text/javascript"> function fclass(name,age){ this.name = name; this.age = age; } fclass.prototype.showname = function(){ alert(this.name); } fclass.prototype.showage = function(){ alert(this.age); } function sclass(name,age,job) { fclass.call(this,name,age); this.job = job; } sclass.prototype = new fclass(); sclass.prototype.showjob = function(){ alert(this.job); } var tom = new sclass('tom',19,'全栈工程师'); tom.showname(); tom.showage(); tom.showjob(); </script>