JS高级阶段
- 如何创建类和方法
- 了解构造函数,实例对象,对象原型和原型对象
- 了解ES5新增的数组的方法,搜索商品案例,是对数组方法的应用
- 点击发送验证码中改变this指向的方法
- 递归函数
- 正则表达式的应用
JS高级第一天
tab切换
需求:点击测试一,二,三,显示图片一,二,三
使用创建类的方法:
var that;
// 利用构造函数的方法
class Tab {
constructor(id) {
// 构造函数里放的是属性,用于接收参数,返回对象,这里的实参是DOM中的需要添加切换的盒子的id
that = this;
this.main = document.querySelector(id);
// 通过document获取元素,但是这里需要获取的是盒子里的li
// this.lis = document.querySelectorAll('li');
this.lis = this.main.querySelectorAll('li');
// this.sections = document.querySelectorAll('section');
this.sections = this.main.querySelectorAll('section');
// 类的方法需要调用,而构造函数里的内容会自动执行,所以可以在这里调用方法
this.liCli();
}
// 添加方法
liCli() {
// 给每个li添加事件
for (var i = 0; i < this.lis.length; i++) {
// 添加了点击事件之后,里面的功能是切换,所以可以添加到创建的类
// 给li添加属性,记录下标
this.lis[i].index = i;
this.lis[i].onclick = this.tabToggle;
}
}
tabToggle() {
// 需要添加清除类名功能
that.clearClass();
this.classList.add('liactive');
that.sections[this.index].classList.add('conactive');
}
clearClass() {
for (var j = 0; j < that.lis.length; j++) {
that.lis[j].classList.remove('liactive');
that.sections[j].classList.remove('conactive');
}
}
}
var obj = new Tab("#tab");
- this指向类,而类的方法调用方法时,想用的this指向了类的方法,所以此时用了一个笨办法,让that = this,当类里的方法调用另一个方法时,指向问题就明确了
- this.tabToggle而不是this.tabToggle();此处是方法名,如果带括号,就执行了里面的内容
JS高级第二天
无
JS高级第三天
搜索商品
分析功能: 1.打开页面,将所有产品显示到页面中
2.在文本框输入内容, 搜索商品
3.下拉菜单筛选, 显示筛选出来的产品
显示商品
- forEach遍历
// 将data中的数据渲染到界面中
var data = [{
id: 1,
pname: '小米',
price: 3999
}, {
id: 2,
pname: 'oppo',
price: 999
}, {
id: 3,
pname: '荣耀',
price: 1299
}, {
id: 4,
pname: '华为',
price: 1999
},];
// 功能一:将产品信息渲染到页面中
// 获取节点
var tbody = document.querySelector('tbody');
// 遍历数组
// 后面需要用到遍历数组,所以需要封装该函数
showPro(data);
function showPro(arr) {
arr.forEach(function (elm) {
// 页面中生成tr
var tr = document.createElement('tr');
tr.innerHTML = '<th>' + elm.id + '</th>\
<th>'+ elm.pname + '</th>\
<th>'+ elm.price + '</th>';
tbody.appendChild(tr);
});
}
- 插入节点另外一个方法:insertAdjacentElement(‘beforeend’,tr);
tbody.insertAdjacentElement('beforeend', tr);
- 该语法兼容性较差
搜索商品
// 功能二:价格查询,筛选数组
var btn = document.querySelector('.search-price');
// 注册事件
btn.onclick = function () {
// 在此处获取表单内容,一上来就获取,用户还没有输入,内容为空
var lowPrice = document.querySelector('.start').value;
var highPrice = document.querySelector('.end').value;
var arr1 = data.filter(function (elm) {
// 判断条件,返回符合条件的elm
return elm.price > lowPrice && elm.price < highPrice;
})
// 在显示搜索结果前,需要清空tbody内容
tbody.innerHTML = '';
showPro(arr1);
}
- filter遍历
- 获取的表单的值是value
下拉菜单搜索
// 功能三:根据下拉菜单筛选
var sele = document.querySelector('#sele');
// 此时的事件是变化事件
sele.onchange = function () {
// 需要知道选择菜单此时选择的是谁
var pro = sele.value;
// 寻找id== pro的商品,渲染出来
var arr2 = data.filter(function (elm) {
// pro是字符串,三个等号时候要转换成number类型
return elm.id === +pro;
})
// 展示前先清空tbody
tbody.innerHTML = '';
showPro(arr2);
// 问题:如果选“请选择商品名称”,没有符合的内容,页面应该显示所有商品
if (pro == 0) {
showPro(data);
}
}
- 判断select的值与数据中的值是否相等
- filter遍历
补充知识:
<select name="citys">
<option value="1">北京</option>
<option value="2">上海</option>
<option value="3">天津</option>
<option value="4">广州</option>
<option value="5">深圳</option>
</select>
<!--
select 如果没有value值
当option有value值, select使用option的value值
当option没有value值,select使用option的内容作为value值
-->
点击发送验证码
点击按钮之后, 按钮被禁用, 隔几秒, 恢复
- 用到bind()方法
<body>
<input type="button" value="点击发送验证码">
<script>
var btn = document.querySelector('input');
btn.onclick = function () {
this.disabled = true;
// 定时器
window.setTimeout(function () {
this.disabled = false;
}.bind(this), 2000);
//改变this的指向, 在定时器里,this指向window
}
</script>
</body>
- 此时设置的是一次性定时器,因为点击一次就只执行一次,如果是永久性的,还需要清除定时器
闭包练习-下标
var lis = document.querySelectorAll('li');
for (var i = 0; i < lis.length; i++) {
// lis[i].onclick = function () {
// console.log(i);
// }
(function (index) {
// var index = i;
lis[index].onclick = function () {
console.log(index);
}
})(i);
}
- 此方法比较繁琐, 但是也可以实现对应的下标
递归-求阶乘
- 需要两个点: 递归点、出口点
function jc(n) {
if (n == 1) {
return 1;
}
return n * jc(n - 1);
}
jc(3);
console.log(jc(3));
递归-斐波那契数列
- 找递归点, 出口点
- 先看规律, 第n项值=n-1项与n-2项的和
// 1、1、2、3、5、8、13、21...
// fn(n-1) + fn(n-2)
// 递归点:前面n-1项的和
// 出口点: 在1月或者2月的时候的值为1
function fn(n) {
if (n == 1 || n == 2) {
return 1;
}
return fn(n - 1) + fn(n - 2);
}
fn(8);
console.log(fn(8));
JS高级第四天
表单验证
需求:检查用户注册时注册信息格式是否正确,正确的话,提示绿色图标;错误的话显示红色图标;提交注册时候,如果所有验证都正确,可以提交,否则弹窗提示
window.onload = function () {
// 大量验证
// 验证表单
// 失去焦点的时候,验证,
// 如果错误的话,给span添加类名error,span里面有i标签i标签具有类名,还有文字提示
// 如果正确的话,span里面也要添加类名,提示也要有i,i也要有类名,还有文字提示
// 获取元素
var tel = document.querySelector('#tel');
var qq = document.querySelector('#qq');
var nc = document.querySelector('#nc');
var msg = document.querySelector('#msg');
var pwd = document.querySelector('#pwd');
var surepwd = document.querySelector('#surepwd');
var over = document.querySelector('.over');
var inps = document.querySelectorAll('.inp');
// 手机正则
var regtel = /^[1][3|4|5|6|7|8|9][0-9]{9}$/;
// qq正则
var regqq = /^[1-9][0-9]{4,10}$/;
// 昵称正则
var regnc = /^[\u4e00-\u9fa5]{2,6}$/;
// 短信正则
var regmsg = /^[0-9]{4}$/;
// 密码正则
var regpwd = /^[a-z0-9_-]{6,18}$/;
// 注册事件,封装
function jiance(element, reg) {
element.onblur = function () {
// 判断:正确错误
if (reg.test(this.value)) {
this.nextElementSibling.className = 'success';
this.nextElementSibling.innerHTML = '<i class="success_icon"></i>输入正确';
return true;
} else {
this.nextElementSibling.className = 'error';
this.nextElementSibling.innerHTML = '<i class="error_icon"></i>输入错误';
return false;
}
}
}
// 调用函数
jiance(tel, regtel);
jiance(qq, regqq);
jiance(nc, regnc);
jiance(msg, regmsg);
jiance(pwd, regpwd);
surepwd.onblur = function () {
if (this.value == pwd.value && this.value.length > 0) {
this.nextElementSibling.className = 'success';
this.nextElementSibling.innerHTML = '<i class="success_icon"></i>输入正确';
return true;
} else {
this.nextElementSibling.className = 'error';
this.nextElementSibling.innerHTML = '<i class="error_icon"></i>输入错误';
return false;
}
}
// 点击提交
over.onclick = function () {
// 假设值
var flag = true;
// 自动触发事件:元素.事件();
// 遍历inps
for (var i = 0; i < inps.length; i++) {
var result = inps[i].onblur();
if (result == false) {
flag = false;
}
}
// 查看flag
if (flag) {
// 允许
location.href = 'http://www.baidu.com';
} else {
// 不允许
alert('你好好好写,别乱来');
}
}
}
敏感字屏蔽
需求:留言板屏蔽掉某些敏感词
// 获取元素
var txt = document.getElementById('txt');
var btn = document.querySelector('input');
var ul = document.querySelector('ul');
// 添加事件
btn.onclick = function () {
// 创建li
var li = document.createElement('li');
// 追加到页面中
ul.appendChild(li);
// 获取value值
var val = txt.value;
// 替换
val = val.replace(/搞基|gay/gi,'**');
// 追加内容
li.innerHTML = val;
// 清除内容
txt.value = '';
}