前端与JavaScript(上)|青训营笔记
这是我参与「第四届青训营 」笔记创作活动的的第五天
一.初识JavaScript
二.javascrpit输入输出语句
| 方法 | 说明 |
|---|---|
| alert(msg) | 浏览器弹出警示框 |
| console.log(msg) | 浏览器控制台打印输出信息 |
| prompt(info) | 浏览器弹出输出框,用户可以输入 |
三.变量
声明变量
var age;声明一个age的变量
变量的初始化
var age = 18 ;
更新变量
var age = 18 ;
console.log(age);输出为18
age = 22
console.log(age);输出为22
后面覆盖前面
四.数据类型
JS是动态语言,变量的数据类型可以改变
简单数据类型(基本数据类型)
简单数据类型 说明 默认值
Number 数字型包含整型、浮点型(21、0.21) 0
Boolean 布尔,true false false
String 字符串 ""
Undefined var a 声明变量没有给值,a=Undefined Undefined
Null var a = null;声明为空 null
数字型范围Number
最大值和最小值
alert(Number.MAX_VALUE);
alert(Number.MIN_VALUE);
数值型三个特殊值
alert(Infinity);无穷大
alert(-Infinity);无穷小
alert(NaN); not a number 代表一个非数值 判断是不是数字 是数字返回false
五.if语句
案例:水仙花
<script>
//水仙花判断
var n = Number(prompt('请输入一个三位数'));
//对用户输入的数值,进行合法的验证
if (!isNaN(n) && 100 <= n && n <= 999) {
//把数字n变为字符串
var n_str = n.toString();
//百位
//var a = Math.floor(n / 100);
var a = Number(n_str.charAt(0));
//十位
//var b = Math.floor(n / 10) % 10
var b = Number(n_str.charAt(1));
//个位
//var c = n % 10;
var c = Number(n_str.charAt(2));
console.log(a);
console.log(b);
console.log(c);
//根据水仙花数的条件进行判断
if (Math.pow(a, 3) + Math.pow(b, 3) + Math.pow(c, 3) == n) {
//Math.pow(a, 3) 意思是a的三次方
alert('这个数字是水仙花数');
} else {
alert('这个数字不是水仙花数');
}
} else {
alert('输出不合法');
}
</script>
六.switch语句
用途:当一个变量被分类讨论的情况
多条case能公用同一个语句体
案例:输入月份
<script>
//让用户输入年份
var year = Number(prompt('输入年份'));
//让用户输入一个月份
var month = Number(prompt('请输入月份'));
//分类讨论
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
alert('这个月有31天');
break;
case 4:
case 6:
case 9:
case 11:
alert('这个月有30天');
break;
case 2:
//根据用户输入的值year计算是不是闰年
if (year % 4 == 0 && year % 100 != 0 || year % 100 == 0 && year % 400 == 0) {
//满足闰年的条件
alert('这个月有28天');
} else {
alert('这个月有29天')
}
//alert('这个月有28天或29天');
break;
default:
alert('输入有误');
}
</script>
七.三元运算符
条件表达式?表达式1:表达式2(当条件表达式为真时调用表达式1,为假时调用表达式2)
用途:根据某个条件是否成立,在两个不同的值中选择变量的值
案例:
<script>
var age = Number(prompt('输入年龄'));
//三元运算
//var type = age >= 18 ? '成年人' : '未成年人';
var type;
if (age >= 18) {
type = '成年人';
} else {
type = '未年人';
}
alert(type);
</script>
八.for循环
for(var i = 2; i < 12; i += 3){
i +=4;
console.log(i);
}
6 13
toFixed(1) 保留一位小数
案例99乘法表:
<script>
for (var i = 1; i <= 9; i++) {
for (var j = 1; j <= i; j++) {
document.write(j + '*' + i + '=' + j * i + ' ');
}
document.write('<br>');
}
</script>
案例鸡兔同笼:
<script>
for (var x = 0; x <= 35; x++) {
for (var y = 0; y <= 35; y++) {
if (x + y == 35 && 2 * x + 4 * y == 94) {
console.log('小鸡' + x, '兔子' + y);
}
}
}
</script>
穷举水仙花
<script>
for (var i = 100; i < 1000; i++) {
//水仙花数要拆位数
//a,b,c分别表示百位,十位,个位
var i_str = i.toString(); //转为字符串
var a = i_str.charAt(0);
var b = i_str.charAt(1);
var c = i_str.charAt(2);
if (Math.pow(a, 3) + Math.pow(b, 3) + Math.pow(c, 3) == i) {
console.log(i);
}
}
</script>
九.while循环
- 一种’不定范围‘循环
- whlie语句事先不指定循环开始 结束范围 只要测试条件满足就一直执行循环体
- 循环体语句,必须使条件趋向部成立 否则死循环
案例求100以内基数和:
// 求100以内基数和
var i = 1;
var sum = 0;
while (i <= 100) {
if (i % 2 !== 0) {
sum += i;
}
i++;
}
console.log(sum);
十.do while循环
do-while循环将循环执行条件写到循环体的后面,这样循环体一定会至少执行一次,然后再检测循环执行条件是否位true,决定是否继续执行循环体
do{
循环体
}while(循环条件)
随机函数:
parseInt 取整
得到[a,b]区间的整数,公式 parseInt(Math.random()*(b-a+1))+a
案例猜数字:
<script>
//随机数字,2~99之间
var answer = parseInt(Math.random() * 98) + 2;
//此时范围的最小值和最大值,用来提示用户
var min = 1;
var max = 100;
//为了重复死循环
while (true) {
//询问用户猜测的数字
var n = Number(prompt('请猜测数字' + min + '~' + max));
if (n <= min || n > max) {
alert('输入的值不在范围,请从新输入');
//如果不再区间直接放弃这次循环跳过,开始下一次迭代
continue;
}
//判断
if (n > answer) {
alert('输入的数字太大了');
//因为输入的数字太大,让此时最大范围的值变为用户输入的值
max = n;
} else if (n < answer) {
alert('输入的数字太小了');
////因为输入的数字太小,让此时最小范围的值变为用户输入的值
min = n;
} else {
alert('输入正确!!!');
break;
}
}
//写法二*******************************************
do {
//询问用户猜测的数字
var n = Number(prompt('请猜测数字' + min + '~' + max));
if (n <= min || n > max) {
alert('输入的值不在范围,请从新输入');
//如果不再区间直接放弃这次循环跳过,开始下一次迭代
continue;
}
//判断
if (n > answer) {
alert('输入的数字太大了');
//因为输入的数字太大,让此时最大范围的值变为用户输入的值
max = n;
} else if (n < answer) {
alert('输入的数字太小了');
////因为输入的数字太小,让此时最小范围的值变为用户输入的值
min = n;
}
} while (n != answer); //当输入的值不等于正确答案时上面的循环的一直执行
alert('猜对了');
</script>
十一.数组(Array)
var arr=['a','b','c'];
var arr =new Array('a','b','c'); 表示函数在调用
var arr =new Array(4);
.toUpperCse(); 变为大写
数组的头尾操作方法:
| 方法 | 功能 |
|---|---|
| push() | 在尾部插入新项 |
| pop() | 在尾部删除最后一项 里面参数没有意义 有返回值 |
| unshift() | 在头部插入新项 |
| shift() | 在头部删除 |
splice()方法用于替换数组的指定项
| 方法 | 功能 |
|---|---|
| arr.spice(3,2,'x','y') | 从下标为3的项开始,连续替换2项 |
| arr.spice(3,0,'x','y') | 当变成0的时候 表示直接插入下标为3的前面 |
| arr.spice(3,1) | 直接删除下标为3个那项 |
| arr.spice(3,3) | 直接删除下标为3个那项和后面的 一共删除三个 |
都有返回值
slece()
arr.slice(2,5) 取下标为2开始后面的5项
join()和split()方法
数组转换为字符转 用join; 字符串转化为数组用split
concat()方法
合并链接多个数组
var varr1 = [1,2,3,4];
var arr2 = [5,6,7,8];
var arr3 = [9,10,11];
var arr = arr1.concat(arr2,arr3);
元素组不会受改变
reverse()方法用来将数组中的全部顺序置放 只能对数组使用
indexOf()和includes()方法
indexOf():搜索数组中的元素,并返回它所在的位置,如果元素不存在,贼返回-1
includes():判断一个数组是否包含一个指定的值,放回布尔值
十二.函数
function fun(){ }
匿名函数:
var fun = function(){}
函数的返回值:
调用一个有返回值的函数,可以被当作一个普通值,从而可以出现在任何可以书写值得地方
变量作用域:
变量只在其定义时所在的function内部具有意义 (局部变量)
闭包:函数本身和该函数声明时所处的环境状态的组合:
它允许我们将数据与操作该数据的函数关联起来
记忆性:当闭包产生的时候,函数所处环境的状态始终保持在内存中,不会在外层函数调用后被自动清除。这就是闭包的记忆性
注意点:不能滥用闭包,否则会造成网页的性能问题,严重时可能导致内存泄露。所谓内存泄漏是指程序中已动态分配的内存由于某种原因未释放或无法释放
IIFE 立即调用函数表达式,特殊写法,一旦被定义,就立即被调用
十三.DOM 文档对象模型
是javaScript操作HTML文档的接口,使文档操作变得非常方便
nodeType常用属性值
1 元素节点
3 文字节点
8 注释节点
9 document节点
10 DTD节点
访问元素节点的常用方法
| 标题 | |
|---|---|
| document.getElementById() | 通过ID得到元素 |
| document.getElementsByTagName() | 通过标签名得到元素数组 |
| document.getElementsByClassName() | 通过类名得到元素数组 |
| document.querySelector() | 通过选择器得到元素 |
| document.querySelectorAll() | 通过选择器得到元素数组 |
延迟运行
在测试DOM代码时,通常JS代码 一定要写在HTML节点的后面,否则JS无法找到相应的HTML
可以使用window.onload=function(){}事件,使页面加载完毕后,再执行指定的代码
节点的关系
| 关系 | 考虑所有节点 |
|---|---|
| 子节点 | childNodes |
| 父节点 | parentNode |
| 第一个子节点 | firstChild |
| 最后一个子节点 | lastChild |
| 前一个兄弟节点 | previousSibling |
| 后一个兄弟节点 | nextSibling |
如何改变元素节点中的内容
1.innnerHTML
2.innerText
不符合W3C标准的属性,要使用setAttribute()和getAttribute()来设置、读取
oBox.setAttribute('data-n',10;
var n = oBox.getAttribute('data-n');
alert(n);
节点的创建:
document.createElemnt()方法用于创建一个指定的Tagname的HTML元素
var oDiv =document.createElemnt('div');
新创建出来的节点是孤儿节点 意味着并没有被挂在到DOM树上,无法就看见 必须使用appendChild()或者insertBefore()将孤儿节点插入到DOM树上
appendChild(),可以将孤儿节点挂载到内部,称为它最后一个子节点
父节点.appendChild(孤儿节点);
insertBefore(),可以将孤儿节点挂载到内部,成为它的‘标杆子节点’之前的节点
父节点.insertBefore(孤儿节点,标杆节点);
删除节点
removeChild()方法从DOM中删除一个子节点
父节点.removeChild(要删除的子节点);
节点不能主动删除自己,必须由父节点删除它
克隆节点
cloneNode()方法可以克隆节点,克隆出的节点是‘孤儿节点’
var 孤儿节点 = 老节点.cloneNode();
var 孤儿节点 = 老节点.cloneNode(true);
参数是个布尔值,表示是否采用深度克隆:如果为true,则该节点的所有后代节点也都会被克隆,如果为false,则只克隆该节点本身
事件监听
DOM允许我们书写javaScript代码以让html元素对事件做出反应
| 事件名 | 事件描述 |
|---|---|
| onclick | 当鼠标单击某个对象 |
| ondblclick | 当鼠标双击某个对象 |
| onmousedown | 当某个鼠标按键在某个对象上被按下 |
| onmouseup | 当某个鼠标按键在某个对象上被松开 |
| onmousemove | 当某个鼠标按键在某个对象上被移动 |
| onmouseenter | 当鼠标进入某个对象(相似事件onmouseover) |
| onmouseleave | 当鼠标离开某个对象(相似事件onmouseout) |
常见的键盘事件监听
| 事件名 | 事件描述 |
|---|---|
| onkeypress | 当某个键盘的键被按下(系统按钮如箭头键和功能键无法得到识别) |
| onkeydown | 当某个键盘的键被按下(系统按钮可以识别,并且会先于onkeypress发生) |
| onkeyup | 当某个键盘的键被松开 |
常见的页面事件监听
| 事件名 | 事件描述 |
|---|---|
| onload | 当页面或图像被完成加载 |
| onunload | 当用户退出页面 |
常见的表单事件监听
| 事件名 | 事件描述 |
|---|---|
| oninput | 当用户正在修改 |
| onchange | 当用户改变域(Field)的内容 |
| onfocus | 当某元素获得焦点(比如tab键或鼠标点击) |
| onblur | 当某元素失去焦点 |
| onsubmint | 当表单被提交 |
| onreset | 当表单被重置 |
事件传播
addEventListener()方法
DOM0级事件监听:只能监听冒泡阶段
oBox.onclick = function(){
};
DOM2级事件监听:
oBox.addEventListener('click',function(){
//这是事件处理函数
},true) ; ture监听捕获节点 false监听冒泡阶段
事件对象
事件处理函数提供一个形式参数,它是一个对象,封装了本次事件的细节这个参数通常用单词event或字母e来表示
oBox.onmousemove = function (e) {
//对象e就是这次事件的‘事件对象’
};
鼠标位置
| 属性 | 属性描述 |
|---|---|
| client(X,Y) | 鼠标指针相对于浏览器的(水平,垂直)坐标 |
| page(X,Y) | 鼠标指针相对于整张网页的(水平,垂直)坐标 |
| offset(X,Y) | 鼠标指针相对于事件元素的(水平,垂直)坐标 |
e.charCode 和e.keyCode 属性
e.charCode属性通常用于onketpress事件中,表示用户输入的字符的‘字符码’
e.keyCode属性通常用于onkeydown事件和onkeyup中,表示用户按下的按键的‘键码’
e.preventDefault()方法:e.preventDefault()方法用来阻止事件产生得'默认动作'
鼠标滚轮事件onmousewheel,它的对象e提供deltaY属性表示鼠标滚动方向,向下滚动时返回正值,向上滚动时返回负值
e.stopPropagation()方法: e.stopPropagation()用来阻止事件继续传播 在一些场合 有必要切断事件继续传播否则会造成页面特效显示出bug
事件委托
批量添加事件监听的性能问题:
每一个事件监听注册都会消耗一定的系统内存,而批量添加事件会导致监听数量太多,内存消耗会非常大
动态绑定事件的问题:
- 新元素必须分别添加事件监听。不能自动获得事件监听
- 大量事件监听、大量事件处理函数都会产生大量消耗内存
什么是事件委托:
利用事件冒泡机制,将后代元素事件委托给祖先元素 事件委托通常要结合使用e.target属性
属性描述 属性描述
target属性 触发此事件的最早元素,即'事件源元素'
currentTarget 事件处理程序附加到的元素
使用事件委托时需要注意的事项
onmouseenter和onmouseover都表示 鼠标进入
区别:onmouseenter不冒泡 , onmouseover冒泡
最内层元素不能再有额外的内层元素
定时器:
setInterval()函数可以重复调用一个函数,在每次调配用之间具有固定的时间间隔
setInterval(function(){
//这个函数将自动被固定间隔时间调用
},2000);
函数的参数:
setInterval()函数可以接收第3、4....个参数。他们将按顺序传入函数
setInterval(function(a,b){
//形式参数a是88 b是66
},2000,88,66);
具名函数也可以传入setInterval
var a = 0;
function fun(){
console.log(++a);
}
setInterval(fun,1000);
清除定时器:
clearInterval()函数可以清除一个定时器
var timer = setInterval(function(){
},2000);
//点击定时器,清除定时
oBtn.onclick = function(){
clearInterval(timer);
}
延时器 :setTimeout()函数可以设置一个延时器,当指定时间到了之后,会执行函数一次,不再重复执行
etTimeout(function (){
//这个函数会在2秒后执行一次
},2000);
clearTimeout()函数可以清除延时器,和clearInterval()非常类似
异步语句:setInterval()和setTimeout()是两个异步语句
异步(asynchronous):不会阻塞CPU继续执行其他语句,当异步完成时会执行‘回调函数’callback
函数节流:
函数节流:一个函数执行一次后,只有大于设定的执行周期后才允许执行第二次
函数节流非常容易实现,只需要借助setTimeout()延时器
公式: var lock = true;
function 需要节流的函数(){
//如果锁是关闭状态,则不执行
if(!lock) return;
//函数核心语句
//关锁
lock = false;
//指定毫秒数后将锁打开
setTimeout(function(){
lock = true;
},2000);
}