目录
小米商城分为六大模块:首页,分类,米圈,购物车,我的,登录注册。
其中分类,米圈,登录注册这三个模块较为复杂,技术点较多。以下是我总结的一些技术点。
一、分类
1.横向拖拽条
由于横向tab中的li元素过多,超出的元素需要拖拽出现。代码如下:
// .横向拖动滚动导航条
function getDragger(outternode, innernode) {
let isDragging = false;
let startX = 0;
// 处理鼠标按下事件
innernode.addEventListener("mousedown", function (e) {
isDragging = true;
startX = e.clientX;
});
// 处理触摸开始事件
innernode.addEventListener("touchstart", function (e) {
isDragging = true;
startX = e.touches[0].clientX; // 使用触摸点的 X 坐标
});
// 处理鼠标抬起事件
document.addEventListener("mouseup", function () {
isDragging = false;
});
// 处理触摸结束事件
document.addEventListener("touchend", function () {
isDragging = false;
});
// 处理鼠标移动事件
outternode.addEventListener("mousemove", function (e) {
if (isDragging) {
const delta = startX - e.clientX;
outternode.scrollLeft += delta;
startX = e.clientX;
}
});
// 处理触摸移动事件
outternode.addEventListener("touchmove", function (e) {
if (isDragging) {
const delta = startX - e.touches[0].clientX; // 使用触摸点的 X 坐标
outternode.scrollLeft += delta;
startX = e.touches[0].clientX; // 更新为当前触摸点的 X 坐标
e.preventDefault(); // 防止默认的触摸行为
}
});
}
// 使用示例
getDragger(container, content);
2.锚点平滑跳转
页面中有很多a标签及其对应的锚点,实现平滑跳转:
// .锚点平滑跳转
function smoothTarget() {
document.querySelectorAll('a[href^="#"]').forEach((anchor) => {
anchor.addEventListener("click", function (e) {
e.preventDefault(); // 阻止默认的锚点跳转
const targetId = this.getAttribute("href"); // 获取目标元素的 ID
const target = document.querySelector(targetId); // 获取目标元素
if (target) {
// 检查目标元素是否存在
target.scrollIntoView({
behavior: "smooth", // 设置滚动行为为平滑
});
} else {
console.warn(`目标元素 ${targetId} 不存在`); // 打印警告信息
}
});
});
}
smoothTarget();
3.左右布局盒子分别滚动
由于分类页面是左右布局,滚动事件也是分开的:
// .左右布局分别滚动
// deltaY 是 WheelEvent 对象的一个属性
leftBox.addEventListener("wheel", (event) => {
event.preventDefault(); // 阻止默认行为,以防页面滚动
leftBox.scrollTop += event.deltaY; // 根据滚轮移动量滚动左侧盒子
});
rightBox.addEventListener("wheel", (event) => {
event.preventDefault(); // 阻止默认行为,以防页面滚动
rightBox.scrollTop += event.deltaY; // 根据滚轮移动量滚动右侧盒子
});
二、米圈
1.NProgress进度条
在请求数据时,页面上数据没渲染时,增强用户交互。顶端增加进度条
(1)由于不是node环境,引入NProgress的cdn地址:
<link rel="stylesheet" href="https://unpkg.com/nprogress@0.2.0/nprogress.css"/>
<script src="https://unpkg.com/nprogress@0.2.0/nprogress.js"></script>
(2)准备一个节点存储NProgress
注意:一定要是id=content,否则没效果
<div id="content"></div>
(3)js中在请求中插入(以下是示例代码)
document.getElementById('fetchData').addEventListener('click', function () {
// 开始进度条
NProgress.start();
// 发起 Axios 请求
axios.get('https://jsonplaceholder.typicode.com/posts')
.then(function (response) {
// 假设返回的是 JSON 数据
const contentDiv = document.getElementById('content');
contentDiv.innerHTML = JSON.stringify(response.data, null, 2);
})
.catch(function (error) {
console.error('Error fetching data:', error);
})
.finally(function () {
// 完成进度条
NProgress.done();
});
});
2.用映射处理对应渲染函数
米圈的评论类型被我分为了四种,根据数据库的recType字段进行区分,渲染准备的四种渲染函数,为了便于管理用了映射:
// >创建一个映射对象
const renderFunctions = {
1: renderComment1,
2: renderComment2,
3: renderComment3,
4: renderComment4,
};
response.data.forEach((item) => {
// >根据 recType 获取相应的渲染函数
const renderFunction = renderFunctions[item.recType];
if (renderFunction) {
renderFunction(item); // 调用渲染函数
}
});
三、登录
1.头像上传
// .上传头像
var uploadedImageSrc = "";
fileInput.addEventListener("change", function (event) {
const file = event.target.files[0]; // 获取用户上传的文件
if (file) {
const reader = new FileReader(); // 创建 FileReader 对象
reader.onload = function (e) {
const preview = document.getElementById("preview");
preview.innerHTML = ""; // 清空预览区
const img = document.createElement("img"); // 创建 img 元素
uploadedImageSrc = e.target.result;
console.log("🚀 ~ uploadedImageSrc:", uploadedImageSrc);
img.src = e.target.result; // 设置 img 的 src 为文件内容
preview.appendChild(img); // 将 img 添加到预览区
};
reader.readAsDataURL(file); // 读取文件为 Data URL
}
});