思路提升

    技术2026-01-02  1

    写代码需要思路

    定义一个变量来存状态排他思想(去掉其他样式)定义变量,循环判断里面条件成立把for循环的i值赋值给自定义属性值,以便后面再获取自定义属性的值,然后让当前的样式发生变化购物车里面的事件委托形式表格中使用事件委托来实现功能把元素的位置以对象的形式存在数组中,后面再用位置来解析数组集合定时器清除时,定时器的名字需要定义一个特定的值面向对象中this的使用:声明一个变量存放

    定义一个变量来存状态

    <!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> </head> <body> <button id="btn">开关灯</button> <script> var btn = document.getElementById('btn'); // 先定义一个变量,来通过它来改变开关灯的状态 var flag = 0; btn.onclick = function () { // 如果刚开始flag是0 则背景变为黑色 if (flag == 0) { document.body.style.backgroundColor = 'black'; // 之后再把flag变为1,当下次点击的时候执行条件不成立,执行else后面的语句 flag = 1; } else { document.body.style.backgroundColor = '#fff'; // 再把flag改为0 当下次点击的时候条件成立,执行if后面的语句 flag = 0; } } </script> </body> </html>

    排他思想(去掉其他样式)

    <!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> <style> button { /* 当元素获得焦点的时候,焦点框为0 */ outline: 0; /* 去掉默认样式 */ border: 0; } </style> </head> <body> <button>按钮1</button> <button>按钮2</button> <button>按钮3</button> <button>按钮4</button> <button>按钮5</button> <script> // 1. 获取所有按钮元素 var btns = document.getElementsByTagName('button'); // console.log(btns) // btns得到的是伪数组 里面的每一个元素 btns[i] for (var i = 0; i < btns.length; i++) { btns[i].onclick = function () { // (1) 我们先把所有的按钮背景颜色去掉 干掉所有人 for (var i = 0; i < btns.length; i++) { btns[i].style.backgroundColor = ''; } // (2) 然后才让当前的元素背景颜色为pink 留下我自己 this.style.backgroundColor = 'skyblue'; } } //2. 首先先排除其他人,然后才设置自己的样式 这种排除其他人的思想我们成为排他思想 </script> </body> </html>

    定义变量,循环判断里面条件成立

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> <style> * { padding: 0; margin: 0; } .wrap { width: 300px; margin: 100px auto 0; } table { border-collapse: collapse; border-spacing: 0; border: 1px solid #c0c0c0; width: 300px; } th, td { border: 1px solid #d0d0d0; color: #404060; padding: 10px; } th { background-color: #09c; font: bold 16px "微软雅黑"; color: #fff; } td { font: 14px "微软雅黑"; } tbody tr { background-color: #f0f0f0; } tbody tr:hover { cursor: pointer; background-color: #fafafa; } </style> </head> <body> <div class="wrap"> <table> <thead> <tr> <th> <input type="checkbox" id="thAll" /> </th> <th>商品</th> <th>价钱</th> </tr> </thead> <tbody id="tb"> <tr> <td> <input type="checkbox" /> </td> <td>iPhone18</td> <td>8000</td> </tr> <tr> <td> <input type="checkbox" /> </td> <td>iPad Pro</td> <td>5000</td> </tr> <tr> <td> <input type="checkbox" /> </td> <td>iPad Air</td> <td>3000</td> </tr> <tr> <td> <input type="checkbox" /> </td> <td>Apple Watch</td> <td>2000</td> </tr> </tbody> </table> </div> <script> // 1. 全选和取消全选做法: 让下面所有复选框的checked属性(选中状态) 跟随 全选按钮即可 // 获取元素 var thAll = document.getElementById('thAll'); // 全选按钮 var tdIpts = document.getElementById('tb').getElementsByTagName('input'); // 下面所有的复选框 // 注册事件 thAll.onclick = function () { // this.checked 它可以得到当前复选框的选中状态如果是true 就是选中,如果是false 就是未选中 // console.log(this.checked); for (var i = 0; i < tdIpts.length; i++) { tdIpts[i].checked = this.checked; } } // 2. 下面复选框需要全部选中, 上面全选才能选中做法: 给下面所有复选框绑定点击事件, //每次点击,都要循环查看下面所有的复选框是否有没选中的,如果有一个没选中的, 上面全选就不选中。 for (var i = 0; i < tdIpts.length; i++) { tdIpts[i].onclick = function () { // flag 控制全选按钮是否选中 var flag = true; // 每次点击下面的复选框都要循环检查下面的小按钮是否全被选中 for (var i = 0; i < tdIpts.length; i++) { // 循环判断 如果有一个为false,则下面条件成立,则让flag为false if (!tdIpts[i].checked) { flag = false; break; // 退出for循环 这样可以提高执行效率 //因为只要有一个没有选中,剩下的就无需循环判断了 } } thAll.checked = flag; } } </script> </body> </html>

    把for循环的i值赋值给自定义属性值,以便后面再获取自定义属性的值,然后让当前的样式发生变化

    <!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> <style> * { margin: 0; padding: 0; box-sizing: border-box; } li { list-style-type: none; } .tab { width: 978px; margin: 100px auto; } .tab_list { height: 39px; border: 1px solid #ccc; background-color: #f1f1f1; } .tab_list li { float: left; height: 39px; line-height: 39px; padding: 0 20px; text-align: center; cursor: pointer; } .tab_list .current { background-color: #c81623; color: #fff; } .item_info { padding: 20px 0 0 20px; } .item { display: none; width: 978px; height: 400px; border: 1px solid #ccc; } </style> </head> <body> <div class="tab"> <div class="tab_list"> <ul> <li class="current">商品介绍</li> <li>规格与包装</li> <li>售后保障</li> <li>商品评价(50000</li> <li>手机社区</li> </ul> </div> <div class="tab_con"> <div class="item" style="display: block;"> 商品介绍模块内容 </div> <div class="item"> 规格与包装模块内容 </div> <div class="item"> 售后保障模块内容 </div> <div class="item"> 商品评价(50000)模块内容 </div> <div class="item"> 手机社区模块内容 </div> </div> </div> <script> // 获取元素 var tab_list = document.querySelector('.tab_list'); var lis = tab_list.querySelectorAll('li'); var items = document.querySelectorAll('.item'); // for循环绑定点击事件 for (var i = 0; i < lis.length; i++) { // 开始给5个小li 设置索引号 // 自定义一个属性 把遍历的 i 值赋值给这个属性值 lis[i].setAttribute('index', i); lis[i].onclick = function () { // 1. 上的模块选项卡,点击某一个,当前这一个底色会是红色,其余不变(排他思想) 修改类名的方式 // 干掉所有人 其余的li清除 class 这个类 for (var i = 0; i < lis.length; i++) { lis[i].className = ''; } // 留下我自己 this.className = 'current'; // 2. 下面的显示内容模块 获取自定义属性的索引号 var index = this.getAttribute('index'); console.log(index); // 干掉所有人 让其余的item 这些div 隐藏 for (var i = 0; i < items.length; i++) { items[i].style.display = 'none'; } // 留下我自己 让对应的item 显示出来 items[index].style.display = 'block'; } } </script> </body> </html>

    购物车里面的事件委托形式

    包括switch case 的使用

    // 渲染页面 let shopS = document.querySelector('.shopS'); let cartall = document.querySelector('.cartall'); let savetall = document.querySelector('.savetall'); //数据库数据,数组形式的lists render(lists); function render(goodLists) { // 渲染数据 shopS.innerHTML = goodLists.map((item) => { let saveTotal = item.num * (item.oriPrice - item.nowPrice); return ` <tr class="shopList" idx="${item.id}"> <td class="imgTd"> <img class="shops" src="${item.img}" alt="" srcset=""> </td> <td class="titleTd"> <h6>${item.title}</h6> <span>ID:#${item.id}</span> <span>Size:${item.size}</span> </td> <td class="Son2"> <span class="reduce">-</span> <input type="text" disabled value="${item.num}" class="count"> <span class="add">+</span> </td> <td class="Son3"> <del class="oriPrice">${item.oriPrice} py6</del> <b class="nowPrice">${item.nowPrice} py6</b> </td> <td class="Son4"> <span class="priceAll">${(item.nowPrice * item.num).toFixed(2)} py6</span> <span class="saveAll">You save ${saveTotal.toFixed(2)} py6</span> </td> <td class="Son5"> <img class="del" src="../images/del.png" alt=""> </td> </tr>` }).join('') // 计算总价 let carTall = goodLists.reduce((pre, cur, index) => { return pre + cur.nowPrice * cur.num; }, 0) cartall.firstElementChild.innerHTML = carTall.toFixed(2) + ' py6.'; // 计算折扣总价 let saveTall = goodLists.reduce((pre, cur, index) => { return pre + cur.num * (cur.oriPrice - cur.nowPrice) }, 0) savetall.innerHTML = `Your Total Saving:${saveTall.toFixed(2)} py6.`; } // 定义变量来接收 获取点击元素的父元素,和点击的商品id let $tr, $id; // 事件委托的形式绑定点击事件 let shop = document.querySelector('.shop'); shop.onclick = (e) => { switch (e.target.className) { // 点击减数量 case 'reduce': // 获取点击这个元素的父元素 $tr = e.target.parentNode.parentNode; // 拿到父元素中存储的idx属性 $id = $tr.getAttribute('idx'); // 通过这个idx属性去 数据库中匹配数据,改数据 lists.forEach(item => { // 如果 获取的id 和数组中对象对应的id一样的时候,更改这个条数据 num值 // 并且数量不等于 1,只有大于1才能见减数量 if (item.id == $id && item.num > 1) { item.num -= 1; // 数据改变之后重新渲染页面 render(lists); } }) break // 点击加数量 case 'add': $tr = e.target.parentNode.parentNode; $id = $tr.getAttribute('idx'); lists.forEach(item => { if (item.id == $id) { item.num += 1; render(lists); } }) break // 点击删除此商品 case 'del': let res = confirm('你确定删除吗'); if (res) { $tr = e.target.parentNode.parentNode; $id = $tr.getAttribute('idx'); lists.forEach((item, index, array) => { if (item.id == $id) { // 把当前点击的这个商品从数组中删除 array.splice(index, 1) render(lists); } }) } break } }

    表格中使用事件委托来实现功能

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> table { width: 100%; border: 1px solid #ccc; border-collapse: collapse; border-spacing: 0px; } table td { border: 1px solid #ccc; height: 30px; } </style> </head> <body> <div class="box"> <h1>的使用创建dom节点动态生成表格</h1> <label for="">行:</label> <input type="text" id="row"> <label for="">列:</label> <input type="text" id="col"> <input type="button" id="btn" value="生成"> <div id="output"> <!-- <table> <tbody> <tr> <td>浮动法</td> </tr> </tbody> </table> --> </div> </div> <script> /* 【1】先获取页面中你需要用到的元素 【2】点击生成的时候根据行和列数生成 表格 【2】拿到输入框的值 【2】根据值循环生成表格 【3】点击表格中的 复制 和删除按钮 复制:复制整行 添加 tbody 删除:把整行从tbody里面删除 */ // 【1】先获取页面中你需要用到的元素 var output = document.querySelector('#output'); var btn = document.querySelector('#btn'); var row = document.querySelector('#row'); var col = document.querySelector('#col'); // 生成table 和tbody var table = document.createElement('table'); var tbody = document.createElement('tbody'); // 把tbody放入table中 table.appendChild(tbody); // 【2】点击生成的时候根据行和列数生成 表格 btn.onclick = function () { // 1】拿到输入框的值 var _row = row.value; var _col = col.value; renderTable(_row, _col); // 需要点击复制和删除按钮 ,必须保证页面中有这个两个按钮 // 等页面渲染完成之后才能执行这个操作 // 在获取元素 绑定事件 } // 事件委托:给父元素output元素绑定事件 output.onclick = function (e) { // 判断点击的是复制按钮,实现克隆元素 if (e.target.className === 'copy') { var newTr = e.target.parentNode.parentNode.cloneNode(true); tbody.appendChild(newTr) } // 判断点击的时候删除按钮 实现删除元素 if (e.target.className === 'delete') { // e.target就是鼠标点击的元素 e.target.parentNode.parentNode.remove(); } } function renderTable(_row, _col) { // 2】循环生成行和列 for (var i = 0; i < _row; i++) { var tr = document.createElement('tr'); // 循环生成列数 for (var j = 0; j < _col; j++) { var td = document.createElement('td'); td.innerHTML = '单元格' + i + j; tr.appendChild(td); } // 多一列出来 存放删除和赋值按钮 var _td = document.createElement('td'); var copyEle = document.createElement('button'); // 给元素绑定给一个id属性 copyEle.className = 'copy'; copyEle.innerHTML = '复制'; var deleteEle = document.createElement('button'); deleteEle.className = 'delete'; deleteEle.innerHTML = '删除' _td.appendChild(copyEle); _td.appendChild(deleteEle); // 把这个的多出来的列也放入 tr tr.appendChild(_td) // 把生成的tr放入tbody中 tbody.appendChild(tr); } // 把table放入output里面 output.appendChild(table); } </script> </body> </html>

    把元素的位置以对象的形式存在数组中,后面再用位置来解析数组集合

    <!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> <style> html, body { overflow: hidden; } body, div, h2, p { margin: 0; padding: 0; } body { color: #fff; background: #000; font: 12px/2 Arial; } p { padding: 0 10px; margin-top: 10px; } span { color: #ff0; padding-left: 5px; } #box { position: absolute; width: 300px; height: 150px; background: #333; border: 2px solid #ccc; left: 20px; top: 20px; } #box h2 { height: 25px; line-height: 25px; cursor: move; /*手型:移动*/ background: #222; border-bottom: 2px solid #ccc; text-align: right; padding: 0 10px; } #box h2 a { color: #fff; font: 12px/25px Arial; text-decoration: none; outline: none; } </style> </head> <body> <div id="box"> <h2><a href="#">点击回放拖动轨迹</a></h2> <p><strong>Drag:</strong><span>false</span></p> <p><strong>offsetLeft:</strong><span>0</span></p> <p><strong>offsetTop:</strong><span>0</span></p> </div> <script> window.onload = function () { /* 两个阶段: 【1】拖拽阶段 1.在元素上按下 mousedown,同时给document添加 mousemove 事件 记录光标在元素上的位置 2.但在元素上鼠标抬起 mouseup,解除 document的 mousemove 事件 3.mousemove过程,将盒子的 左边和上边的位置 以对象的形式存在数组中 【2】回放阶段 1.点击回放的时候,把存入数组中的 数据一次取出添加给 元素 */ var box = document.getElementById('box'); // 获取box孩子的第1个 var h2 = box.children[0]; // 获取box孩子的第2个的第1个元素 var dragSpan = box.children[1].children[1]; // 获取box孩子的第3个的第1个元素 var leftSpan = box.children[2].children[1]; // 获取box孩子的第4个的第1个元素 var topSpan = box.children[3].children[1]; // 获取元素点击回放元素 var links = h2.children[0]; // 定义一个空数组,存后面位置数据的集合 var arr = []; // 给h2绑定鼠标按下事件 h2.onmousedown = function (e) { // console.log(1); // 定义一个对象 // var obj = {}; // // 把box第一次的位置获取到 就是跟浏览器最左侧的距离和最上面的距离 赋值给对象 给 x y 属性 // obj.x = box.offsetLeft; // obj.y = box.offsetTop; // console.log(obj.x) // // 然后把点击的时候第一次的位置的 left和top值 添加数组里面,存放起来 // arr.push(obj); // console.log(arr) // 获取点击时候,光标在元素上的位置 var ox = e.offsetX; var oy = e.offsetY; dragSpan.innerHTML = 'true'; // 鼠标移动事件 让盒子随鼠标一起运动 document.onmousemove = function (evt) { // 获取 鼠标在可视窗口的位置 减去 光标在元素的位置 赋值给元素的left和top值 box.style.left = evt.clientX - ox + 'px' box.style.top = evt.clientY - oy + 'px'; // 把位置的值 显示在页面中 leftSpan.innerHTML = evt.clientX - ox; topSpan.innerHTML = evt.clientY - oy; // 再定义一个对象 把left和top值存起来 var obj = {}; obj.x = evt.clientX - ox; obj.y = evt.clientY - oy; // 把位置存到数组中 arr.push(obj); // console.log(arr) } } // 鼠标抬起事件 document.onmouseup = function () { // 清除事件和改变内容 document.onmousemove = null; dragSpan.innerHTML = 'false' } // 点击事件 links.onclick = function () { // 清除定时器,定时器名字是唯一的,不然清除不掉之前的定时器 clearInterval(links.timer); var i = 0; // 定时器名字尽量是唯一的 links.timer = setInterval(function () { // 当点击之后 把数组中的值再赋值给 left和top值 box.style.left = arr[i].x + 'px'; box.style.top = arr[i].y + 'px'; // console.log(arr[i].x) leftSpan.innerHTML = arr[i].x; topSpan.innerHTML = arr[i].y; i++; // 判断当数组里面的值赋值完之后 清除定时器 在清空数组中的值 if (i === arr.length) { clearInterval(links.timer); arr = []; } }, 10) } } </script> </body> </html>

    定时器清除时,定时器的名字需要定义一个特定的值

    主要是注意那个清除定时器的那个定时器的名字

    /* 运动函数: 有3个参数 参数1:dom元素 参加动画元素 参数2:一个对象,这个元素什么属性参加动画 参数3:一个回调函数 */ function move(ele, obj, callback) { // 用于定义一个定时器的个数 为0 let timerLen = 0; // 遍历obj对象中的多个属性 for (let key in obj) { // 定时器个数++ timerLen++ let speed; /* let timer = 定时器 不能定义变量来接收定时器 如果使用变量的时候,点击的时候会创建一个函数地址 变量在函数中是属于局部作用域, 下一次点击的时候不能获取上一次点击时候创建的变量 clearInterval(timer) 清除的是当前timer的值,当前的timer = undefined 把定时器 给到元素的属性中 元素是一个dom 也是一个对象,以地址的形式 当第一个点击的时候 给dom对象对象添加了属性, 下一次点击的时候是能获取 上一次给dom添加的属性 */ // 清除定时器(当点击多次时,需要先清除上一次的定时器) clearInterval(ele[key]) // 给这个对象添加一个 left 属性,属性值为 一个定时器的空间地址 ele[key] = setInterval(() => { let style; // 0-1 *100 == 0-100 0.1*100 = 10 if (key === 'opacity') { style = getStyle(ele, key) * 100; } else { style = parseInt(getStyle(ele, key)); } // 0 - 4 = -4/5 = -0.8 向上取整 = 0 speed = (obj[key] - style) / 5; // 如果计算出来的 speed 大于0 向上取整,如果小于0就向下取整 speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed); style = style + speed; if (key === 'opacity') { ele.style[key] = style / 100; } else { ele.style[key] = style + 'px'; } // 如果先执行回调函数 再给 元素设置 样式,会先把回调函数中的 // 所有 代码执行完成之后再执行后面代码 if (style === obj[key]) { clearInterval(ele[key]); timerLen--; if (timerLen === 0) { // 短路运算 如果有callback 就执行callback,没有就不执行 callback && callback(); } } // 当时间 为60的时候,30次 1800毫秒 才能把内层的定时器执行完成 // 外层的定时器 是1300毫秒执行一次,会造成的问题就是 内层的定时器还没有执行完成 外层定时器有重新执行了 }, 30) } }

    面向对象中this的使用:声明一个变量存放

    那下面以一个简单案例 选项卡来说:

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <div class="container"> <div class="control"> <button>选项1</button> <button>选项2</button> <button>选项3</button> </div> <div class="content"> <div class="box">内容1</div> <div class="box">内容2</div> <div class="box">内容3</div> </div> </div> <script> // 重点是 var self = this 这个地方 //OOA面向对象分析 > OOD面向对象设计 > OOP 面向对象编程 // 分析哪些数据 ,方法功能, // OO : 面向对象; // OOA : 面向对象分析; // OOD : 面向对象设计; // function Table(){ // // this.btns // // this.cont // // 索引 // // this.index; // } // // 事件绑定功能; // Table.prototype.bindEvent = function(){ // } // // 切换内容功能; // Table.prototype.changeTable = function(){ // } // OOP : 面向对象编程; // 1. 如果数据在后面原型对象之中需要应用; // 那么我就要把这个数据放在this之中; // 这里要有复用思想 ; // 2. 所有的this指向都要指向实例对象; function Table(btns_sele, contents) { this.btns = document.querySelectorAll(btns_sele) this.cont = document.querySelectorAll(contents) //存放数据 索引号 this.index = 0 // 先调用第一次 改变内容方法 this.changeTable() // 调用绑定事件 this.bindEvent() } // 绑定事件 Table.prototype.bindEvent = function () { // 把实例对象中的this保存起来 var self = this for (let i = 0; i < self.btns.length; i++) { // self.btns[i].index = i //当for循环里面用var时 self.btns[i].onclick = function () { // console.log(this) // 把当前的索引号给到实例对象中的index self.index = i // self.index = this.index //当for循环里面用var时 // console.log(self.index) // 当索引改变后 再去调用函数 self.changeTable() } } } // 改变内容 Table.prototype.changeTable = function () { // 把实例对象中的this保存起来 var self = this // 排他思想 for (let i = 0; i < self.cont.length; i++) { self.cont[i].style.display = "none" } // 让当前样式改为block self.cont[self.index].style.display = "block" } // new 实例 var table = new Table(".control button", ".box") </script> </body> </html>
    Processed: 0.010, SQL: 10