众所不周知,在我们的日常生活中常常会出现需要一个漂亮的UI而暂时没有对应方案的问题
本人已遇到好几次想要做一个聊天界面,但总是弄不出来的问题
之前是剪视频用,后来是C墙的CCT(详见我的网站cwall.czoffice.top,不甚完善,大概5月前更新一个更强的)聊天用
从网上,都是一些写的很奇怪的代码,也不实用,也不漂亮
于是我写了一个全新的,没有借鉴任何软件的纯自制聊天界面,页面主要以蓝色为主题,可以右键复制文件,复制图片和下载图片,用户发送的图片单击可以进入图片查看界面(旋转放大之类的那些),界面也比较简洁
大概就这么多,示例如下,代码可自行使用和学习(愿意的话给我标注一下原作者awa,也别直接不改的拿去用哈):
<!DOCTYPE html>
<html>
<meta charset="UTF-8">
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f0f0f0;
}
.chat-container {
max-height: 500px;
height: 500px;
width: 50%;
overflow-y: scroll;
padding: 10px;
display: flex;
flex-direction: column;
align-items: flex-start; /* 居左对齐 */
justify-content: flex-start; /* 居左对齐 */
margin: 0 auto; /* 水平居中 */
}
/* 滚动条宽度 */
.chat-container::-webkit-scrollbar {
border-radius: 5px;
width: 10px;
}
/* 滚动条轨道背景色 */
.chat-container::-webkit-scrollbar-track {
border-radius: 5px;
background: #f1f1f1;
}
/* 滚动条滑块背景色 */
.chat-container::-webkit-scrollbar-thumb {
background: #888;
border-radius: 5px;
}
/* 滚动条滑块在悬停时的背景色 */
.chat-container::-webkit-scrollbar-thumb:hover {
background: #555;
}
.message {
margin-top: 30px;
margin-bottom: 10px;
padding: 5px;
border-radius: 5px;
max-width: 70%; /* 聊天框最大宽度 */
word-wrap: break-word; /* 超过长度自动换行 */
position: relative;
/*text-align: center; 聊天框文本居中对齐 */
display: flex;
justify-content: center;
align-items: center;
min-width: 1.5%;
}
.sent {
background-color: #add8e6;
align-self: flex-end; /* 消息居右 */
border-top-right-radius: 0; /* 将右上角变成方形 */
border-radius: 10px; /* 设置其他三个角的圆角大小 */
}
.received {
background-color: #fff;
align-self: flex-start; /* 消息居左 */
border-top-left-radius: 0; /* 将右上角变成方形 */
border-radius: 10px; /* 设置其他三个角的圆角大小 */
}
.name {
font-weight: bold;
margin-bottom: 5px;
white-space: nowrap; /* 防止昵称自动换行 */
}
.name-container {
position: absolute;
top: -20px;
left: 0;
}
.input-container {
display: flex;
align-items: center;
justify-content: space-between;
border-top: 1px solid #ccc;
padding: 10px;
width: 50%;
margin: 0 auto; /* 水平居中 */
}
input[type="text"] {
flex: 1;
padding: 5px;
margin-right: 10px;
border: 1px solid #ccc;
border-radius: 3px;
}
.sendbutton {
padding: 5px 15px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 3px;
cursor: pointer;
}
/* 添加动态效果和互动效果的代码 */
.message {
transition: transform 0.2s; /* 添加过渡效果 */
}
.message:hover {
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); /* 阴影效果 */
}
input[type="text"]:focus {
outline: none;
border-color: #0056b3; /* 输入框获取焦点时的边框颜色 */
}
button:focus {
outline: none;
box-shadow: 0 0 5px rgba(0, 0, 0, 0.2); /* 按钮获取焦点时的阴影效果 */
}
/* 输入框样式 */
input[type="text"] {
flex: 1;
padding: 8px; /* 调整输入框内边距 */
margin-right: 10px;
border: 1px solid #ccc;
border-radius: 5px; /* 圆角边框 */
transition: border-color 0.3s; /* 添加过渡效果 */
}
input[type="text"]:focus {
outline: none;
border-color: #007bff; /* 输入框获取焦点时的边框颜色 */
}
/* 文件选择框样式 */
.file-input {
padding: 8px 20px; /* 调整按钮内边距 */
border-radius: 5px;
position: relative;
overflow: hidden;
display: inline-block;
margin-right: 10px;
cursor:pointer;
}
.file-input input[type="file"] {
position: absolute;
font-size: 100px;
opacity: 0;
right: 0;
top: 0;
cursor:pointer;
}
.file-input span {
padding: 8px 15px;
background-color: #007bff;
color: #fff;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s; /* 添加过渡效果 */
cursor:pointer;
}
.file-input span:hover {
background-color: #0056b3; /* 鼠标悬停时的背景颜色 */
}
/* 发送按钮样式 */
.sendbutton {
padding: 8px 20px; /* 调整按钮内边距 */
background-color: #007bff;
color: #fff;
border: none;
border-radius: 5px;
cursor: pointer;
transition: background-color 0.3s; /* 添加过渡效果 */
}
.sendbutton:hover {
background-color: #0056b3; /* 鼠标悬停时的背景颜色 */
}
.notification {
position: fixed;
top: -200px; /* 初始位置在页面正上方 */
left: 50%;
transform: translateX(-50%);
background-color: #007bff;
color: #fff;
padding: 10px 20px;
border-radius: 5px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
transition: top 0.3s; /* 添加过渡效果 */
height: 25px;
width: 95px;
}
.notification.show {
top: 20px; /* 弹出后的位置 */
}
.message {
display: inline-block;
}
.time {
display: flex;
justify-content: center;
align-items: center;
background-color: #f0f0f0; /* 浅灰色背景颜色 */
padding: 5px;
border-radius: 5px;
margin-top: 10px;
margin: 0 auto; /* 水平居中 */
background-color: lightgrey;
}
.time:hover {
transform: scale(1.1); /* 添加放大效果 */
}
/* 添加动态效果和互动效果的代码 */
.notification {
cursor: pointer;
}
.notification:hover {
background-color: #0056b3; /* 鼠标悬停时的背景颜色 */
}
.notification .nmessage {
margin: 0 auto; /* 水平居中 */
transition: opacity 0.3s; /* 添加过渡效果 */
}
.notification.hide .nmessage {
opacity: 0; /* 收回时隐藏消息文本 */
}
#overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
#image-container {
position: relative;
max-width: 90%;
max-height: 90%;
}
#image-container img {
display: block;
max-width: 100%;
max-height: 100%;
margin: 0 auto;
cursor: pointer;
}
#buttons {
position: absolute;
bottom: -60px;
left: 50%;
transform: translateX(-50%); /* 水平居中按钮组 */
display: flex;
justify-content: center;
gap: 10px; /* 按钮间距 */
z-index: 10; /* 确保按钮在图片上方 */
}
#buttons button {
background-color: #fff; /* 按钮背景色 */
border: none; /* 去除边框 */
padding: 8px 16px; /* 按钮内边距 */
border-radius: 5px; /* 按钮圆角 */
cursor: pointer; /* 鼠标悬停时改变指针样式 */
font-size: 16px; /* 字体大小 */
color: #333; /* 字体颜色 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 按钮阴影 */
transition: background-color 0.3s ease; /* 按钮背景色过渡效果 */
}
#buttons button:hover {
background-color: #f0f0f0; /* 鼠标悬停时按钮背景色 */
}
#buttons .reset-button {
margin-left: auto; /* 将复位按钮与其他按钮分开 */
}
.tpck {
height: 500px;
width: 300px;
max-height: 1000px;
max-width: 1000px;
animation: slideIn 1s forwards;
}
#custom-menu,
#custom-menu2 {
display: none;
position: absolute;
z-index: 1000;
background-color: #f9f9f9;
border: 1px solid #d4d4d4;
padding: 10px;
border-radius: 5px;
}
#custom-menu li,
#custom-menu2 li {
list-style: none;
padding: 5px;
cursor: pointer;
}
#custom-menu li:hover,
#custom-menu2 li:hover {
background-color: #e5e5e5;
}
#custom-menu:active,
#custom-menu2:active {
display: none;
}
#custom-menu li:active,
#custom-menu2 li:active {
background-color: #ccc;
}
#message-received-animate__animated-animate__fadeInLeft .span {
float: left;
opacity: 0;
animation: fadeIn 1s forwards;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
#navbar {
position: fixed;
top: 0;
right: -300px; /* 初始状态隐藏导航栏 */
width: 300px;
height: 100vh;
background-color: #f1f1f1;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
transition: right 0.3s ease-in-out;
z-index: 9999;
}
#navbar.open {
right: 0; /* 展开导航栏时显示在页面右侧 */
}
#navbar .content {
padding: 20px;
}
#toggle-btn {
position: fixed;
top: 20px;
right: 20px;
width: 40px;
height: 40px;
background-color: #f1f1f1;
border-radius: 50%;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
cursor: pointer;
transition: background-color 0.3s ease-in-out;
z-index: 9999;
}
#toggle-btn:hover {
background-color: #ccc;
}
#toggle-btn span {
display: block;
width: 20px;
height: 2px;
background-color: #555;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
transition: background-color 0.3s ease-in-out;
}
#toggle-btn.open span:nth-child(1) {
transform: translate(-50%, -50%) rotate(-45deg);
}
#toggle-btn.open span:nth-child(2) {
display: none;
}
#toggle-btn.open span:nth-child(3) {
transform: translate(-50%, -50%) rotate(45deg);
}
</style>
<title>CZ+四会聊天————C墙</title>
</head>
<body>
<div class="title">CZ+四会聊天</div>
<div class="notification">
<p class="nmessage"><svg style="height:15px;width:15px;" t="1707968708192" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4197" width="200" height="200"><path d="M802.922882 383.309012 428.076612 758.155283 220.943065 551.154765c-22.317285-22.317285-22.317285-55.993269 0-78.310553 22.450315-22.450315 55.993269-22.450315 78.443583 0l128.689964 128.689964L724.613352 304.999482c22.450315-22.450315 55.993269-22.450315 78.30953 0C825.373197 327.316767 825.373197 360.858698 802.922882 383.309012zM512 64.322981c-246.155283 0-447.677019 201.521736-447.677019 447.677019s201.521736 447.677019 447.677019 447.677019 447.677019-201.521736 447.677019-447.677019S758.155283 64.322981 512 64.322981z" fill="#22C134" p-id="4198"></path></svg>复制成功!<!--<span id="text"></span>--></p>
</div>
<div class="chat-container">
<div class="time">16:34:32</div>
<div class="message received">
<span class="umessage">HI</span>
<div class="name-container">
<div class="name">frisk</div>
</div>
</div>
<div class="time">17:23:27</div>
<div class="message sent">
<span class="umessage">嘿</span>
<div class="name-container">
<div class="name">陈致</div>
</div>
</div>
<div class="time">17:23:50</div>
<div class="message sent">
<img class="tpck" src="https://cdn.czoffice.top/people/%E9%99%88%E8%87%B4/upload/officeweb/img/2.jpg">
<div class="name-container">
<div class="name">陈致</div>
</div>
</div>
</div>
<form id="message-form" method="post" action="" enctype="multipart/form-data">
<div class="input-container" id="input-container">
<input autocomplete="off" type="text" name="message" placeholder="发你所想...">
<div class="file-input">
<span>发送文件</span>
<input type="file" name="image[]" multiple>
</div>
<button class="sendbutton" type="submit" name="send">发送</button>
</div>
</form>
<div id="overlay" style="display: none;">
<div id="image-container">
<img id="zoom-image" src="" alt="Zoomed Image">
<div id="buttons">
<button id="rotate-button">旋转</button>
<button id="zoom-in-button">放大</button>
<button id="zoom-out-button">缩小</button>
<button class="reset-button">复位</button>
</div>
</div>
</div>
<ul id="custom-menu">
<li onclick="downloadImage()"><svg style="width:20px;height:20px" t="1708093336130" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4227" width="200" height="200"><path d="M896 704c-17.695686 0-31.99914 14.303454-31.99914 31.99914l0 128L160.00086 863.99914l0-128c0-17.695686-14.336138-31.99914-32.00086-31.99914s-32.00086 14.303454-32.00086 31.99914l0 160.00086c0 17.695686 14.336138 31.99914 32.00086 31.99914l768 0c17.695686 0 32.00086-14.303454 32.00086-31.99914l0-160.00086C928.00086 718.303454 913.695686 704 896 704zM227.579 530.662l259.11 259.293c6.368 6.399 14.689 9.471 22.977 9.408 1.12 0.096 2.08 0.64 3.2 0.64 4.673 0 9.024-1.088 13.024-2.88 4.032-1.536 7.872-3.872 11.137-7.135l259.329-259.124c12.513-12.48 12.544-32.735 0.033-45.248-6.24-6.272-14.432-9.407-22.656-9.408-8.193 0-16.352 3.136-22.624 9.344l-206.24 206.162 0-563.713c0-17.696-14.336-31.999-32.001-31.999s-32.001 14.303-32.001 31.999l0 565.281-207.91-207.74c-6.241-6.272-14.496-9.44-22.688-9.44s-16.32 3.103-22.56 9.311c-12.575 12.449-12.607 32.737-0.127 45.248z" fill="#272636" p-id="4228"></path></svg>下载</li>
<li onclick="copyImage()"><svg style="width:20px;height:20px" t="1707882201291" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5440" width="200" height="200"><path d="M263.2 761.3H145.4c-45.5 0-82.5-37-82.5-82.5V150.6c0-45.5 37-82.5 82.5-82.5h488.9c45.5 0 82.5 37 82.5 82.5v70.1c0 11-9 20-20 20s-20-9-20-20v-70.1c0-23.4-19-42.5-42.5-42.5H145.4c-23.4 0-42.5 19-42.5 42.5v528.3c0 23.4 19 42.5 42.5 42.5h117.8c11 0 20 9 20 20s-8.9 19.9-20 19.9z" fill="#1C1C1C" p-id="5441"></path><path d="M897.2 971.1H400.9c-42.5 0-77.2-34.6-77.2-77.2V358.4c0-42.5 34.6-77.2 77.2-77.2h496.4c42.5 0 77.2 34.6 77.2 77.2V894c-0.1 42.5-34.7 77.1-77.3 77.1zM400.9 321.2c-20.5 0-37.2 16.7-37.2 37.2V894c0 20.5 16.7 37.2 37.2 37.2h496.4c20.5 0 37.2-16.7 37.2-37.2V358.4c0-20.5-16.7-37.2-37.2-37.2H400.9z" fill="#1C1C1C" p-id="5442"></path></svg>复制</li>
</ul>
<ul id="custom-menu2">
<li onclick="copyumessage()"><svg style="width:20px;height:20px" t="1707882201291" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5440" width="200" height="200"><path d="M263.2 761.3H145.4c-45.5 0-82.5-37-82.5-82.5V150.6c0-45.5 37-82.5 82.5-82.5h488.9c45.5 0 82.5 37 82.5 82.5v70.1c0 11-9 20-20 20s-20-9-20-20v-70.1c0-23.4-19-42.5-42.5-42.5H145.4c-23.4 0-42.5 19-42.5 42.5v528.3c0 23.4 19 42.5 42.5 42.5h117.8c11 0 20 9 20 20s-8.9 19.9-20 19.9z" fill="#1C1C1C" p-id="5441"></path><path d="M897.2 971.1H400.9c-42.5 0-77.2-34.6-77.2-77.2V358.4c0-42.5 34.6-77.2 77.2-77.2h496.4c42.5 0 77.2 34.6 77.2 77.2V894c-0.1 42.5-34.7 77.1-77.3 77.1zM400.9 321.2c-20.5 0-37.2 16.7-37.2 37.2V894c0 20.5 16.7 37.2 37.2 37.2h496.4c20.5 0 37.2-16.7 37.2-37.2V358.4c0-20.5-16.7-37.2-37.2-37.2H400.9z" fill="#1C1C1C" p-id="5442"></path></svg>复制</li>
</ul>
<script type="text/javascript">
$(document).ready(function () {
$('#messagesall').scrollTop($('#messagesall')[0].scrollHeight);
$('#messagesall').scrollLeft($('#messagesall')[0].scrollWidth);
});
</script>
<div id="overlay" style="display: none;">
<div id="image-container">
<img id="zoom-image" src="" alt="Zoomed Image">
<div id="buttons">
<button id="rotate-button" class="blue">旋转</button>
<button id="zoom-in-button" class="white">放大</button>
<button id="zoom-out-button" class="white">缩小</button>
</div>
</div>
</div>
<script>
window.history.replaceState(null, null, window.location.href);
window.addEventListener('DOMContentLoaded', function() {
var chatContainer = document.querySelector('.chat-container');
chatContainer.scrollTop = chatContainer.scrollHeight;
});
// 全局变量,用于保存用户点击的umessage内容
var clickedUmessageContent = '';
// 获取所有的umessage
var umessages = document.querySelectorAll('.umessage');
// 为每个umessage添加上下文菜单
umessages.forEach(function(umessage) {
umessage.addEventListener('contextmenu', function(e) {
e.preventDefault(); // 阻止默认的右键菜单
// 保存被点击的umessage的内容
clickedUmessageContent = umessage.textContent || umessage.innerText;
// 显示自定义菜单
var menu = document.getElementById('custom-menu2');
menu.style.display = 'block';
menu.style.left = e.pageX + 'px'; // 设置菜单的位置
menu.style.top = e.pageY + 'px';
// 当点击其他地方时,隐藏菜单
document.addEventListener('click', function hideMenu() {
menu.style.display = 'none';
document.removeEventListener('click', hideMenu); // 移除事件监听器
}, { once: true });
});
// 点击图片时隐藏菜单
umessage.addEventListener('click', function() {
var menu = document.getElementById('custom-menu2');
menu.style.display = 'none';
});
});
function copyumessage() {
// 创建一个临时的textarea元素用于复制操作
var tempTextarea = document.createElement('textarea');
// 将textarea元素添加到文档中,但不可见
document.body.appendChild(tempTextarea);
// 设置textarea的值为要复制的文本
tempTextarea.value = clickedUmessageContent;
// 选中textarea中的文本
tempTextarea.select();
// 执行复制命令
document.execCommand('copy');
// 从文档中移除textarea元素
document.body.removeChild(tempTextarea);
// 显示复制成功的通知
const notification = document.querySelector('.notification');
notification.classList.add('show');
// 在一段时间后隐藏通知
setTimeout(() => {
notification.classList.remove('show', 'hide');
}, 3000);
}
// 全局变量,用于保存用户点击的tpck图片链接
var clickedTpckImageLink = '';
// 获取所有的tpck图片
var tpckImages = document.querySelectorAll('.tpck');
// 为每个tpck图片添加上下文菜单
tpckImages.forEach(function(image) {
image.addEventListener('contextmenu', function(e) {
e.preventDefault(); // 阻止默认的右键菜单
// 保存被点击的tpck图片链接
clickedTpckImageLink = image.src;
// 显示自定义菜单
var menu = document.getElementById('custom-menu');
menu.style.display = 'block';
menu.style.left = e.pageX + 'px'; // 设置菜单的位置
menu.style.top = e.pageY + 'px';
// 当点击其他地方时,隐藏菜单
document.addEventListener('click', function hideMenu() {
menu.style.display = 'none';
document.removeEventListener('click', hideMenu); // 移除事件监听器
}, { once: true });
});
// 点击图片时隐藏菜单
image.addEventListener('click', function() {
var menu = document.getElementById('custom-menu');
menu.style.display = 'none';
});
});
// 下载图片的函数
function downloadImage() {
var link = document.createElement('a');
link.href = clickedTpckImageLink;
link.download = clickedTpckImageLink.split('/').pop(); // 获取图片的文件名
link.click();
}
// 复制图片的函数
function copyImage() {
navigator.clipboard.writeText(clickedTpckImageLink).then(function() {
// 显示复制成功的通知
const notification = document.querySelector('.notification');
notification.classList.add('show');
// 在一段时间后隐藏通知
setTimeout(() => {
notification.classList.remove('show', 'hide');
}, 3000);
}).catch(function(err) {
alert('无法复制图片链接:' + err);
});
}
// 获取所有class为tpck的img标签
var images = document.querySelectorAll('.tpck');
// 监听图片点击事件
images.forEach(function(image) {
image.addEventListener('click', function() {
var overlay = document.getElementById('overlay');
var zoomImage = document.getElementById('zoom-image');
var rotateButton = document.getElementById('rotate-button');
var zoomInButton = document.getElementById('zoom-in-button');
var zoomOutButton = document.getElementById('zoom-out-button');
var resetButton = document.querySelector('.reset-button');
// 显示图片查看器
overlay.style.display = 'flex';
zoomImage.src = image.src;
// 关闭图片查看器
overlay.addEventListener('click', function(e) {
if (e.target === overlay) {
overlay.style.display = 'none';
zoomImage.style.transform = 'none'; // 复位图片
}
});
// 旋转图片
var rotation = 0;
rotateButton.addEventListener('click', function() {
rotation += 90;
zoomImage.style.transform = 'rotate(' + rotation + 'deg)';
});
// 放大图片
zoomInButton.addEventListener('click', function() {
var currentScale = parseFloat(zoomImage.style.transform.replace('scale(', '').replace(')', '')) || 1;
var newScale = currentScale + 0.1;
zoomImage.style.transform = 'scale(' + newScale + ')';
});
// 缩小图片
zoomOutButton.addEventListener('click', function() {
var currentScale = parseFloat(zoomImage.style.transform.replace('scale(', '').replace(')', '')) || 1;
var newScale = currentScale - 0.1;
zoomImage.style.transform = 'scale(' + newScale + ')';
});
// 复位图片
resetButton.addEventListener('click', function() {
zoomImage.style.transform = 'none';
});
});
});
</script>
<div id="navbar">
<div class="content">
<h2>导航栏</h2>
<p>这里是导航栏的内容。</p>
<iframe src="./mmodify.php" width="100%" height="800px" style="border:0px;"></iframe>
</div>
</div>
<div id="toggle-btn">
<span></span>
<span></span>
<span></span>
</div>
<script>
const navbar = document.getElementById('navbar');
const toggleBtn = document.getElementById('toggle-btn');
toggleBtn.addEventListener('click', function() {
navbar.classList.toggle('open');
toggleBtn.classList.toggle('open');
});
</script>
</body>
</html>