1.实现多层深拷贝
递归实现
var obj = { name: "zhangsna", age: 20, gfs: [ { gfname: "lili", hobby: ["篮球", '乒乓球'] }, { gfname: "shasha", hobby: ["篮球", '乒乓球'] }, ] } function deepClone(newObj, oldObj) { // key gfs value = [.....] // newObj {gfs:[hobby:[]]} // deepclone([],[.....]) // for (const key in oldObj) { // 判断是不是数组 if (Array.isArray(oldObj[key])) { newObj[key] = []; deepClone(newObj[key], oldObj[key]); } else if (oldObj[key] instanceof Object) { newObj[key] = {}; deepClone(newObj[key], oldObj[key]); } else { newObj[key] = oldObj[key]; } } return newObj; } // 实现了深拷贝 var newObj = deepClone({}, obj);
2.防止无限制创建计时器
<button id="btn">点我!!</button>
<script>
var num = 10;
var timer = null;
btn.onclick = function () {
// 防止无限次创建计时器
if (!timer) {
timer = setInterval(() => {
num--;
console.log(num);
if(num == 0){
clearInterval(timer);
}
}, 1000);
}
}
// settimeout
// 一般用于性能提升 用于防抖和节流
3.获取验证码
禁用按钮:this.disabled = true;
移除计时器:clearInterval(timer);
<div>
<input type="text" id="ipt">
<button id="btn">获取验证码</button>
</div>
<script>
var timer = null;
btn.onclick = function () {
if (!ipt.value) {
alert("请输入手机号");
}
// 此处正则 不需要掌握 后续课程中会讲解 test()属于正则中的方 返回值是true或false 看是否规则
else if (!(/^1([358][0-9]|4[579]|66|7[0135678]|9[89])[0-9]{8}$/.test(ipt.value))) {
alert("请输入正确手机号");
}
else {
this.disabled = true;
var seconds = 6;
timer = setInterval(() => {
this.textContent = seconds;
seconds--;
if (seconds == -1) {
clearInterval(timer);
this.disabled = false;
this.textContent = "获取验证码";
}
}, 1000);
}
}
</script>
4.元素节点
节点:node 为dom的最小单位
分为: 元素节点 文本节点 属性节点 注释节点
节点属性:nodeValue nodeType nodeName
nodeType( 1 元素节点 2 属性节点 3 文本节点 8 注释节点)
div.childNodes//包含换行
//
var els=div.children;//获取所有子元素
var span=els[0];
// 判断元素类型
span.nodeName
span.tagName
// 获取父节点
span.parentElement
span.parentNode
// 获取兄弟节点
span.previousElementSibling//上一个
span.nextElementSibling//下一个
// 获取的是文本节点
span.previousSibling//上一个
span.nextSibling//下一个
// 移除指定的子元素
// 参数必须为元素节点
div.removeChild(span);
div.remove();
5.删除所有子元素
<div>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
<p>5</p>
</div>
<script>
var div = document.querySelector('div');
// 1.动态的 children
// var ps = div.children;
// for(var i = 0;i < ps.length;i++){
// div.removeChild(ps[i]);
// i--;
// }
// 2.getElementsByTagName() 动态的
// var ps = div.getElementsByTagName("p");
// for (var i = 0; i < ps.length; i++) {
// div.removeChild(ps[i]);
// i--;
// }
// 3 querySelectorAll 静态的
// var ps = div.querySelectorAll("p");
// for (var i = 0; i < ps.length; i++) {
// div.removeChild(ps[i]);
// }
// 4. 能不能删除完?
for(var i = 0;i < 5;i++){
console.log(11111111111111111111111)
//
// Uncaught TypeError: Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'
// 当i=3时 div中已经只剩两个元素
// 而且 removeChild 必须传递 Node 对象
div.removeChild(div.children[i]);
}
</script>
6.关闭广告
var div = document.querySelector('div');
var span = document.querySelector('.s1');
var close = document.querySelector('.close');
var num = 5;
var timer = setInterval(() => {
console.log("======");
num--;
span.innerHTML = `${num}s后自动关闭`;
if (num == 0) {
div.remove();// 移除当前调用remove的元素
clearInterval(timer);// 清除定时器
// clearTimeout(timer);// 清除延时器
}
}, 1000);
close.onclick = function () {
div.remove();// 移除当前调用remove的元素
clearInterval(timer);// 清除定时器
// clearTimeout(timer);// 清除延时器
}
7.全选反选
利用中间变量来改变多选框
var allInput = document.querySelector('h1>input'); var liInputs = document.querySelectorAll('ul input'); allInput.onchange = function () { console.log(this.checked); // 以后使用this之前 一定知道this目前指向的是谁 //此时 是没有效果的因为 this指向window 而window没有 checked属性 所以不会有效果 // liInputs.forEach(function (el) { // console.log("this =",this); // el.checked = this.checked; // }); // 1. // liInputs.forEach((el) => { // el.checked = this.checked; // }) // 2. var that = this; liInputs.forEach(function (el) { el.checked = that.checked; }) // 3. // liInputs.forEach(function(el) { // el.checked = this.checked; // }.bind(this)); } // 作业1: 中断foreach的执行 break 只能中断for循环 // liInputs.forEach(function (el) { // }) for (var i = 0; i < liInputs.length; i++) { var input = liInputs[i]; input.onchange = function () { var isSelect = true; for (var j = 0; j < liInputs.length; j++) { if (liInputs[j].checked == false) { isSelect = false; break; } } allInput.checked = isSelect; } } // function test(obj) { // console.log(obj.name); // console.log(obj.age); // obj.success(10); // } // test({ // name:123, // age:20, // success:function(response){ // console.log("this = ",this);//this指向 当前方法传递的对象 // } // })
利用数组的every方法来判断所有小框是否被选中,从而改变全选框的选中状态
allInput.onchange = function () { var that = this; liInputs.forEach(function (el) { el.checked = that.checked; }) } for (var i = 0; i < liInputs.length; i++) { var input = liInputs[i]; input.onchange = function () { // allInput.checked = Array.from(liInputs).every((el) => el.checked); liInputs = Array.from(liInputs);//转成数组 才可以使用数组的方法 // every 所有条件满足时 返回为true 只要有一个为false 则返回false var result = liInputs.every(function (el) { return el.checked; }) allInput.checked = result; } }
8.多级全选反选
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
<h1><input type="checkbox" name="" id="">全选</h1>
<ul>
<li>
<h2><input type="checkbox">小米</h2>
<ul>
<li>
<input type="checkbox" name="" id="">手机
</li>
<li>
<input type="checkbox" name="" id="">电脑
</li>
<li>
<input type="checkbox" name="" id="">平板
</li>
</ul>
</li>
<li>
<h2><input type="checkbox">超市</h2>
<ul>
<li>
<input type="checkbox" name="" id="">瓶酒
</li>
<li>
<input type="checkbox" name="" id="">饮料
</li>
<li>
<input type="checkbox" name="" id="">矿泉水
</li>
<li>
<input type="checkbox" name="" id="">兽兽叫
</li>
</ul>
</li>
<li>
<h2><input type="checkbox">华为</h2>
<ul>
<li>
<input type="checkbox" name="" id="">电脑
</li>
<li>
<input type="checkbox" name="" id="">平板
</li>
</ul>
</li>
</ul>
</div>
<script>
// 利用了 二维数组 [[],[],[]]
// 1.找到全选框
var allipt = document.querySelector('h1 input');
// 2.找商店
var shopipts = document.querySelectorAll("h2 input");
shopipts = Array.from(shopipts);
// 3.所有商品
var allGoodIpts = [];
for (var i = 0; i < shopipts.length; i++) {
var ipt = shopipts[i];
// parentElement 找父级节点
var li = ipt.parentElement.parentElement;
var goodipts = li.querySelectorAll("ul>li>input");
goodipts = Array.from(goodipts);
allGoodIpts.push(goodipts);
}
console.log(allGoodIpts);
// 4.点击全选
allipt.onchange = function () {
shopipts.forEach((el) => {
el.checked = this.checked;
});
allGoodIpts.forEach((arr) => {
arr.forEach((el) => {
el.checked = this.checked;
})
});
}
// 5.商店的选中
shopipts.forEach(function (el, index) {
// el 小米 超市 华为 input
el.onchange = function () {
console.log(index);// 可以通过index找到 大数组中对应商店商品的小数组
var smallArray = allGoodIpts[index];
smallArray.forEach((goodIpt) => {
goodIpt.checked = this.checked;
});
bigSelect();
}
})
// 6.商品的选中
// smallArray [],[],[]
allGoodIpts.forEach(function (smallArray, index) {
smallArray.forEach(function (el) {
// 确定所有商品中的商品是否全部选中 、控制对应商店的input选中与否
el.onchange = function () {
shopipts[index].checked = smallArray.every((el) => el.checked);
bigSelect();
}
})
})
// 全选的控制
function bigSelect() {
// 可以根据商店的选中与否 控制全选
allipt.checked = shopipts.every((el) => el.checked);
}
</script>
</body>
</html>