DOM-节点操作
节点操作
本质上针对标签本身的增删查 总结: 有明确的亲戚关系的时候, 使用查语法更加方便一些
节点-查
返回的都是dom对象
查找父级: 子元素.parentNode
查找最近的父级元素,返回是dom元素
查找子集: 父元素.children
伪数组
遍历,不能使用forEach 兄弟 nextElementSibling 下一个兄弟元素 previousElementSibling 上一个兄弟元素
创建新节点: let result = document.createElement(标签名称)
追加节点
parent.appendChild(child),将child的元素添加到parent元素里去(最后面)
append:追加,都是在最后面追加。
parent.insertBofore(child, refChild),将child元素添加到refChild的前面去,ref:相对引用参照,
如果refChild元素获取不到, 会默认以appendChild形式添加,一定要传递第二个参数,否则报错,追加的节点可以是新创建的 也可以是页面上已经存在 (移动)
- 克隆节点
模板元素.cloneNode(布尔值)
false: 浅拷贝,只拷贝元素结构 true: 深拷贝,拷贝元素结构及内容 用于需要创建一个复杂的标签前提: 页面上有一个模板节点
删除节点
parent.removeChild(child)
-
获取日期对象new Date()
-
获取日期对象的每一个部分
getFullYear() getMonth() + 1 getDate() getHours() getMinutes() getSeconds()
补0
hour = hour < 10 ? '0' + hour : hour
minute = minute < 10 ? '0' + minute : minute
second = second < 10 ? '0' + second : second`
微博发布案例
需求1:
- 注册input事件2. 将文本的内容的长度赋值给对应的数值 3. 表单的maxlength属性可以直接限制在200个数之间
需求2: 克隆预定义好的模板,将模板的hidden属性设置为false, 并最终展示到页面上判断如果内容为空,则提示不能输入为空, 并且直接return防止输入无意义空格, 使用字符串.trim()去掉首尾空格, 并将表单value值设置为空字符串
需求3: 获取文本域的内容, 赋值给由模板克隆出来的新标签里面的content.innerText =随机获取数据数组里面的内容, 替换newNode的图片和名称 =Math.random()* (n + 1) =利用时间对象将时间动态化
需求4: 在事件处理函数里面获取点击按钮,注册点击事件 =(易错点: 必须在事件里面获取,外面获取不到) 删除对应的元素 (通过this获取对应的那条需要删除的元素)
需求5: 将表单域内容重置为空 将userCount里面的内容重置为0
<body>
<div class="w">
<!-- 操作的界面 -->
<div class="controls">
<img src="./images/9.6/tip.png" alt="" /><br />
<!-- maxlength 可以用来限制表单输入的内容长度 -->
<textarea placeholder="说点什么吧..." id="area" cols="30" rows="10" maxlength="200"></textarea>
<div>
<span class="useCount" id="useCount">0</span>
<span>/</span>
<span>200</span>
<button id="send">发布</button>
</div>
</div>
<!-- 微博内容列表 -->
<div class="contentList">
<ul id="list">
<!-- <li>
<div class="info">
<img class="userpic" src="./images/9.5/01.jpg" />
<span class="username">名字</span>
<p class="send-time">发布于 时间</p>
</div>
<div class="content">内容</div>
<span class="the_del">X</span>
</li> -->
</ul>
</div>
</div>
<script>
// 模拟数据,后期我们需要从这个数组中随机获取一个数据对象,做为发布微博的用户信息进行渲染,但是这个不是关键业务,我也可以固定写死
let dataArr = [
{ uname: '司马懿', imgSrc: './images/9.5/01.jpg' },
{ uname: '女娲', imgSrc: './images/9.5/02.jpg' },
{ uname: '百里守约', imgSrc: './images/9.5/03.jpg' },
{ uname: '亚瑟', imgSrc: './images/9.5/04.jpg' },
{ uname: '虞姬', imgSrc: './images/9.5/05.jpg' },
{ uname: '张良', imgSrc: './images/9.5/06.jpg' },
{ uname: '安琪拉', imgSrc: './images/9.5/07.jpg' },
{ uname: '李白', imgSrc: './images/9.5/08.jpg' },
{ uname: '阿珂', imgSrc: './images/9.5/09.jpg' },
{ uname: '墨子', imgSrc: './images/9.5/10.jpg' },
{ uname: '鲁班', imgSrc: './images/9.5/11.jpg' },
{ uname: '嬴政', imgSrc: './images/9.5/12.jpg' },
{ uname: '孙膑', imgSrc: './images/9.5/13.jpg' },
{ uname: '周瑜', imgSrc: './images/9.5/14.jpg' },
{ uname: '老夫子', imgSrc: './images/9.5/15.jpg' },
{ uname: '狄仁杰', imgSrc: './images/9.5/16.jpg' },
{ uname: '扁鹊', imgSrc: './images/9.5/17.jpg' },
{ uname: '马可波罗', imgSrc: './images/9.5/18.jpg' },
{ uname: '露娜', imgSrc: './images/9.5/19.jpg' },
{ uname: '孙悟空', imgSrc: './images/9.5/20.jpg' },
{ uname: '黄忠', imgSrc: './images/9.5/21.jpg' },
{ uname: '百里玄策', imgSrc: './images/9.5/22.jpg' }
]
// 获取数据
let area = document.querySelector('#area')/* 文本域 */
let useCount = document.querySelector('#useCount')/* 字数 */
let send = document.querySelector('#send')/* 发布按钮 */
let list = document.querySelector('#list')/* 列表 */
// 为send发布按钮绑定单击事件
send.addEventListener('click', function () {
// 根据用户输入内容建立元素
//获取用户输入
let content = area.value
// 判断用户是否输入了内容 content.trim()空格不计入字数
if (content.trim().length == 0) {
alert('你还没输入内容,请输入')
return
}
let newLi = document.createElement('li')
// 生成一个随机数,获取一个英雄头像
let index = parseInt(Math.random() * dataArr.length)
let obj = dataArr[index]
// 为元素设置内容
newLi.innerHTML = ` <div class="info">
<img class="userpic" src="${obj.imgSrc}" />
<span class="username">${obj.uname}</span>
<p class="send-time">发布于 ${dateFormat()}</p>
</div>
<div class="content">${content}</div>
<span class="the_del">X</span>`
// 插入到第一条
list.insertBefore(newLi, list.children[0])
// 删除微博
// 获取数据 x
let det = document.querySelector('.the_del')
// 绑定单击删除事件
det.addEventListener('click', function () {
// 删除当前微博
list.removeChild(newLi)
})
// 发送之后清空文本
area.value = ''
useCount.innerText = 0
})
// 为文本域添加按键事件,如果按下的是enter键,则实现发布功能
area.addEventListener('keyup', function (e) {
// 如果按下的是enter键,则发布
if (e.key === 'Enter') {
send.click()
}
})
// 封装当前时间函数
function dateFormat() {
let date = new Date()
let year = date.getFullYear()
let month = date.getMonth() + 1
let day = date.getDate()
let hour = date.getHours()
let minute = date.getMinutes()
let second = date.getSeconds()
return `${year}-${month < 10 ? '0' + month : month}-${day} ${hour}:${minute < 10 ? '0' + minute : minute
}:${second < 10 ? '0' + second : second}`
}
// 监听用户的字数的变化:input当输入内容发生变化的时候就会触发,字数即时更新
area.addEventListener('input', function () {
let count = area.value.length
useCount.innerText = count
})
</script>
</body>
下班倒计时
<body>
<div class="countdown">
<p class="next">今天是2021年8月28日</p>
<p class="title">下班倒计时
<!-- <input type="datetime-local" id="des" /> -->
</p>
<p class="clock">
<span id="hour">00</span>
<i>:</i>
<span id="minutes">00</span>
<i>:</i>
<span id="scond">00</span>
</p>
<p class="tips">
现在是18:30:00
</p>
</div>
<script>
// 先获取元素
let des = document.querySelector('#des')
let start = 0
let hourele = document.querySelector('#hour')
let minutesele = document.querySelector('#minutes ')
let scondele = document.querySelector('#scond')
// let timeId = null
// des.addEventListener('change', function () {
// let desTime = this.value
// clearInterval(timeId)
// setTimeout(function () {
// start = 1000
// }, 999)
// })
let timeId = setInterval(function () {
// 获取两个时间间隔的时间戳 未来-现在
// +new Date('2022-1-20-21:00') 未来的时间
// (Date.now()) 现在的时间
let offset = parseInt((+new Date('2022-1-20-21:00')) - (Date.now())) / 1000
// 小时
let hour = parseInt(offset / 3600)
// 分钟
let minute = parseInt(offset % 3600 / 60)
// 秒
let second = parseInt(offset % 60)
// 补0
hour = hour < 10 ? '0' + hour : hour
minute = minute < 10 ? '0' + minute : minute
second = second < 10 ? '0' + second : second
if (offset === 0) {
clearInterval(timeId)
}
// 赋值给指定元素
hourele.innerHTML = hour
minutesele.innerHTML = minute
scondele.innerHTML = second
}, 1000)
</script>
</body>
复制节点
<body>
<button>复制节点并添加到另外一个div中</button>
<div class="first">
<p><span>我是first的p元素</span></p>
</div>
<div class="second"></div>
<script>
// 1.为按钮添加单击事件
let btn = document.querySelector('button')
let originP = document.querySelector('.first > p')
let second = document.querySelector('.second')
btn.addEventListener('click', function() {
// 2.在事件处理函数中:
// 2.1 复制指定的节点,接收复制之后的节点
// cloneNode的参数作用:如果为true,说明复制时也会复制元素的子节点,如果为false则不会复制它的子节点
// let res = originP.cloneNode(true)
// 2.2 将复制的节点添加到指定的容器中
// second.appendChild(res)
second.appendChild(originP)
})
</script>
</body>
创建元素
<body>
<button>来一个p元素</button>
<div class="box">
<span>这是原始就有的</span>
</div>
<script>
let btn = document.querySelector('button')
let box = document.querySelector('.box')
// let p = document.querySelector('p')
btn.addEventListener('click', function () {
// 通过 document.createElement('元素名称')就可以创建一个指定的标签了
let newP = document.createElement('p')
newP.innerText = '我是新增的p元素'
// 将创建的元素追加到box的最后
// 父容器.appendChild(子元素):可以将子元素追加到父容器的最后---做父子
// box.appendChild(newP)
// 父容器.insertBefore(子元素,子元素的相对位置):可以将指定的元素插入到某个子元素之前--做父子
// 如果父容器没有子元素,那么可以为第二个参数传递null
// 如果有子元素,最好能够设置一个具体的子元素位置参照
box.insertBefore(newP, null)
})
</script>
</body>