在移动端网页开发中,为触控操作提供即时反馈可以显著提升用户体验。以下是使用JavaScript和CSS3实现触控反馈的几种方法:
/* 基础触控样式 */
.touchable-element {
transition: transform 0.1s ease, opacity 0.1s ease;
}
/* 触控按下状态 */
.touchable-element:active {
transform: scale(0.95);
opacity: 0.8;
}
const elements = document.querySelectorAll('.touchable-element');
elements.forEach(el => {
el.addEventListener('touchstart', function() {
this.classList.add('touch-active');
});
el.addEventListener('touchend', function() {
this.classList.remove('touch-active');
});
});
配合CSS:
.touch-active {
transform: scale(0.95);
opacity: 0.8;
transition: transform 0.1s ease, opacity 0.1s ease;
}
<div class="ripple-container">
<button class="ripple-button">点击我</button>
</div>
.ripple-container {
position: relative;
overflow: hidden;
display: inline-block;
}
.ripple-button {
position: relative;
overflow: hidden;
padding: 12px 24px;
border: none;
background: #6200ee;
color: white;
border-radius: 4px;
cursor: pointer;
}
.ripple-effect {
position: absolute;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.7);
transform: scale(0);
animation: ripple 0.6s linear;
pointer-events: none;
}
@keyframes ripple {
to {
transform: scale(4);
opacity: 0;
}
}
document.querySelectorAll('.ripple-button').forEach(button => {
button.addEventListener('touchstart', function(e) {
e.preventDefault();
const rect = this.getBoundingClientRect();
const x = e.touches[0].clientX - rect.left;
const y = e.touches[0].clientY - rect.top;
const ripple = document.createElement('span');
ripple.classList.add('ripple-effect');
ripple.style.left = `${x}px`;
ripple.style.top = `${y}px`;
this.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
});
});
.touch-feedback {
will-change: transform, opacity;
transform: translateZ(0);
}
// 检查是否支持振动API
if ('vibrate' in navigator) {
element.addEventListener('touchstart', () => {
navigator.vibrate(10); // 振动10毫秒
});
}
class TouchFeedback {
constructor(selector) {
this.elements = document.querySelectorAll(selector);
this.init();
}
init() {
this.elements.forEach(el => {
// 添加必要的CSS类
el.classList.add('touch-feedback-element');
// 添加事件监听
el.addEventListener('touchstart', this.handleTouchStart.bind(this));
el.addEventListener('touchend', this.handleTouchEnd.bind(this));
el.addEventListener('touchcancel', this.handleTouchEnd.bind(this));
});
}
handleTouchStart(e) {
const el = e.currentTarget;
el.classList.add('active');
// 创建波纹效果
this.createRipple(el, e.touches[0]);
// 触发触觉反馈(如果支持)
if ('vibrate' in navigator) {
navigator.vibrate(10);
}
}
handleTouchEnd(e) {
const el = e.currentTarget;
el.classList.remove('active');
}
createRipple(el, touch) {
const rect = el.getBoundingClientRect();
const x = touch.clientX - rect.left;
const y = touch.clientY - rect.top;
const ripple = document.createElement('div');
ripple.className = 'touch-ripple';
ripple.style.left = `${x}px`;
ripple.style.top = `${y}px`;
el.appendChild(ripple);
setTimeout(() => {
ripple.remove();
}, 600);
}
}
// 使用示例
new TouchFeedback('.touch-feedback');
配套CSS:
.touch-feedback-element {
position: relative;
overflow: hidden;
transition: transform 0.1s ease;
will-change: transform;
}
.touch-feedback-element.active {
transform: scale(0.97);
}
.touch-ripple {
position: absolute;
width: 20px;
height: 20px;
margin-left: -10px;
margin-top: -10px;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.5);
animation: ripple 0.6s ease-out;
pointer-events: none;
}
@keyframes ripple {
to {
transform: scale(10);
opacity: 0;
}
}
will-change
和transform
属性优化动画性能这些技术可以组合使用,根据你的具体需求创建最适合的触控反馈体验。