留言评论效果在社交平台比较常见,本案例使用原生的HTML+CSS+JS实现评论留言案例
静态页面效果如下:
表情包渲染页面如下:
网页中集成表情包请参考:另外一篇博客“原生前端中整合emoji表情”
添加留言/评论后的效果:
删除效果也能实现。
本案例使用了localStorage发布评论/留言之后刷新,数据仍然会在页面中存在。
不足之处是使用了reload事件页面会闪,可以将节点操作换成innerHTML
参考代码:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>评论案例</title>
<style>
* {
margin: 0;
padding: 0;
}
li {
list-style: none;
background-color: white;
}
a {
text-decoration: none;
font-size: 20px;
color: red;
}
body {
background: url(./images/bg.jpg) no-repeat;
background-size: cover;
width: 100vw;
height: 100vh;
overflow: hidden;
}
.comment_box {
margin: 10px;
}
.comment_box .top {
margin: 20px;
height: 35vh;
padding: 15px;
background-color: white;
border-radius: 10px;
}
.comment_box .top .msg {
padding: 10px;
}
.input textarea {
width: 100%;
height: 70%;
outline: none;
border: 1px solid #ccc;
resize: none;
padding: 5px;
font-size: 16px;
}
.operaction {
display: flex;
justify-content: space-between;
margin-top: 10px;
}
.operaction img {
width: 40px;
height: 40px;
}
.operaction button {
width: 100px;
background-color: #fe813f;
color: white;
border: none;
outline: none;
border-radius: 10px;
}
.comment_box .comment_content {
height: 65vh;
margin-top: 10px;
overflow: auto;
padding: 15px;
}
.comment_content::-webkit-scrollbar {
display: none;
}
.comment_content li {
padding: 20px;
border-radius: 10px;
margin: 40px 0;
}
.comment_content li .header {
display: flex;
justify-content: space-between;
margin-bottom: 10px;
}
.comment_content li .header .avater_info {
display: flex;
}
.comment_content img {
width: 50px;
height: 50px;
border-radius: 50%;
margin-right: 10px;
}
.comment_content .content {
margin-top: 10px;
}
li:nth-child(1) {
margin-top: 0;
}
.emoji {
width: 450px;
margin-left: 15px;
padding: 5px;
display: flex;
flex-wrap: wrap;
font-size: 30px;
cursor: pointer;
background-color: white;
border-radius: 10px;
}
.emoji li {
flex: 1;
text-align: center;
}
.emoji li:hover {
background-color: #dddd;
}
.active {
display: none;
}
</style>
</head>
<body>
<div class="comment_box">
<div class="top">
<p class="msg">有什么新鲜事想告诉大家?</p>
<div class="input">
<textarea name="" id=""></textarea>
</div>
<div class="operaction">
<img src="./images/表情.jpg" alt="" />
<button>发表</button>
</div>
</div>
<ul class="emoji active"></ul>
<ul class="comment_content"></ul>
</div>
<script>
// 获取DOM元素
/* 按钮 */
const btn = document.querySelector('button')
/* 文本域 */
const text = document.querySelector('textarea')
/* ul */
const comment_content = document.querySelector('.comment_content')
// 删除标签
const del = document.querySelector('a')
// 渲染表情包区域
let emoji = document.querySelector('.emoji')
let img = document.querySelector('img')
let comment = []
let emojis = [
'😀',
'😁',
'😂',
'😃',
'😄',
'😅',
'😆',
'😇',
'😈',
'😉',
'😊',
'😋',
'😌',
'😍',
'😎',
'😏',
'😐',
'😑',
'😒',
'😒',
'😓',
'😔',
'😕',
'😖',
'😗',
'😘',
'😙',
'😚',
'😛',
'😜',
'😝',
'😞',
'😟',
'😠',
'😡',
'😢',
'😣',
'😤',
'😥',
'😦',
'😧',
'😨',
'😩',
'😪',
'😫',
'😬',
'😭',
'😮',
'😯',
'😰'
]
/* 格式化日期时间 */
function getTime() {
let date = new Date()
let year = date.getFullYear()
let Month = date.getMonth() + 1
Month = Month >= 10 ? Month : '0' + Month
let day = date.getDate()
day = day >= 10 ? day : '0' + day
let hour = date.getHours()
hour = hour >= 10 ? hour : '0' + hour
let min = date.getMinutes()
min = min >= 10 ? min : '0' + min
let seconds = date.getSeconds()
seconds = seconds >= 10 ? seconds : '0' + seconds
return `${year}-${Month}-${day} ${hour}:${min}:${seconds}`
}
// 页面初始化渲染数据
window.onload = function () {
/* 页面初始化已有的留言 */
comment = JSON.parse(localStorage.getItem('data'))
console.log(comment)
if (comment !== null) {
comment.forEach(item => {
let li = document.createElement('li')
li.innerHTML = `
<div class="header">
<div class="avater_info">
<div class="avater">
<img src="./images/tx.jpeg" alt="" />
</div>
<div class="info_time">
<p>小黄人</p>
<span>${item.time}</span>
</div>
</div>
<div class="del">
<a href="javascript:;" title="${item.id}" >删除</a>
</div>
</div>
<hr />
<div class="content">${item.msg}</div>`
comment_content.append(li)
})
let as = document.querySelectorAll('a')
as.forEach((item, index) => {
item.onclick = function (e) {
comment = comment.filter(item => item.id != e.target.title)
console.log(comment)
localStorage.setItem('data', JSON.stringify(comment))
location.reload()
}
})
// localStorage.setItem('data', JSON.stringify(comment))
// location.reload()
} else {
comment = []
}
/* 将表情包渲染到页面 */
emojis.forEach(item => {
let li = document.createElement('li')
li.innerHTML = item
emoji.appendChild(li)
})
}
function add_comment() {
if (text.value === '') {
alert('评论的内容不能为空')
} else {
comment.unshift({
id: comment.length + 1,
img: './images/tx.jpeg',
time: getTime(),
msg: text.value
})
alert('添加成功')
localStorage.setItem('data', JSON.stringify(comment))
}
}
btn.onclick = function () {
add_comment()
location.reload()
}
// 显示隐藏表情包列表
img.onclick = function () {
emoji.classList.toggle('active')
}
// 点击表情包拼接内容
emoji.onclick = function (e) {
text.value += e.target.innerHTML
}
</script>
</body>
</html>