- 网页特效原理
- JavaScript 就是修改样式(文档)
- 编写 JS 的流程
- 布局:HTML + CSS
- 属性:确定要修改的属性
- 事件: 确定用户 做哪些操作(产品设计)
- 编写 JS :在事件中,用 JS 来修改页面元素的样式
-
分析效果实现原理
- 样式:
div
的display / none
- 事件:
onmouseover / onmouseout
- 动手编写效果
- 样式:
-
特效基础
- 事件驱动:
onmouseover
- 元素属性操作:
obj.style.[...]
- 特效实现原理概括:响应式用户操作,对页面元素样式修改
- 事件驱动:
-
兼容性问题
// div2.style.display='block'; // 部分浏览器不兼容 document.getElementById('div2').style.display='block'; // 所有浏览器兼容
-
函数
- 制作更复杂的效果
- 直接在事件内写代码会很乱
- 引入
function()
函数的基本形式 - 把 JS 标签里放入到函数里,类似于 css 里的
class
- 变量的使用:别名
- 引入
- 定义和调用
- 函数定义:告诉系统有这个函数,不会执行
- 函数调用:执行函数里面的代码
- 关系和区别
-
代码
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>第一个JS效果</title> <style> #div2 { display: none; background: red; width: 100px; height: 50px; font-size: 16px; } #div1 { display: block; background: red; width: 100px; height: 100px; font-size: 16px; } </style> <script> // 封装 getElementById 函数 function get(id) { return document.getElementById(id); } // 显示 div2 function show() { // div2.style.display='block'; // 部分浏览器不兼容 get('div2').style.display='block'; } // 隐藏 div2 function hide() { // div2.style.display='none'; // 部分浏览器不兼容 get('div2').style.display='none'; } // div1 变绿 function toGreen() { get('div1').style.background='green'; } // div1 变蓝 function toblue() { get('div1').style.background='blue'; } // div1 变红 function toRed() { get('div1').style.background='red'; } // 点击循环变色 var i = 0; function changeColor() { console.log('i=',i) if (i == 0) { toGreen(); i++; console.log('i=',i) return; } if (i == 1) { toblue(); i++; console.log('i=',i) return; } if (i == 2) { toRed(); i = i - 2; console.log('i=',i) return; } } </script> </head> <body> <!-- 调用页内函数修改样式 --> <input type="button" onclick="changeColor()" value="按钮"> <div id="div1"> </div> <!-- 行内 JS 修改样式 --> <input type="checkbox" onmouseover="div2.style.display='block';" onmouseout="div2.style.display='none';" value="按钮"> <div id="div2"> <p>文字<br>文字2</p> </div> </body> </html>
-
网页换肤
- 土豆网 “开灯” “关灯效果”
- 任何标签都可以加 ID ,包括 link
- 任何标签的属性,都可以修改
- HTML 里面怎么写,JS 里面就怎么写
-
if 判断
- 特效实现原理
- if 基本形式
- JS 里面
= 赋值, == 判断
- 为 a 链接添加 JS
<a href="javascript:;"></a>
- className 的使用
class
是关键字,所以用className
代替- 其它 HTML 里面怎么写,JS 里面就怎么写
-
代码
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <link id="link1" rel="stylesheet" type="text/css" href="css/grey.css"> <script> function changeColor() { if (document.getElementById('b1').value == '关灯') { document.getElementById('link1').href = 'css/black.css'; document.getElementById('b1').value = '开灯'; console.log('black') } else { document.getElementById('link1').href = 'css/grey.css'; document.getElementById('b1').value = '关灯'; console.log('bl2:', document.getElementById('link1').href) } } function changeText() { document.getElementById('text1').value = '456'; document.getElementById('text1').title = '文字1'; } function showHide() { var div2 = document.getElementById('div2'); if(div2.style.display == 'block') { div2.style.display ='none'; console.log('1'); } else { div2.style.display = 'block'; div2.style.background = 'blue'; } console.log('display:', div2.style.display); } function class1() { var div = document.getElementById('div4'); div.className='div5'; div.id='div5'; } </script> </head> <body> <!-- 换肤 --> <input id="b1" type="button" onclick="changeColor()" value="关灯"> <div id="div1">1</div> <div id="div2">2</div> <div id="div3">3</div> <input type="button" value="显示隐藏div2" onclick="showHide()"> <br> <!-- HTMl 里面怎么写,JS 里面就怎么写 --> <input id="text1" type="text" value="123"> <input type="button" value="改文字" onclick="changeText()"> <br> <!-- a 链接的使用 --> <a href="javascript:;">javascript:;</a> <!-- className 的使用 --> <div id="div4">4</div> <input type="button" value="className" onclick="class1()"> </body> </html>
-
改变背景颜色
- 函数传参:参数就是占位符
- 函数里面变量用传参
- 函数传参:参数就是占位符
-
改变 div 的任意样式
- 操纵属性的第二种方式
- 要修改的属性不确定时:
元素.style[ 变量/字符串 ] = 变量/字符串
- JS 中用
.
的地方都可以用[]
代替; - 字符串变量区别和关系 :带引号是字符串,不带是变量
- 要修改的属性不确定时:
- 将属性名作为参数传递
- 操纵属性的第二种方式
-
style 与 className
元素.style.属性 = 变量/字符串
- style 是修改行内样式
- 行内样式优先级最高,之后再修改 className 不会有效果
- 建议:只操作一种样式,要么只操作 style ,要么只操作 className
-
代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>函数传参</title> <style> div { display: block; background: red; width: 100px; height: 100px; font-size: 16px; } .div2 { display: block; background: grey; width: 100px; height: 100px; } </style> <script> // 封装 getElementById 函数 function get(id) { return document.getElementById(id); } // div1 变绿 function toGreen() { get('div1').style.background='green'; } // div1 变蓝 function toblue() { get('div1').style.background='blue'; } // div1 变红 function toRed() { get('div1').style.background='red'; } // 点击循环变色 var i = 0; function changeColor() { console.log('i=',i) if (i == 0) { toGreen(); i++; console.log('i=',i) return; } if (i == 1) { toblue(); i++; console.log('i=',i) return; } if (i == 2) { toRed(); i = i - 2; console.log('i=',i) return; } } // 函数传参 function toColor(color, width) { get('div1').style.background = color; get('div1').style.width = width; } // 将属性名作为参数传递 function chgName(name, width) { // get('div1').style.name = width; // name 会被当作属性赋值 get('div1')['style'][name] = width; // 数组 可以加字符串或者变量 } // 样式优先级 function chgClass(className) { get('div1').className = className; } </script> </head> <body> <!-- 调用页内函数修改样式 --> <input type="button" onclick="changeColor()" value="循环"> <!-- 函数传参 --> <input type="button" onclick="toColor('green', '200px')" value="变绿"> <input type="button" onclick="toColor('blue', '300px')" value="变蓝"> <input type="button" onclick="toColor('red', '400px')" value="变红"> <input type="button" onclick="chgName('height', '200px')" value="变高"> <input type="button" onclick="chgClass('div2')" value="class变灰"> <div id="div1"></div> </body> </html>
- 提取事件
- 为元素添加事件
- 事件和其它属性一样,可以用 JS 添加:
元素.事件 = 函数名/函数;
- 不能加括号,加括号直接执行函数
window.onload
的意义:等待页面加载完成再执行 JS- 行为( js )、样式( css )、结构( html ) 三者分离
- 事件和其它属性一样,可以用 JS 添加:
- 为元素添加事件
- 获取一组元素
元素.getElementsByTagName('标签名')
- 数组的使用
- 数组的属性
- 全选的实现
- 代码: 同下
-
用 while 引入 循环的概念
- while 循环语法
- 自增的意义
- 循环的构成:初始化、条件、语句、自增
- while 循环语法
-
for 循环
- 用 for 代替 while 循环
- 用 for 循环为一组元素甜腻骄傲事件
- 什么时候用循环----一组元素
- 例子
- 全选---- checked 属性
- 反选---- for 循环配合 if 判断
- 用 for 代替 while 循环
-
代码:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>提取行间事件和循环</title> <style> div { display: block; border: 1px solid black; width: 100px; height: 100px; margin: 10px; float: left; } </style> <script> window.onload = function () { // 封装 getElementById 函数 function get(id) { return document.getElementById(id); } // 封装 getElementsByTagName function gets(tagName) { return document.getElementsByTagName(tagName) } // 提取行间样式 get('btn1').onclick = function () { get('btn1').value = '提取成功'; } // 修改一组元素中的某一个元素 get('btn2').onclick = function () { gets('div')[2].style.background = 'blue'; } // 修改一组元素- while 循环 get('btn3').onclick = function () { var i = 0; while ( i < gets('div').length ) { gets('div')[i].style.background = 'yellow'; i++; } } // for get('btn4').onclick = function () { for (var i = 0; i < gets('div').length; i++ ){ gets('div')[i].style.background = 'pink'; } } // 全选的实现 if 判断 无需div get('btn5').onclick = function () { for (var i = 0; i < gets('input').length; i++ ){ if (gets('input')[i].type == 'checkbox'){ if (gets('input')[i].checked == false) { gets('input')[i].checked = true; } else { gets('input')[i].checked = false; } } } } // 元素.getElementsByTagName 方法 单个div get('btn6').onclick = function () { var div2 = get('div2'); var inp = div2.getElementsByTagName('input'); for (var i = 0; i < inp.length; i++ ){ // console.log(inp); if (inp[i].checked == false) { inp[i].checked = true; } else { inp[i].checked = false; } } } // 元素.getElementsByTagName 方法 多个div get('btn7').onclick = function () { var div2 = gets('div'); for (var i = 0; i < div2.length; i++ ){ var div = gets('div')[i]; var inps = div.getElementsByTagName('input'); for (var a = 0; a < inps.length; a++){ if (inps[a].checked == false) { inps[a].checked = true; } else { inps[a].checked = false; } } } } }; </script> </head> <body> <!-- 提取行间样式 --> <input id="btn1" type="button" value="按钮"> <!-- 修改一组元素中的某一个元素 --> <input type="button" id="btn2" value="改第三个元素"> <!-- 修改一组元素-循环 --> <input type="button" id="btn3" value="while循环改一组元素"> <input type="button" id="btn4" value="for循环改一组元素"> <input type="button" id="btn5" value="全选"> <input type="button" id="btn6" value="全选2"> <input type="button" id="btn7" value="全选3"> <div><input type="checkbox" name="1" id="c1"></div> <div><input type="checkbox" name="1" id="c2"></div> <div><input type="checkbox" name="1" id="c3"></div> <div><input type="checkbox" name="1" id="c4"></div> <div><input type="checkbox" name="1" id="c5"></div> <div id="div2"> <input type="checkbox" name="" id=""> <input type="checkbox" name="" id=""> <input type="checkbox" name="" id=""> <input type="checkbox" name="" id=""> <input type="checkbox" name="" id=""> <input type="checkbox" name="" id=""> <input type="checkbox" name="" id=""> </div> </body> </html>
-
按钮的实现
- 添加事件
- this 的使用: 指当前发生事件的元素
- 先清空所有按钮,再选中当前按钮
- 添加事件
-
内容的实现(ul)
- 先隐藏所有 ul,再显示当前 ul
- 索引值的使用:什么时候用索引值
- HTML 添加 index 会被 FireFox 过滤
- JS 添加 index
- 先隐藏所有 ul,再显示当前 ul
-
代码:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>导航选项卡</title> <style> body { margin: 0; padding: 0; } #div2 { width: 200px; height: 200px; margin-top: 20px; position: relative; } #div1 { width: 200px; height: 20px; position: absolute; top: 0px; } ul { margin: 0; padding: 0; display: block; background: rgb(157, 234, 253); float: left; position: absolute; display: none; width: 200px; height: 200px; } .ul { display: block; } a { display: block; float: left; width: 49px; height: 20px; background: rgb(7, 184, 253); border-left: 1px solid rgb(255, 0, 234); text-decoration: none; } .a { background: rgb(32, 108, 221); } </style> <script> window.onload = function (){ // 封装 getElementById 函数 function get(id) { return document.getElementById(id); } // 封装 getElementsByTagName function gets(tagName) { return document.getElementsByTagName(tagName) } // 显示第一个元素 gets('ul')[0].className = 'ul'; // 当鼠标覆盖某个标签时 显示对应元素 for (var i = 0; i < 4; i++) { gets('a')[i].index = i; gets('a')[i].onmouseover = function () { for (var a = 0; a < 4; a++) { gets('ul')[a].className = ''; gets('a')[a].className = ''; } // console.log(this); gets('ul')[this.index].className = 'ul'; this.className = 'a'; } } } </script> </head> <body> <div id="div1"> <a href="javascript:;" id="a0">1</a> <a href="javascript:;" id="a1">2</a> <a href="javascript:;" id="a2">3</a> <a href="javascript:;" id="a3">4</a> </div> <div id="div2"> <ul> <li>1</li> <li>1</li> <li>1</li> </ul> <ul> <li>2</li> <li>2</li> <li>2</li> </ul> <ul> <li>3</li> <li>3</li> <li>3</li> </ul> <ul> <li>4</li> <li>4</li> <li>4</li> </ul> </div> </body> </html>
-
程序实现思路
- 类似于选项卡,只是下面只有一个div
- innerHTML 的使用
-
数组的使用
- 定义:
arr = [1, 2, 3]
- 使用:
arr[0]
- 定义:
-
字符串拼接
- 作用:拼接两个字符串
- 问题:拼接中的优先级
- 就近相加, 字符串后面数字相加要加括号
-
代码:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>简易日历</title> <style> body { margin: 0; padding: 0; } td { border: 5px solid rgb(218, 218, 218); width: 59px; height: 59px; text-align: center; background: rgb(83, 83, 83); color: white; } .td { background: rgb(255, 255, 255); color: rgb(0, 0, 0); } /* 日历数字区 */ #t1 { border: 10px solid rgb(218, 218, 218); margin:0 auto; position: relative; width: 240px; height: 320px; background: rgb(218, 218, 218); } /* 下方文字 */ #d2 { margin:0 auto; width: 240px; height: 100px; background: rgb(218, 218, 218); } #p1 { position: relative; margin: auto; width: 205px; height: 80px; background: rgb(255, 255, 255); } </style> <script> window.onload = function () { // 封装 getElementById 函数 function get(id) { return document.getElementById(id); } // 封装 getElementsByTagName function gets(tagName) { return document.getElementsByTagName(tagName) } // 获取所有 td,注册 onmouseover 事件,添加索引 // console.log(gets('td')) var tds = gets('td'); var i = 0; for (i = 0; i < tds.length; i++) { tds[i].index = i; tds[i].onmouseover = function () { // 先清空 td className for (a = 0; a < tds.length; a++) { tds[a].className = ''; } // 修改td className 并插入文字 tds[this.index].className = 'td'; // console.log(i); get('p1').innerHTML = (this.index + 1) + arr[this.index]; } } arr = [ '月活动:学编程、英语', '月活动:学编程、英语', '月活动:学编程、日语', '月活动:学编程、画画', '月活动:学编程、旅游', '月活动:学编程', '月活动:学编程', '月活动:学编程', '月活动:学编程', '月活动:学编程', '月活动:学编程', '月活动:学编程' ] } </script> </head> <body> <div id="d1"> <table id="t1"> <tr> <td>1 <br>JAN</td> <td>2 <br>FER</td> <td>3 <br>MAR</td> </tr> <tr> <td>4 <br>APR</td> <td>5 <br>MAY</td> <td>6 <br>JUN</td> </tr> <tr> <td>7 <br>JUL</td> <td>8 <br>AUG</td> <td>9 <br>SEP</td> </tr> <tr> <td>10 <br>OCT</td> <td>11 <br>NOV</td> <td>12 <br>DEC</td> </tr> </table> <div id="d2"> <p id="p1"> </p> </div> </div> </body> </html>
- ECMAScript:解释器、编译器(几乎所有兼容)
- DOM:Document Object Model,HTML,
document
(大部分兼容) - BOM:Browser Object Model,浏览器,
window
(完全不兼容)- 各组成部分的兼容性、兼容性问题的由来
- 类型:
typeof
运算符- 用法:
typeof 元素
返回变量的类型 - 常见类型:
number
、string
、boolean
、undefined
(未定义或定义未使用)、object
、function
- 用法:
- 一个变量应该只放一种类型的数据
-
数据类型转换
-
例子:计算两个文本框的和
-
显式类型转换(强制类型转换)
-
parseInt()
去除小数、parseFloat()
保留小数:从左至右提取数字,遇到不是数字跳出 -
NaN
的意义和检测:Not a Number
-
NaN: NaN 和任何值都不相等,包括它自己
- 使用
isNaN()
检测是否是全是数字
- 使用
-
Number() 转换数值,String() 转换字符串,Boolean() 转换布尔值
-
-
隐式类型的转换
-
==
:先转换类型 再比较对比
===
:全等于,不转换类型直接比较 -
-
:数字相减对比
+
:字符串连接、数字相加 -
5 + null // 返回 5 因为 null 被转换为 0 "5" + null // 返回 "5null" 因为 null 被转换为 "null" "5" + 2 // 返回 52 因为 2 被转换为 "2" "5" - 2 // 返回 3 因为 "5" 被转换为 5 "5" * "2" // 返回 10 因为 "5" 和 "2" 被转换为 5 和 2
-
-
-
更多可用于将数值转换为字符串的方法:
方法 描述 toExponential() 返回字符串,对数字进行舍入,并使用指数计数法来写。 toFixed() 返回字符串,对数字进行舍入,并使用指定位数的小数来写。 toPrecision() 返回字符串,把数字写为指定的长度。 -
代码:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>变量类型转换</title> <style></style> <script> window.onload = function () { // 封装 getElementById 函数 function get(id) { return document.getElementById(id); } let t1 = get('t1'); let t2 = get('t2'); let b1 = get('b1'); let s1 = get('s1'); let s2 = get('s2'); b1.onclick = function (){ if (isNaN(t1.value)) { s1.innerHTML = '<br>' + t1.value + '不是数字'; } else if (isNaN(t2.value)) { s1.innerHTML = '<br>' + t2.value + '不是数字'; } else { console.log('t1:',typeof t1.value, 't2',typeof t2.value); let val = parseInt(t1.value) + parseInt(t2.value); let val2 = parseFloat(t1.value) + parseFloat(t2.value); s1.innerHTML = '<br>int结果:' + val+ '<br>float结果:' + val2; console.log(typeof val); // == 和 - 隐式转换 let a = t1.value ; let b = t2.value; if (a == b) { s2.innerHTML = 'a == b' + '<br>a - b = ' + (a - b) + '<br>a + b = ' + (a + b); } else if (a === b) { s2.innerHTML = 'a === b!'; } else { s2.innerHTML = 'a不等于b!' + '<br>a - b = ' + (a - b) + '<br>a + b = ' + (a + b); } } } } </script> </head> <body> <input type="text" name="" id="t1"> <input type="text" name="" id="t2"> <input type="button" name="" id="b1" value="计算"> <div> <span id="s1"></span> </div> <div> <span id="s2"></span> </div> </body> </html>
- 变量作用域(作用范围)
- 局部变量、全局变量
- 什么是闭包?
- 子函数可以使用父函数中的局部变量
- 之前一直在使用闭包
- 网上对于闭包的定义
- 命名规范及必要性
- 可读性--能看懂
- 规范性--符合规则
- 匈牙利命名法
- 类型前缀 + 首字母大写:
getElementByTagName
- 类型前缀 + 首字母大写:
类型 | 前缀 | 类型(英文) | 实例 |
---|---|---|---|
数组 | a | Array | aItems |
布尔值 | b | Boolean | bIsComplete |
浮点数 | f | Float | fPrice |
函数 | fn | Function | fnHandler |
整数 | i | Integer | iItemCount |
对象 | o | Object | oDiv1 |
正则表达式 | re | RegExp | reEmailCheck |
字符串 | s | String | sUserName |
变体变量 | v | Variant | vAnything |
-
算数:
+加、-减、*乘、/ 除、%取模
- 实例:隔行变色、秒转时间
-
赋值:
=、+=、-=、*=、/=、%=
+=
:i += 1 等于 i++
-
关系:
<、>、<=、>=、== 、===、!=、!==
!==
:不同类型不比较,且无结果,同类型才比较,对应===
!=
:若类型不同,会偿试转换类型,对应==
-
逻辑:&&与、||或、!否
- 实例:全选与反选
-
运算符优先级:括号
-
代码:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>运算符</title> <style> .blue { width: auto; height: 20px; background: blue; } .yellow { width: auto; height: 20px; background: yellow; } </style> <script> window.onload = function () { // 封装 getElementById 函数 function get(id) { return document.getElementById(id); } // 封装 getElementsByTagName function gets(tagName) { return document.getElementsByTagName(tagName) } // 隔行变色 function liCol() { let i = 0; let oLi = gets('li') ; for (i = 0; i < oLi.length; i++) { if (i % 2 === 0) { oLi[i].className = 'blue'; } else { oLi[i].className = 'yellow'; } } } liCol(); // 毫秒转日期 const date = Date.now(); // 60000ms / 1000ms /60s /60m /24h /365d const millisecond = date % 1000 + '毫秒'; const second = parseInt(date/1000) % 60 + '秒'; const minute = parseInt(date/1000/60) % 60 + '分'; const hour = parseInt(date/1000/60/60) % 24 + 8 + '小时'; const day = parseInt(date/1000/60/60/24/365) % 30 - 9 + '号'; const month = parseInt(date/1000/60/60/24/30) % 12 + 4 + '月'; const year = parseInt(date/1000/60/60/24/265) + 1951 +'年'; const d1 = get('d1'); d1.innerHTML = millisecond+ second+ minute+ hour+ day+ month+ year; } // 赋值 ` =、+=、-=、*=、/=、%= ` let i = 11; i += 2; console.log(i); i -= 3; console.log(i); i *= 2; console.log(i); i /= 2; console.log(i); i %= 3; console.log(i); // 判断 <、>、<=、>=、== 、===、!=、!== if (i > 0) { console.log('i > 0'); } if (i <= i) { console.log('i <= i'); } if (i == '1') { console.log('i == "1"') } if (i === 1) { console.log('i === 1') } if (i != '1') { console.log('i != 2') } if (i !== 1) { console.log('i !== 1') } // 逻辑 &&与、||或、!否 if (i<2 && i>0) { console.log('i<2 && i>0') } if (i<2 || i<0) { console.log('i<2 || i<0') } </script> </head> <body> <div> <ul> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> <li></li> </ul> </div> <div id="d1"></div> </body> </html>
- 判断:
if、switch、?:
- 循环:
while、for
- 跳出:
break、continue
- 什么是真、什么是假
- 真:true、非零数字、非空字符串、非空对象
- 假:false、数字0、空字符串、空对象、undefiend
- 代码:同下
-
什么是 JSON
-
JSON 和数组
-
JSON
和for in
-
代码:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>程序流程控制</title> <script> window.onload = function () { // switch var i = 0; switch (i){ case i*++i: console.log('i'); break; case 1: console.log('1') break; default: console.log('default'); break; } // ?: 条件?语句一:语句二 var a = 1; a % 2 == 0 ? console.log('双数'):console.log('单数'); // break continue for (i = 0; i < 5; i++){ if (i === 2){ // break; // 中断所有循环 continue; // 中断本次循环 } console.log(i); } // json 和 数组 const json = {a: 2, b: 5, c:9}; const arr = [23, 45, 5467]; console.log('b:', json.b, 'c:', json['c'], '没有length', json.length); console.log(arr[2], arr.length); // JSON 和 for in for (var i in arr) { console.log('第' + i + '个:' + arr[i]); } for (var i in json) { console.log('第' + i + '个:' + json[i]); } } </script> </head> <body> </body> </html>
- 什么是函数返回值
- 函数的执行结果
- 可以没有 return
- 一个函数应该只有一种返回值类型
-
可变函数(不定参数):
arguments
- 参数数组
-
例子:求和
- 求所有参数的和
-
例子2:CSS 函数
- 判断
arguments.length
- 给参数取名,增强可读性
- 判断
-
取非行间样式(不能用来设置):
-
obj.currentStyle[attr]
只兼容 IE ,返回小数 -
getComputedStyle(obj, false)[attr]
,返回小数 -
// 解决兼容问题 // 封装获取计算后元素样式函数 function getStyle(obj, name) { if (obj.currentStyle) { return obj.currentStyle[name]; } else { return getComputedStyle(obj, '') [name]; } }
-
复合样式:
background
/border
要用具体样式名backgroundColor
等 -
单一样式:
width
/height
/position
-
-
数组的使用
- 定义
var arr = [23, 234, 23, 45];
var arr = new Array(12, 5, 7, 34);
- 没有任何差别,
[]
的性能略高,因为代码短
- 定义
-
数组的属性
length
- 既可以获取,又可以设置
- 例子:快速清空数组
length = 0
-
数组的使用原则:数组中应该只存一种类型的变量
-
数组的方法
- 添加
push(元素)
,从尾部添加unshift(元素)
,从头部添加
- 删除
pop()
,从尾部删除shift()
,从头部删除
- 添加
-
排序
-
数组.sort([比较函数])
,排序一个数组,只有数组能使用-
排序一个字符串数组,不加比较函数,默认按照 ASCII 码排序
-
排序一个数字数组,加数字比较大小函数
-
// 正序比较函数 数字比大小 字符比ASCII值大小 function positiveSort(n1, n2) { if (isNaN) { if (n1 > n2) { return 1; } if (n1 < n2) { return -1; } if (n1 === n2) { return 0; } } else { return n1 - n2; } }
-
-
-
转换类
数组.concat(数组2)
- 连接两个数组,可用于深度复制
数组.join(分隔符)
- 用分隔符,组合数组元素,生成字符串
- 字符串
split
数组.reverse()
- 颠倒数组中元素的顺序
-
数组.slice(start,end)
- 从已有数组中返回选定元素,可用于深度复制
- start 为负数时,和数组长度相加再查找
-
splice
:先删除,后插入 -
数组.splice(起点,长度,元素)
-
删除
数组.splice(起点,长度)
-
插入
数组.splice(起点,0,元素...)
-
替换
数组.splice(起点,长度,元素)
-
ECMAScript 两个关于位置的方法
arrayObject.indexOf(searchvalue,startIndex)
- 从startIndex 开始向后查找,默认值为 0
- 返回 number 查找项在数组中的位置,没找到返回-1
- ``arrayObject.lastIndexOf(searchvalue,startIndex)`
- 从startIndex 开始向前查找,默认值为 0
- 返回 number 查找项在数组中的位置,没找到返回-1
-
代码:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>数组操作</title> <style> div { margin-top: 10px; } </style> <script> var arr = [23, 435, 567, 321, 9, 4]; var arr2 = new Array('m', 'r', 'a', 'z', 'c', 'p', 'e', '破就', '不发'); // 封装getById function get(id) { return document.getElementById(id); } window.onload = function () { // 显示数组 function showArr() { get('d1').innerHTML = arr + ' + ' + arr2; } showArr(); // 添加元素 从尾部添加 get('btn2').onclick = function () { arr.push(222); showArr(); } // 添加元素 从头部添加 get('btn22').onclick = function () { arr.unshift(234); showArr(); } // 删除元素 从尾部删除 get('btn3').onclick = function () { arr.pop(); showArr(); } // 删除元素 从头部删除 get('btn33').onclick = function () { arr.shift(); showArr(); } // 排序元素 get('btn4').onclick = function () { arr.sort(positiveSort); arr2.sort(positiveSort); showArr(); } // 比较函数 数字比大小 字符比ASCII值大小 function positiveSort(n1, n2) { if (isNaN) { if (n1 > n2) { return 1; } if (n1 < n2) { return -1; } if (n1 === n2) { return 0; } } else { return n1 - n2; } } // 拼接数组 get('btn5').onclick = function () { arr = arr.concat(arr2); showArr(); } // 分隔符 get('btn6').onclick = function () { arr = arr.join('_'); showArr(); } // splice 插入 splice(起点,长度,元素) get('btn7').onclick = function () { arr.splice(2, 0, 5, 1); showArr(); } // splice 删除 get('btn8').onclick = function () { arr.splice(0, arr.length); showArr(); } // splice 替换 = 删除 + 插入 get('btn9').onclick = function () { arr.splice(2, 1, 999, 888); showArr(); } } </script> </head> <body> <div> <input type="button" name="" id="btn2" value="尾部添加元素"> <input type="button" name="" id="btn22" value="头部添加元素"> <input type="button" name="" id="btn3" value="尾部删除元素"> <input type="button" name="" id="btn33" value="头部删除元素"> <input type="button" name="" id="btn4" value="正序排序元素"> </div> <div> <input type="button" name="" id="btn5" value="拼接数组"> <input type="button" name="" id="btn6" value="分割数组"> </div> <div> <input type="button" name="" id="btn7" value="插入元素"> <input type="button" name="" id="btn8" value="删除元素"> <input type="button" name="" id="btn9" value="替换元素"> </div> <div id="d1"></div> </body> </html>
-
数组名作为变量(遍历数组中的数组):
var arr1=new Array(); var arr2=new Array(); var arrlist= new Array(); //存放以上数组 arrlist.push(arr1); arrlist.push(arr2); //循环遍历arrlist,就可以达到你要的效果
-
开启定时器
setInterval(函数, 间隔时间)
间隔型,函数后面不能带括号和传参setTimeout(函数, 延时时间)
延时型- 两种定时器的区别,定时器要
window.onload
完一秒后才执行
-
停止定时器
clearInterval(定时器名字)
clearTimeout(定时器名字)
-
代码:
window.onload = function () { var oBtn1 = document.getElementById('btn1'); var oBtn2 = document.getElementById('btn2'); var timer = null; oBtn1.onclick = function () { timer = setInterval(function () { alert('a'); }, 2000); }; oBtn2.onclick = function () { clearInterval(timer); }; };
-
效果思路
-
获取系统时间
new Date
对象getHours / getMinutes / getSeconds
-
显示系统时间
- 字符串连接
- 空位补零
-
设置图片路径
str[i]
:取出字符串中的第 i 个值,不兼容 ie7
-
charAt(i)
方法 :取出字符串中的第 i 个值,兼容各种浏览器 -
设置路径:
"url('img/0.png')"
-
JavaScript 中的 String 方法
obj.charAt(index)
- 返回index位置的字符
obj.charCodeAt()
- 返回index位置的字符编码
obj.indexOf("str")
- 顺序搜索str,返回其位置,未找到返回-1
obj.lastIndexOf("str")
- 倒序搜索str,返回其位置,未找到返回-1
slice(start,end)
:同数组substring(start,end)
:同上,区别在于参数为负数时自动转换为0,并且较小的数为起始位substr(start,len)
:同上,len 表示截取的长度
-
代码:
<!DOCTYPE html> <html> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>数码时钟</title> <style> body{ margin: 0; padding: 0; background-color: rgb(49, 49, 49); } li { list-style: none; float: left; width: 100px; height: 149px; } span { float: left; font-size: 100px; color: rgb(255, 255, 255); } </style> <script> window.onload = function () { // 封装 getElementsByTagName function gets(tagName) { return document.getElementsByTagName(tagName) } // 数码时钟 // 数字时钟图片设置函数 const oLi = gets('li'); function clock() { const date = new Date(); const str = addZero(date.getHours()) + addZero(date.getMinutes()) + addZero(date.getSeconds()); let i = 0; for (i = 0; i < oLi.length; i++) { oLi[i].style.backgroundImage = "url('img/"+ str.charAt(i) +".png')"; } } // 补零 function addZero(num) { if (num < 10) { num = '0' + num; } else { num = '' + num; } return num; } // 先执行一遍,就不会出现一秒的空白,定时器要 window.onload 完一秒后才执行 clock(); // 定时器 每秒刷新一次 setInterval(clock, 1000); } </script> <body> <ul> <li></li> <li></li> <span>:</span> <li></li> <li></li> <span>:</span> <li></li> <li></li> </ul> </body> </html>
方法 | 描述 |
---|---|
getDate() | 获得以数值计(1-31)的日 |
getDay() | 或者以数值计(0-6)的周 |
getFullYear() | 获得四位的年(yyyy) |
getHours() | 获得时(0-23) |
getMilliseconds() | 获得毫秒(0-999) |
getMinutes() | 获得分钟(0-59) |
getMonth() | 获得月(0-11) |
getSeconds() | 获得秒(0-59) |
getTime() | 获得时间(1970 年 1 月 1 日以来的毫秒) |
-
效果演示
-
原来的方法
- 移入显示,移出隐藏
-
移出延时隐藏
- 移入下面
div
后,还是隐藏
- 移入下面
-
简化代码
- 合并两个相同的
mouseover
和mouseout
- 连续
a=b=c=function()
两个事件共使用一个函数
- 合并两个相同的
-
代码:同下
-
效果演示
-
物体运动基础
- 让
div
移动起来 offsetLeft/offsetTop
的作用:获取当前对象的左边距/上边距offsetWidth/offsetHeight
- 用定时器让物体连续移动:
innerHTML
拼接两节图片, 宽度后面加px
才会生效overflow:hidden;
隐藏元素外的内容
- 让
-
改变滚动的方向
- 修改
speed
- 修改判定条件
- 多次点击越来越快:
if (!timer)
或clearInterval(timer);
避免重复调用
- 修改
-
鼠标移入暂停
- 移入关闭定时器
- 移出重新开启定时器
-
代码:
<!DOCTYPE html> <html> <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <link rel="stylesheet" href="../reset.css"> <title>移出延时隐藏</title> <style> body { width: 560px; margin: 0 auto; } #d2 { margin: 10px; width: 200px; height: 200px; background-color: rgb(0, 204, 255); display: none; float: left; } #d1 { margin: 10px; width: 100px; height: 100px; background-color: rgb(0, 255, 149); float: left; } #d3 { margin: 220px auto; width: 560px; height: 140px; position: absolute; background-color: rgb(135, 182, 182); overflow: hidden; } #u1 { position: relative; } #u1 li { float: left; } </style> <script> window.onload = function () { // 封装 getElementById 函数 function get(id) { return document.getElementById(id); } // 封装 getElementsByTagName function gets(tagName) { return document.getElementsByTagName(tagName) } // 鼠标移动到 d1 上,d2 显示,移出隐藏; // 鼠标移到 d2 上,清除定时器,移出 d2 开启定时器 let timer = ''; get('d1').onmouseover= get('d2').onmouseover = function () { clearTimeout(timer); get('d2').style.display = 'block'; } get('d1').onmouseout= get('d2').onmouseout = function () { timer = setTimeout(hide,1000); } function hide() { get('d2').style.display = 'none'; } // 无缝滚动 get('u1').innerHTML += get('u1').innerHTML; get('u1').style.width = gets('li').length * gets('li')[0].offsetWidth + 'px'; let timer2 = ''; let speed = 2; // 左移 get('btn1').onclick = function () { speed = -2; if (!timer2) { timer2 = setInterval(move, 30); } } // 右移 get('btn2').onclick = function () { speed = 2; if (!timer2) { timer2 = setInterval(move, 30); } } // 移动 function move() { get('u1').style.left = get('u1').offsetLeft + speed + 'px'; if (get('u1').offsetLeft < -get('u1').offsetWidth/2) { get('u1').style.left = 0; } else if (get('u1').offsetLeft > 0){ get('u1').style.left = -get('u1').offsetWidth/2 + 'px'; } console.log(get('u1').offsetLeft); } // 鼠标悬停 get('d3').onmouseover = function () { clearInterval(timer2); } get('d3').onmouseout = function () { timer2 = setInterval(move, 30); } } </script> <body> <div id="d1"></div> <div id="d2"></div> <div id="d3"> <ul id="u1"> <li><img src="images/1.png" alt=""></li> <li><img src="images/2.png" alt=""></li> <li><img src="images/3.png" alt=""></li> <li><img src="images/4.png" alt=""></li> </ul> </div> <input type="button" name="" id="btn1" value="左移"> <input type="button" name="" id="btn2" value="右移"> </body> </html>
- 什么是 DOM
- 浏览器支持情况
- DOM 节点
- 获取子节点
childNodes
:不兼容高版本,用nodeType
兼容- 获取文本节点
( nodeType == 3)
和元素节点( nodeType == 1)
- 获取文本节点
children
:只获取元素节点,兼容
parentNode
:查找父节点- 例子:点击链接,隐藏整个
li
- 例子:点击链接,隐藏整个
offsetParent
:查找定位父级- 例子:获取元素在页面上的实际位置
- 首尾子节点
firstChild
有兼容性问题,IE6-8用firstElementChild
高版本使用lastChild
/lastElementChild
- 兄弟节点
- 有兼容性问题,IE6-8用前面的
nextSbling
/nextElementSibling
previousSibling
/previousElementSibling
- 获取子节点
- 操作元素属性
- 元素属性操作
- 第一种:
oDiv.style.display = 'block';
- 第二种:
oDiv.style['display'] = 'block';
- 第三种:Dom 方式
- 第一种:
- Dom 方式操作元素属性
- 获取:
getAttribute(名称)
- 设置:
setAttribute(名称, 值)
- 删除:
removeAttribute(名称)
- 获取:
- 元素属性操作
-
用 className 选择元素
-
如何用 className 选择元素
- 选出所有元素
- 通过 className 条件筛选
-
封装成函数:
// 通过 className 查找元素 function getByClass(oParent, sClass) { var aResult = []; var aEle = oParent.getElementsByTagName('*'); for(var i = 0; i < aEle.length; i++) { if (aEle[i].className == sClass) { aResult.push(aEle[i]); } } return aResult; }
-
## DOM 操作应用
### 创建、插入和删除元素
- 创建 DOM 元素
- `document.createElement(标签名)` 创建一个节点,不渲染
- `父级.appendChild(节点)` **删除原有子节点**,再添加子节点,并渲染
- 例子:为 `ul` 插入 `li`
- 插入元素
- `父级.insertBefore(节点, 原有节点)` 在已有元素前插入
- 例子:倒叙插入 `li`
- 删除 DOM 元素
- `父级.removeChild(节点)` 删除一个节点
- 例子:删除 `li`
- 代码:
```HTML
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>DOM创建插入删除元素</title>
<script>
window.onload = function () {
// 封装getElementById
function get(id) {
return document.getElementById(id);
};
// 在 ul 下增加 li
let oUl = get('u1');
get('btn1').onclick = function () {
let oLi = document.createElement('li');
let sL = get('txt1').value + "<a href='javascript:;'>删除</a>";
oLi.innerHTML = sL;
oUl.appendChild(oLi);
aRemove();
};
// 从 ul 下插入 li
get('btn2').onclick = function () {
let oLi = document.createElement('li');
let aLi = document.getElementsByTagName('li');
let sL = get('txt1').value + "<a href='javascript:;'>删除</a>";
let i = get('txt2').value - 1;
oLi.innerHTML = sL;
if (aLi.length > i && aLi.length > 0) {
oUl.insertBefore(oLi, aLi[i]);
} else {
oUl.appendChild(oLi);
}
aRemove();
};
// 从 ul 下删除 li
get('btn3').onclick = function () {
let aLi = document.getElementsByTagName('li');
let i = get('txt2').value - 1;
if (i < aLi.length && i >= 0) {
oUl.removeChild(aLi[i]);
} else {
alert('找不到第'+ (parseInt(i) + 1) +'个li');
}
};
// this 从 ul 删除 li
function aRemove() {
let aA = document.getElementsByTagName('a');
let i =0
for (i = 0; i < aA.length; i++) {
aA[i].onclick = function () {
oUl.removeChild(this.parentNode);
}
}
}
}
</script>
</head>
<body>
<input type="text" name="" id="txt1" value="123">
<input type="button" name="" id="btn1" value="增加">
<input type="text" name="" id="txt2" value="1">
<input type="button" name="" id="btn2" value="插入">
<input type="button" name="" id="btn3" value="删除">
<div is="d1">
<ul id="u1">
</ul>
</div>
</body>
</html>
-
文档碎片理论上可以提高 DOM 操作性能
-
文档碎片原理
-
document.createDocumentFragment()
:Vue 、MVVM 还有用到 -
代码:
var element = document.getElementById('ul'); // assuming ul exists var fragment = document.createDocumentFragment(); var browsers = ['Firefox', 'Chrome', 'Opera', 'Safari', 'Internet Explorer']; browsers.forEach(function(browser) { var li = document.createElement('li'); li.textContent = browser; fragment.appendChild(li); }); element.appendChild(fragment);
表格 | 描述 | ||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
(1)、性能卓越,执行速度通常是 Mustache 与 tmpl 的 20 多倍(性能测试) (2)、支持运行时调试,可精确定位异常模板所在语句(演示) (3)、对 NodeJS Express 友好支持 (4)、安全,默认对输出进行转义、在沙箱中运行编译后的代码(Node版本可以安全执行用户上传的模板) (5)、支持include语句 (6)、可在浏览器端实现按路径加载模板(详情) (7)、支持预编译,可将模板转换成为非常精简的 js 文件 (8)、模板语句简洁,无需前缀引用数据,有简洁版本与原生语法版本可选 (9)、支持所有流行的浏览器 (1)、使用 引用简洁语法的引擎版本,例如: (2)、表达式 {{ 与 }} 符号包裹起来的语句则为模板的逻辑表达式。
(3)、输出表达式 对内容编码(转义)输出: (4)、条件表达式 {{if admin}}
<p>admin</p>
{{else if code > 0}}
<p>master</p>
{{else}}
<p>error!</p>
{{/if}} (5)、遍历表达式 无论数组或者对象都可以用 each 进行遍历。 {{each list as value index}}
<li>{{index}} - {{value.user}}</li>
{{/each}}
// 亦可以被简写:$ 特指当前函数中的变量
{{each list}}
<li>{{$index}} - {{$value.user}}</li>
{{/each}} (6)、模板包含表达式 用于嵌入子模板。
子模板默认共享当前数据,亦可以指定数据: (7)、辅助方法 使用 template.defaults.imports.dateFormat = function(arg1,arg2) {
// ..
return value;
}); 模板中使用的方式: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script src="./lib/template-web.js"></script>
</head>
<body>
<div id="content"></div>
<script id="test" type="text/html">
<div>
<!-- 输出表达式 -->
<p>{{name}}</p>
<!-- 不转义输出 -->
<p>{{#value}}</p>
<!-- 条件表达式 -->
{{if bool}}
<p>{{bool}}</p>
{{/if}}
{{if num < 1 }}
<p>'num < 1'</p> {{else}} <p>error!</p>
{{/if}}
<!-- 遍历表达式 数组 -->
<p>遍历表达式 数组</p>
{{each list as value index}}
<li>{{index}}: {{value}}</li>
{{/each}}
<!-- $简写 $ 特指当前函数中的变量 -->
<p>$简写</p>
{{each list}}
<li>{{$index}}: {{$value}}</li>
{{/each}}
<!-- 遍历表达式 对象 -->
<p>遍历表达式 对象</p>
{{each objList as value index}}
<li>{{index}}: {{value}}</li>
{{/each}}
<!-- $简写 -->
<p>$简写</p>
{{each objList}}
<li>{{$index}}: {{$value}}</li>
{{/each}}
<!-- 模板包含子模板,表达式 -->
{{include 'news_list'}}
<!-- 辅助方法 -->
</div>
</script>
<script id="news_list" type="text/html">
<p>模板包含子模板,表达式</p>
<ul>
{{each list as value i}}
<li>索引 {{i + 1}} :{{value + 1}}</li>
{{/each}}
</ul>
</script>
<script>
const data = {
name: 'zhangsan',
value: '<h1>lisi</h1>',
num: 0,
bool: true,
list: [1, 2, 3, 4, 5],
objList: {
name: 'zhangsan',
age: '18',
addr: '广东'
}
}
let temp = template('test', data)
document.getElementById('content').innerHTML = temp
</script>
</body>
</html> <!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>no escape-demo</title>
<script src="../dist/template.js"></script>
</head>
<body>
<h1>不转义HTML</h1>
<div id="content"></div>
<script id="test" type="text/html">
<p>不转义:{{#value}}</p>
<p>默认转义: {{value}}</p>
</script>
<script>
var data = {
value: '<span style="color:#F00">hello world!</span>'
};
var html = template('test', data);
document.getElementById('content').innerHTML = html;
</script>
</body>
</html> <!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>include-demo</title>
<script src="../dist/template.js"></script>
</head>
<body>
<div id="content"></div>
<script id="test" type="text/html">
<h1>{{title}}</h1>
{{include 'list'}}
</script>
<script id="list" type="text/html">
<ul>
{{each list as value i}}
<li>索引 {{i + 1}} :{{value}}</li>
{{/each}}
</ul>
</script>
<script>
var data = {
title: '嵌入子模板',
list: ['文艺', '博客', '摄影', '电影', '民谣', '旅行', '吉他']
};
var html = template('test', data);
document.getElementById('content').innerHTML = html;
</script>
</body>
</html> 左侧工具栏是按字母表排序的列表。 JavaScript中基本关键字和常用表达式。
左边的值是赋值的目标。
前置/后置自增运算符和前置/后置自减运算符. 一元运算符只有一个操作数.
算术运算符以二个数值(字面量或变量)作为操作数,并返回单个数值。 比较运算符比较二个操作数并返回基于比较结果的
注意: => 不是运算符,而是 如果相等,操作符返回的是Boolean(布尔)类型的true,否则是false。 在二进制的基础上对数字进行移动操作 二进制运算符将它们的操作数作为32个二进制位(0或1)的集合,并返回标准的JavaScript数值。 逻辑运算符典型的用法是用于boolean(逻辑)值运算, 它们返回boolean值。
赋值元素符会将右边的操作数的值分配给左边的操作数,并将其值修改为右边操作数相等的值。 |