DOM节点
查找节点
父节点
通过.parentNode属性可以获得某个元素的父节点,并对其进行操作。例如,隐藏.son元素的父节点。
<div class="father"><div class="son">儿子</div></div><script>let son = document.querySelector('.son')console.log(son.parentNode);son.parentNode.style.display = 'none'</script>
子节点
.children属性用来获取元素的所有子元素节点,并可通过循环遍历对子节点进行操作,如给所有
- 元素设置颜色。.childNodes则包含了元素的所有子节点,包括文本节点和注释节点等。
-
<button>点击</button><ul><li>我是孩子</li><li>我是孩子</li><li>我是孩子</li><li>我是孩子</li><li>我是孩子</li><li>我是孩子</li></ul><script>let btn = document.querySelector('button')let ul = document.querySelector('ul')btn.addEventListener('click',function(){for (let i = 0; i < ul.children.length; i++){ul.children[i].style.color = 'red'}})console.log(ul.childNodes);</script>
兄弟节点
兄弟节点:
.nextElementSibling和.previousElementSibling分别用于获取元素的下一个和上一个兄弟元素节点,可用于相邻元素之间的样式或其他属性操作。<button>点击</button><ul><li>1</li><li class="two">1</li><li>1</li><li>1</li></ul><script>let btn = document.querySelector('button')let two = document.querySelector('.two')btn.addEventListener('click', function(){two.style.color = 'red'two.nextElementSibling.style.color = 'blue'two.previousElementSibling.style.color = 'yellow'})</script>
节点操作
追加节点
使用document.createElement()创建新节点,设置其内容,然后通过.insertBefore()方法将新节点插入到指定位置之前。另外,也可以使用.appendChild()方法将新节点追加到元素末尾。
<ul><li>Zero</li></ul><script>let ul = document.querySelector('ul')let li = document.createElement('li')li.innerHTML = 'colors'ul.insertBefore(li, ul.children[0])// li.innerHTML = 'z'// ul.appendChild(li)</script>
克隆节点
使用.cloneNode(true)方法复制一个元素及其所有后代元素,复制后的节点与原节点结构完全一致。可以将克隆后的节点插入到文档的任何位置。
<ul><li>内容</li></ul><script>let ul = document.querySelector('ul')let newul = ul.cloneNode(true)document.body.appendChild(newul)</script>
删除节点
通过.removeChild()方法从父节点中删除指定的子节点。例如,点击按钮时,删除
- 中的第一个子节点
- 。
<button>点击</button> <ul><li>11111111</li><li>11111111</li><li>11111111</li><li>11111111</li> </ul> <script>let btn = document.querySelector('button')let ul = document.querySelector('ul')btn.addEventListener('click',function(){ul.removeChild(ul.children[0])}) </script>
案例
微博案例
一个简单的微博发布及内容展示页面。页面主要分为两部分:微博发布控件区和微博内容列表区。
微博发布控件区包含头像、文本输入框、字符计数器和“发布”按钮。其中文本输入框有字符计数功能,当用户输入内容时,实时更新字符计数。发布按钮在点击时会检查输入内容是否为空,若为空则提示用户,否则将生成一条新的微博条目并插入到内容列表区顶部。
内容列表区是一个动态渲染的无序列表(ul),每条微博条目包括用户头像、用户名、发布时间以及微博内容。此外,每个微博条目还配备了一个删除按钮(X),点击后可删除对应的微博条目。
在脚本部分,定义了一个数据数组,存储了多个用户的昵称和头像地址,每次发布新微博时,会随机选取一个用户信息进行展示。发布按钮的点击事件处理程序会创建一个新的li元素,并填充对应的数据,随后将其插入到内容列表的顶部。同时,为新创建的微博条目的删除按钮绑定点击事件,以便用户删除相应的微博内容。
整体而言,这个案例演示了如何通过JavaScript动态操作DOM元素实现一个基本的微博发布和内容展示功能,并利用事件监听来响应用户交互行为。
<!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><style>* {margin: 0;padding: 0;}ul {list-style: none;}.w {width: 900px;margin: 0 auto;}.controls textarea {width: 878px;height: 100px;resize: none;border-radius: 10px;outline: none;padding-left: 20px;padding-top: 10px;font-size: 18px;}.controls {overflow: hidden;}.controls div {float: right;}.controls div span {color: #666;}.controls div .useCount {color: red;}.controls div button {width: 100px;outline: none;border: none;background-color: rbg(0, 132, 255);height: 30px;cursor: pointer;columns: #fff;font: bold 14px '宋体';transition: all 0.5s;}.controls div button :hover {background: rgb(0, 255, 255);}.controls div button :disabled {background: rgba(0, 255, 255, 0.5);}.contentList li {padding: 20px 0;border-bottom: 1px dashed #ccc;position: relative;}.contentList .info {position: relative;}.contentList li .info span {position: absolute;top: 15px;left: 100px;font: bold 16px '宋体';}.contentList li .info p {position: absolute;top: 40px;left: 100px;color: #aaa;font-size: 12px;}.contentList img {width: 80px;border-radius: 50%;}.contentList li .content {padding-left: 100px;color: #666;word-break: break-all;}.contentList li .the_del {position: absolute;right: 0;top: 0;font-size: 28px;cursor: pointer;}</style> </head><body><div class="w"><div class="controls"><img src="../../resources/image/bilibili/bilibanner.png" alt="" height="100px"><textarea id="area" placeholder="说点什么把..." name="" id="" cols="30" rows="10" maxlength="200"></textarea><div><span class="useCount">0</span><span>/</span><span>200</span><button id="send">发布</button></div></div><div class="contentList"><ul id="list"></ul></div></div><li hidden><div class="info"><img class="userpic" src="../../resources/image/1.png" alt=""><span class="username">可莉</span><p class="send-time">发布于</p></div><div class="content">111</div><span class="the_del">X</span></li><script>// 数据let dataArr = [{ uname: '可莉', imgSrc: '../../resources/image/1.png' },{ uname: '可莉', imgSrc: '../../resources/image/2.png' },{ uname: '霄宫', imgSrc: '../../resources/image/3.png' },{ uname: '刻晴', imgSrc: '../../resources/image/4.png' },{ uname: '胡桃', imgSrc: '../../resources/image/5.png' },{ uname: '胡桃', imgSrc: '../../resources/image/6.png' },{ uname: '胡桃', imgSrc: '../../resources/image/7.png' },]// 文本域let textarea = document.querySelector('#area')let useCount = document.querySelector('.useCount')// 发布按钮let send = document.querySelector('#send')// ullet ul = document.querySelector('#list')function getRandomIntInclusive(min, max) {min = Math.ceil(min);max = Math.floor(max);return Math.floor(Math.random() * (max - min + 1)) + min; //含最大值,含最小值}// 1.检测用户输入长度area.addEventListener('input', function () {useCount.innerHTML = textarea.value.length})// 2.输入内容不能为空send.addEventListener('click', function () {if (textarea.value.trim() === '') {textarea.value = ''useCount.innerHTML = 0return alert('内容不为空')}let random = getRandomIntInclusive(0, dataArr.length - 1)// 3.新增留言let li = document.createElement('li')li.innerHTML = `<div class="info"><img class="userpic" src=${dataArr[random].imgSrc} alt=""><span class="username">${dataArr[random].uname}</span><p class="send-time">发布于${new Date().toLocaleString()}</p></div><div class="content">${textarea.value}</div><span class="the_del">X</span>`// 4.删除留言// 删除留言 放到追加的前面,这样创建元素的同时顺便绑定了时间// 使用li.querySelector('.the_del')let del = li.querySelector('.the_del')del.addEventListener('click', function () {ul.removeChild(li)})ul.insertBefore(li, ul.children[0])// 5.重置文本域textarea.value = ''useCount.innerHTML = 0})</script> </body></html>
购物车
一个购物车界面,其中包括商品列表和底部控制栏两个主要部分。商品列表是一个表格结构,列出了所购商品的信息,如商品图片、名称、单价、数量调整(增加、减少按钮及输入框)、单个商品的小计金额以及删除按钮。底部控制栏提供了全选、删除所有商品、清理购物车和去结算四个功能,同时显示已选择商品总数和总价格。
JavaScript部分实现了以下功能:
商品数量增减:点击商品行内的“+”、“-”按钮时,可以相应地增加或减少商品数量,并实时更新该商品的小计金额;当数量减少到1时,“-”按钮禁用。
商品删除:点击商品行末尾的“删除”链接,会从购物车中移除对应的整行商品,并重新计算购物车总价和商品总数。
全选与反选:点击全选复选框时,会同步所有商品行的复选框状态,并且全选状态下文字显示为“取消”,非全选时显示为“全选”。
实时统计:result()函数用于在任何数量更改或商品删除操作后重新计算购物车中所有商品的总金额和已选择商品的总数量。
控制栏中的功能链接目前仅绑定了事件监听器但未实现具体功能,实际开发中需要补充这些链接对应的处理逻辑,比如删除所有商品和清理购物车的功能实现等。
整体来看,这是一个基础的购物车页面框架,具备商品管理、数量调整、全选功能以及总价统计等常见功能。
<!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><style>* {margin: 0;padding: 0;}ul {list-style: none;}a {text-decoration: none;color: #666;}body {background: #fff;color: #666;font-size: 14px;}input {outline: none;}.clearfix::before,.clearfix::after {content: '';display: block;clear: both;}.clearfix {*zoom: 1}table {width: 800px;margin: 0 auto;border-collapse: collapse;}th,td {border: none;text-align: center;border-bottom: 1px dashed #ccc;}input[type='checkbox'] {width: 13px;height: 13px;}tbody p {position: relative;bottom: 10px;}tbody .add,tbody .reduce {float: left;width: 22px;height: 22px;border: 1px solid #ccc;text-align: center;background: none;outline: none;cursor: pointer;}tbody input[type='text'] {width: 50px;float: left;height: 18px;text-align: center;}tbody.count-c {width: 98px;margin: 0 auto;}button[disabled] {color: #ddd;cursor: not-allowed;}tbody tr:hover {background: #eee;}tbody tr.active {background: rgba(241, 209, 149, 0.945);}.controls {width: 790px;margin: 10px auto;border: 1px solid #ccc;line-height: 50px;padding-left: 10px;position: relative;}.controls .del-all,.controls .clear {float: left;margin-right: 50px;}.controls p {float: right;margin-right: 100px;}.controls span {color: red;}.controls .pay {position: absolute;right: 0;width: 80px;height: 54px;background: red;font: bold 20px/54px '宋体';color: #fff;}.controls .total-price {font-weight: bold;}</style> </head><body><div class="car"><table><therd><th><input type="checkbox" id="all"><span id="quan">全选</span></th><th>商品</th><th>单价</th><th>商品数量</th><th>小计</th><th>操作</th></therd><tbody id="carBody"><tr><td><input type="checkbox" class="s_ck" readonly></td><td><img src="../../resources/image/1.png" alt=""><p>可莉</p></td><td class="price">6¥</td><td><div class="count-c clearfix"><button class="reduce" disabled>-</button><input type="text" value="1"><button class="add">+</button></div></td><td class="total">6¥</td><td><a href="jabascript:" class="del">删除</a></td></tr><tr><td><input type="checkbox" class="s_ck" readonly></td><td><img src="../../resources/image/3.png" alt=""><p>霄宫</p></td><td class="price">128¥</td><td><div class="count-c clearfix"><button class="reduce" disabled>-</button><input type="text" value="1"><button class="add">+</button></div></td><td class="total">128¥</td><td><a href="jabascript:" class="del">删除</a></td><tr><td><input type="checkbox" class="s_ck" readonly></td><td><img src="../../resources/image/4.png" alt=""><p>刻晴</p></td><td class="price">328¥</td><td><div class="count-c clearfix"><button class="reduce" disabled>-</button><input type="text" value="1"><button class="add">+</button></div></td><td class="total">328¥</td><td><a href="jabascript:" class="del">删除</a></td></tr><tr><td><input type="checkbox" class="s_ck" readonly></td><td><img src="../../resources/image/6.png" alt=""><p>胡桃</p></td><td class="price">648¥</td><td><div class="count-c clearfix"><button class="reduce" disabled>-</button><input type="text" value="1"><button class="add">+</button></div></td><td class="total">648¥</td><td><a href="jabascript:" class="del">删除</a></td></tr></tr></tbody></table><div class="controls clearfix"><a href="javascript:" class="del-all">删除所有商品</a><a href="javascript:" class="clear">清理购物车</a><a href="javascript:" class="pay">去结算</a><p>已选中<span id="totalCount">0</span>件商品;总价:<span id="totalPrice" class="total-price">0</span></p></div></div><script>let adds = document.querySelectorAll('.add')let reduces = document.querySelectorAll('.reduce')let dels = document.querySelectorAll('.del')let inputs = document.querySelectorAll('.count-c input')let prices = document.querySelectorAll('.price')let totals = document.querySelectorAll('.total')let totalResult = document.querySelector('.total-price')let totalCount = document.querySelector('#totalCount')let carBody = document.querySelector('#carBody')result()for (let i = 0; i < adds.length; i++) {totals[i].innerHTML = prices[i].innerHTML// 加adds[i].addEventListener('click', function () {inputs[i].value++reduces[i].disabled = false// 计算小计totals[i].innerHTML = parseInt(prices[i].innerHTML) * inputs[i].value + '¥'result()})//减reduces[i].addEventListener('click', function () {inputs[i].value--if (inputs[i].value <= 1) {reduces[i].disabled = true} else {reduces[i].disabled = false}totals[i].innerHTML = parseInt(prices[i].innerHTML) * inputs[i].value + '¥'result()})dels[i].addEventListener('click', function () {carBody.removeChild(this.parentNode.parentNode)result()})}function result() {let sum = 0let num = 0// 重新获取数量和总价let inputs = document.querySelectorAll('.count-c input')let totals = document.querySelectorAll('.total')for (let i = 0; i < totals.length; i++) {sum = sum + parseInt(totals[i].innerHTML)num = num + parseInt(inputs[i].value)}totalResult.innerHTML = sum + '¥'totalCount.innerHTML = num}let all = document.querySelector('#all')let cks = document.querySelectorAll('.s_ck')let span = document.querySelector('#quan')all.addEventListener('click', function () {for (let i = 0; i < cks.length; i++) {cks[i].checked = all.checked}if (all.checked === true) {span.innerHTML = '取消'} else {span.innerHTML = '全选'}})for (let i = 0; i < cks.length; i++) {cks[i].addEventListener('click', function () {// 点击一次遍历所有checkfor (let j = 0; j < cks.length; j++) {if (cks[j].checked === false) {all.checked = false// 退出循环 结束点击事件return}}all.checked = true})}</script> </body></html>
扩展
事件对象
这里并没有直接体现事件对象的概念,但在定时器setInterval函数中,每次执行回调函数时,可以理解为是在处理一个定时事件,而每次回调函数接收到的是当前的时间信息。获取当前时间与格式化输出:首先通过new Date()获取当前时间,然后调用各种getter方法(getFullYear(), getMonth(), getDate(), getHours(), getMinutes(), getSeconds(), getDay())来获取具体的年、月、日、时、分、秒和星期几。然后将这些信息格式化后显示在网页的
元素中。<div></div><script>// 小括号为空可以得到当前时间// console.log(date); // 可以返回指定时间// let last = new Date('2020-9-1 18:30:00') // console.log(last);let arr = ['星期日','星期一','星期二','星期三','星期四','星期五','星期六']setInterval(function(){let date = new Date()let year = date.getFullYear()let month = date.getMonth()let date1 = date.getDate()let hour = date.getHours()let min = date.getMinutes()let sec = date.getSeconds()let day = date.getDay()let div = document.querySelector('div')div.innerHTML = `今天是:${year}年${month}月${date1}日${hour}:${min}:${sec} ${arr[day]}`}, 1000)</script>
时间戳
通过getTime()、+new Date()和Date.now()三种方式获取当前时间的时间戳(自1970年1月1日00:00:00 UTC以来的毫秒数)。同时,还可以通过传递特定日期字符串给new Date()构造函数来获取该日期对应的时间戳。
<script>// 1.getTime()let date = new Date()console.log(date.getTime());console.log('-----------------');// 2.+new Date()console.log(+new Date());console.log(+new Date('2022-11-21 00:00:00'));console.log('-----------------');// 3console.log(Date.now());</script>
倒计时
通过getTime()、+new Date()和Date.now()三种方式获取当前时间的时间戳(自1970年1月1日00:00:00 UTC以来的毫秒数)。同时,还可以通过传递特定日期字符串给new Date()构造函数来获取该日期对应的时间戳。
<!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><style>* {margin: 0;padding: 0;}.countdown {width: 240px;height: 305px;text-align: center;line-height: 1;color: white;background-color: brown;overflow: hidden;}.countdown .next {font-size: 16px;margin: 25px 0 14px;}.countdown .title {font-size: 33px;}.countdown .tips {margin-top: 80px;font-size: 23px;}.countdown .clock {width: 142px;margin: 18px auto 0;overflow: hidden;}.countdown .clock span,.countdown .clock i {display: block;text-align: center;line-height: 34px;font-size: 23px;float: left;}.countdown .clock span {width: 34px;height: 34px;border-radius: 2px;background-color: #303430;}.countdown .clock i {width: 20px;font-style: normal;}</style> </head><body><div class="countdown"><p class="next">今天是</p><p class="title">apex时间</p><p class="clock"><span id="hour"></span><i>:</i><span id="minuter"></span><i>:</i><span id="scond"></span></p><p class="tips">现在是</p></div><script>time()setInterval(time, 1000)function time() {let date = new Date()let year = date.getFullYear()let month = date.getMonth()let date1 = date.getDate()let hour = date.getHours()let min = date.getMinutes()let sec = date.getSeconds()let day = date.getDay()// 时间let tips = document.querySelector('.tips')tips.innerHTML = `现在是${hour}:${min}:${sec}`// 日期let next = document.querySelector('.next')next.innerHTML = `今天是${year}年${month}月${date1}日`let ho = document.querySelector('#hour')let mi = document.querySelector('#minuter')let sc = document.querySelector('#scond')let now = +new Date()let last = +new Date('2022-11-21 00:00:00')let count = (last - now) / 1000let h = parseInt(count / 60 / 60 % 24)let m = parseInt(count / 60 % 60)let s = parseInt(count % 60)ho.innerHTML = hmi.innerHTML = msc.innerHTML = s}</script> </body></html>