1.移动端如何实现下拉刷新
关键在于:
- 使用 touch 事件监听移动端的手势。
- 添加阻尼效果(moveY * 0.5),使下拉更自然。
- 仅在滚动到顶部(scrollTop === 0)时启用下拉。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
#refresh-area {
position: absolute;
top: -50px;
height: 50px;
width: 100%;
text-align: center;
transition: top 0.3s;
background: #f0f0f0;
}
#content {
height: 1000px; /* 模拟内容区域 */
overflow: auto;
}
</style>
</head>
<body>
<div id="refresh-area">下拉刷新</div>
<div id="content">页面内容...</div>
<script>
const refreshArea = document.getElementById('refresh-area');
const content = document.getElementById('content');
let startY = 0;
let moveY = 0;
let isPulling = false;
content.addEventListener('touchstart', (e) => {
startY = e.touches[0].clientY;
isPulling = content.scrollTop === 0; // 仅在顶部时生效
});
content.addEventListener('touchmove', (e) => {
if (!isPulling) return;
moveY = e.touches[0].clientY - startY;
if (moveY > 0) {
// 设置下拉距离(阻尼效果)
const pullDistance = Math.min(moveY * 0.5, 50);
refreshArea.style.top = `${pullDistance - 50}px`;
if (pullDistance >= 50) {
refreshArea.textContent = '释放刷新';
} else {
refreshArea.textContent = '下拉刷新';
}
}
});
content.addEventListener('touchend', () => {
if (!isPulling) return;
if (moveY * 0.5 >= 50) {
// 触发刷新
refreshArea.textContent = '正在刷新...';
refreshArea.style.top = '0px';
setTimeout(() => {
// 模拟刷新完成
refreshArea.style.top = '-50px';
refreshArea.textContent = '下拉刷新';
console.log('刷新完成');
}, 1000);
} else {
// 未达到阈值,回弹
refreshArea.style.top = '-50px';
}
isPulling = false;
});
</script>
</body>
</html>
2. PerformanceObeserver如何测量页面性能?
const observer = new PerformanceObserver((list)=>{
const entries = list.getEntries();
entries.forEach(entry=>{
console.log(entry)
})
})
observer.observe({
entryTypes:['longtask']
})
3. 如何统计用户pv访问时发起的请求数量?
前端统计
- 封装应用请求方法,通过单例模式在请求时进行计数,使用统计API调用场景,无法捕获img,script等标签的静态资源请求
- 借用performance API获取加载期间所有资源请求,能统计所有资源请求(包括图片、CSS、JS 等),但仅限于页面加载完成时的统计,无法实时更新
window.addEventListener('load', function () {
const resources = performance.getEntriesByType('resource');
const requestCount = resources.length;
console.log(`页面加载期间总请求数: ${requestCount}`);
// 可选:发送到服务器
fetch('/log-requests', {
method: 'POST',
body: JSON.stringify({ pvRequests: requestCount }),
});
});
后端统计
服务器日志+会话标识
4.如何实现拖拽效果
5. 统计全站每一个静态资源加载耗时,该如何做
// 获取所有资源的加载信息
function getResourceTiming() {
const resources = performance.getEntriesByType('resource');
const result = resources.map(resource => {
const {
name, // 资源URL
startTime, // 开始时间
responseEnd, // 响应结束时间
transferSize, // 传输大小
decodedBodySize // 解码后大小
} = resource;
// 计算加载耗时(ms)
const loadTime = responseEnd - startTime;
return {
url: name,
loadTime: loadTime.toFixed(2),
size: transferSize,
decodedSize: decodedBodySize
};
});
console.table(result); // 以表格形式输出,便于查看
}
// 在页面加载完成后执行
window.addEventListener('load', () => {
setTimeout(getResourceTiming, 0); // 确保所有资源加载完成
});
// 动态加载的资源可以通过观察者持续监控
const observer = new PerformanceObserver((list) => {
const entries = list.getEntries();
entries.forEach(entry => {
console.log(`${entry.name} 加载耗时: ${(entry.responseEnd - entry.startTime).toFixed(2)}ms`);
});
});
observer.observe({ entryTypes: ['resource'] });