1. CSS3动画卡顿
尽量使用transform,避免使用height,width,margin,padding等。可以开启GPU硬件加速,但用硬件加速的时候也要注意,因为这个也有坑,不合理使用反而会让应用越来越卡!
2. margin bottom
典型的bug,其实这个bug大家都有办法解决,直接使用padding-bottom就好了。
3. 移动端滑动穿透
弹框的内容明显长过屏幕,需要弹框内容滑动,主页页面不滑动
xml
体验AI代码助手
代码解读
复制代码
<script type="text/javascript">
//解决遮罩层滚动穿透问题,分别在遮罩层弹出后和关闭前调用
const ModalHelper = ( (bodyCls) =>{
let scrollTop;
return {
afterOpen: function () {
scrollTop = document.scrollingElement.scrollTop;
document.body.classList.add(bodyCls);
document.body.style.top = -scrollTop + 'px';
},
beforeClose: function () {
document.body.classList.remove(bodyCls);
// scrollTop lost after set position:fixed, restore it back.
document.scrollingElement.scrollTop = scrollTop;
}
};
})('dialog-open');
</script>
body.dialog-open {
position: fixed;
width: 100%;
}
复制代码
原理:弹出弹框时,使背景主页内容作为固定定位,这样页面的滑动对其就没有任何影响,关闭弹框使,移除这个固定定位的类名,回复正常
3. 经典的1px边框
一般是采用伪元素模拟的方式,原理:把原先元素的 border 去掉,然后利用 :before 或者 :after 重做 border ,并 transform 的 scale 缩小一半,原先的元素相对定位,新做的 border 绝对定位。
css
体验AI代码助手
代码解读
复制代码
.scale{
position: relative;
border:none;
}
.scale:after{
content: '';
position: absolute;
bottom: 0;
background: #000;
width: 100%;
height: 1px;
transform: scaleY(0.5);
transform-origin: 0 0;
}
复制代码
具体几种方法见:
4. android,border-radius:50%不圆
具体是因为,使用了rem布局,在部分机型上出现的问题,设置具体的px数值,不用50%即可
5. android里line-height不居中
解决方案:来源互联网
- 把字号内外边距等设置为需求大小的2倍,使用transform进行缩放。(不适用)
- 把字号内外边距等设置为需求大小的2倍,使用zoom进行缩放,可以完美解决。(可以)
- 把line-height设置为0,使用padding值把元素撑开,说是可以解决(不适用)。
具体原因:Android浏览器下line-height垂直居中为什么会偏离
6. 安卓部分版本input的placeholder偏上
input的line-height设为normal
css
体验AI代码助手
代码解读
复制代码
input{
line-height:normal;
}
复制代码
原理看stackoverflow上的回答:
7. ios的body设置overflow:hidden仍然可以滚动
一般在所有元素最外层再包一个大盒子.wrap
css
体验AI代码助手
代码解读
复制代码
.wrap{
position:relative;
overflow:hidden;
}
复制代码
stackoverflow上有好几种处理方法,可以顺便参考下:
Does overflow:hidden applied to work on iPhone Safari?
8. ios 滚动不流畅
使用了absolute布局之后,ios会发现元素内的滚动非常不流畅,滑动的手指松开后,滚动立刻停止,失去了原本的流畅滚动特性。百度一下弹性滚动的问题,发现在 webkit 中,下面的属性可以恢复弹性滚动。
css
体验AI代码助手
代码解读
复制代码
-webkit-overflow-scrolling: touch;
复制代码
9. ios fixed问题
用ios下当键盘弹起时fixed会失效。解决办法就是把页面滚动改为容器内滚动。
10. 点透问题
在移动端开发中,点透(click 穿透) 是常见的交互问题,通常发生在快速点击叠加元素时(如遮罩层消失后,下方元素意外触发点击)。其本质是由于移动端 click 事件存在 300ms 延迟,而 touch 事件(如 touchstart/touchend)触发更快,导致上层元素隐藏后,延迟的 click 事件落到了下层元素上。
常见场景
- 弹窗 / 遮罩层关闭后,下方的按钮 / 链接被意外点击。
- 快速点击两层重叠的可点击元素,下层元素触发点击。
解决方案
1. 避免使用 click,优先用 touch 事件
移动端优先使用 touchstart/touchend 替代 click,减少延迟导致的穿透。注意:touchstart 触发过早(手指刚接触屏幕),touchend 更接近点击完成的时机,推荐使用 touchend。
javascript
运行
// 替代 click 事件
element.addEventListener('touchend', (e) => {
// 阻止事件冒泡和默认行为(避免触发上层click)
e.stopPropagation();
e.preventDefault();
// 处理逻辑
handleClick();
});
2. 给上层元素添加 pointer-events: none 延迟
当上层元素(如遮罩)隐藏时,先设置 pointer-events: none(禁止点击穿透),延迟一段时间后再真正移除元素,等待底层 click 事件过期。
css
.mask {
/* 遮罩样式 */
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
}
javascript
运行
const mask = document.querySelector('.mask');
// 关闭遮罩时
function closeMask() {
// 先禁止点击穿透
mask.style.pointerEvents = 'none';
// 隐藏动画(如透明度渐变)
mask.style.opacity = '0';
// 延迟300ms(匹配click延迟)后彻底移除
setTimeout(() => {
mask.remove();
}, 300);
}
3. 使用 fastclick 库消除 300ms 延迟
fastclick 是专门解决移动端 click 延迟的库,原理是在 touchend 时立即触发模拟的 click 事件,避免 300ms 等待,从根源减少点透可能。
使用步骤:
-
引入库(CDN 或本地):
html
预览
<script src="https://cdnjs.cloudflare.com/ajax/libs/fastclick/1.0.6/fastclick.min.js"></script> -
初始化:
javascript
运行
if ('addEventListener' in document) { document.addEventListener('DOMContentLoaded', () => { FastClick.attach(document.body); // 全局生效 }, false); }
4. 阻止事件冒泡和默认行为
在触发上层元素的事件时,通过 e.stopPropagation() 和 e.preventDefault() 阻止事件传递到下层。
javascript
运行
// 上层元素点击事件
upperElement.addEventListener('touchend', (e) => {
e.stopPropagation(); // 阻止冒泡到下层
e.preventDefault(); // 阻止默认行为(如浏览器默认click)
upperElement.style.display = 'none'; // 隐藏上层元素
});
5. 针对特殊元素(如 <a> 标签)
- 避免使用
<a href>直接作为下层元素,可改用<div>模拟链接,通过 JS 跳转。 - 若必须用
<a>,可在点击上层元素后,临时给<a>添加pointer-events: none,延迟后恢复。
最佳实践
- 移动端优先使用
touch事件(touchend),配合pointer-events控制穿透。 - 若需兼容
click事件(如 PC 端),可结合fastclick消除延迟。 - 遮罩 / 弹窗关闭时,添加适当延迟再移除元素,确保底层
click事件失效。
11. 键盘遮挡输入框问题
核心思路
当虚拟键盘弹出时,通过监听键盘事件或元素位置变化,动态调整输入框(或其容器)的位置,使其滚动到可视区域内。
解决方案
1. 基础方案:利用浏览器自动滚动(最简单)
部分浏览器(如 Chrome、Safari)会在输入框聚焦时,自动将其滚动到可视区域。若未生效,检查是否存在以下问题:
- 输入框的父元素是否设置了
overflow: hidden或固定高度,导致无法滚动。 - 页面是否使用了
position: fixed布局,可能干扰浏览器自动调整。
修复建议:移除不必要的 overflow: hidden,或避免在滚动容器上使用固定定位。
2. 监听焦点事件,手动滚动输入框到可视区
当输入框聚焦时,强制将其滚动到视口内(利用 scrollIntoView 方法)。
html
预览
<input type="text" class="input-field" placeholder="点击输入">
<script>
// 获取所有输入框
const inputs = document.querySelectorAll('.input-field');
inputs.forEach(input => {
// 聚焦时触发
input.addEventListener('focus', () => {
// 延迟执行,确保键盘弹出后再滚动(兼容不同浏览器)
setTimeout(() => {
// 滚动到可视区,参数 { block: 'center' } 可调整垂直位置
input.scrollIntoView({ block: 'center', behavior: 'smooth' });
}, 300);
});
});
</script>
原理:scrollIntoView 会自动调整父容器滚动位置,使元素出现在视口中。
3. 监听键盘高度变化(更精准)
通过 visualViewport 或 resize 事件感知键盘弹出(键盘弹出会导致视口高度变小),动态调整输入框位置。
html
预览
<input type="text" class="input-field" placeholder="点击输入">
<script>
const input = document.querySelector('.input-field');
let originalHeight = window.innerHeight; // 初始视口高度
input.addEventListener('focus', () => {
// 监听视口大小变化(键盘弹出会触发)
window.addEventListener('resize', handleResize);
});
input.addEventListener('blur', () => {
// 失去焦点后移除监听
window.removeEventListener('resize', handleResize);
});
function handleResize() {
const currentHeight = window.innerHeight;
// 若视口高度变小(判断为键盘弹出)
if (currentHeight < originalHeight) {
const keyboardHeight = originalHeight - currentHeight;
// 获取输入框底部到视口顶部的距离
const inputBottom = input.getBoundingClientRect().bottom;
// 若输入框底部超过当前视口高度(被键盘遮挡)
if (inputBottom > currentHeight) {
// 滚动到输入框可见位置(可根据需要调整偏移量)
window.scrollBy({
top: inputBottom - currentHeight + 20, // 加20px留白
behavior: 'smooth'
});
}
} else {
// 键盘收起,恢复初始高度记录
originalHeight = currentHeight;
}
}
</script>
优势:通过计算键盘高度和输入框位置,精准避免遮挡。
4. 针对固定定位元素(如底部输入框)
若输入框在 position: fixed; bottom: 0 布局中(常见于聊天界面),键盘弹出时会被完全遮挡,需动态调整 bottom 值:
css
.fixed-input {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 10px;
}
javascript
运行
const fixedInput = document.querySelector('.fixed-input');
let originalBottom = 0;
fixedInput.addEventListener('focus', () => {
window.addEventListener('resize', adjustFixedInput);
});
fixedInput.addEventListener('blur', () => {
window.removeEventListener('resize', adjustFixedInput);
// 恢复初始位置
fixedInput.style.bottom = '0';
});
function adjustFixedInput() {
const currentHeight = window.innerHeight;
if (currentHeight < originalHeight) {
// 键盘高度 = 初始高度 - 当前高度
const keyboardHeight = originalHeight - currentHeight;
// 将输入框底部调整为键盘高度(显示在键盘上方)
fixedInput.style.bottom = `${keyboardHeight}px`;
}
}
补充建议
- 测试兼容性:不同手机浏览器(如微信浏览器、Safari、Chrome)对键盘事件的处理存在差异,需多设备测试。
- 避免过度滚动:滚动时保留适当留白(如 20px),提升用户体验。
- 结合框架特性:若使用 Vue/React,可封装成自定义指令(如
v-auto-scroll),简化代码复用。
12. 浮层上进行滑动,浮层下面的页面也跟着滚动
具体就是当浮层出现、隐藏的时候,设置相应的overflow值
13. ios日期转换NAN问题
具体就是,new Date('2020-11-12 00:00:00')在ios中会为NAN
决绝方案:用new Date('2020/11/12 00:00:00')的日期格式,或者写个正则转换
14. ios滚动时动画停止
移动端滚动懒人推荐使用[better-scroll]
15. 长按闪退
css
体验AI代码助手
代码解读
复制代码
element {
-webkit-touch-callout:none;
}
复制代码
16. 禁止数字识别为电话号码
ini
体验AI代码助手
代码解读
复制代码
<meta name = "format-detection" content = "telephone=no">
复制代码
17. transition闪屏
css
体验AI代码助手
代码解读
复制代码
.box {
-webkit-transform-style: preserve-3d;
-webkit-backface-visibility: hidden;
-webkit-perspective: 1000;
}
复制代码