@@ -0,0 +1,54 @@
|
||||
# k_ry_mobile_form - 科瑞移动端表单优化模块
|
||||
|
||||
## 功能说明
|
||||
|
||||
此模块为 Odoo 17 的 form 视图添加移动端优化功能:
|
||||
- 在手机浏览器中,form 视图 header 的工具按钮栏会悬浮在屏幕底部
|
||||
- 提供类似正常 APP 的底部按钮栏体验
|
||||
- 桌面端不受影响,保持原有显示方式
|
||||
|
||||
## 依赖
|
||||
|
||||
- `base`
|
||||
- `web`
|
||||
|
||||
## 安装
|
||||
|
||||
1. 将模块放置在 Odoo 的 addons 目录下
|
||||
2. 更新应用列表
|
||||
3. 安装 `k_ry_mobile_form` 模块
|
||||
|
||||
## 技术实现
|
||||
|
||||
### 文件结构
|
||||
|
||||
```
|
||||
k_ry_mobile_form/
|
||||
├── __init__.py
|
||||
├── __manifest__.py
|
||||
├── README.md
|
||||
└── static/
|
||||
└── src/
|
||||
├── js/
|
||||
│ └── status_bar_buttons.js # 覆盖 StatusBarButtons 组件模板
|
||||
├── xml/
|
||||
│ └── status_bar_buttons.xml # 新的模板定义
|
||||
└── scss/
|
||||
└── status_bar_buttons.scss # 移动端底部悬浮栏样式
|
||||
```
|
||||
|
||||
### 实现原理
|
||||
|
||||
1. **JavaScript 覆盖**:使用 `patch` 方法覆盖 `StatusBarButtons` 组件的模板
|
||||
2. **模板替换**:提供新的模板,根据 `env.isSmall` 判断显示方式
|
||||
3. **样式隔离**:使用媒体查询确保移动端和桌面端样式互不影响
|
||||
|
||||
## 使用说明
|
||||
|
||||
安装模块后,无需额外配置。在手机浏览器中打开任何包含 header 的 form 视图时,工具按钮栏会自动显示在底部。
|
||||
|
||||
## 注意事项
|
||||
|
||||
- 此模块只影响 form 视图的 header 按钮栏
|
||||
- 桌面端完全不受影响
|
||||
- 支持 iOS 设备的底部安全区域(safe area)
|
||||
@@ -7,3 +7,49 @@ import { patch } from "@web/core/utils/patch";
|
||||
patch(StatusBarButtons, {
|
||||
template: "k_ry_mobile_form.StatusBarButtons",
|
||||
});
|
||||
|
||||
// iOS Safari修复:确保移动端按钮在iOS上可点击
|
||||
// 使用MutationObserver监听DOM变化,确保新添加的按钮也能正常工作
|
||||
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
||||
const fixIOSButtons = () => {
|
||||
const containers = document.querySelectorAll('.o_statusbar_buttons_mobile_fixed');
|
||||
containers.forEach(container => {
|
||||
const buttons = container.querySelectorAll('button, a.btn, .btn, a[role="button"], .o_statusbar_buttons > * > button');
|
||||
buttons.forEach(button => {
|
||||
// 确保pointer-events正确设置
|
||||
if (getComputedStyle(button).pointerEvents === 'none') {
|
||||
button.style.pointerEvents = 'auto';
|
||||
}
|
||||
button.style.cursor = 'pointer';
|
||||
button.style.touchAction = 'manipulation';
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 初始化函数:确保DOM准备好后再设置observer
|
||||
const initIOSButtonFix = () => {
|
||||
// 先执行一次修复
|
||||
fixIOSButtons();
|
||||
|
||||
// 确保document.body存在后再创建observer
|
||||
if (document.body) {
|
||||
// 监听DOM变化,确保动态添加的按钮也能正常工作
|
||||
const observer = new MutationObserver(fixIOSButtons);
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
} else {
|
||||
// 如果body还不存在,等待DOMContentLoaded
|
||||
document.addEventListener('DOMContentLoaded', initIOSButtonFix, { once: true });
|
||||
}
|
||||
};
|
||||
|
||||
// 页面加载后执行
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initIOSButtonFix);
|
||||
} else {
|
||||
// 使用setTimeout确保DOM完全准备好
|
||||
setTimeout(initIOSButtonFix, 0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,22 +11,52 @@
|
||||
padding: map-get($spacers, 2) map-get($spacers, 3);
|
||||
// 为底部悬浮栏预留空间,避免内容被遮挡(支持 iOS safe area)
|
||||
padding-bottom: calc(#{map-get($spacers, 2)} + env(safe-area-inset-bottom, 0px));
|
||||
// iOS Safari 修复:确保元素可交互
|
||||
-webkit-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
// iOS Safari 修复:防止滚动时fixed定位失效
|
||||
-webkit-backface-visibility: hidden;
|
||||
backface-visibility: hidden;
|
||||
|
||||
.o_statusbar_buttons {
|
||||
max-width: 100%;
|
||||
width: 100%;
|
||||
// iOS Safari 修复:确保容器可交互
|
||||
pointer-events: auto;
|
||||
-webkit-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
|
||||
> * {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
// iOS Safari 修复:确保子元素可交互
|
||||
pointer-events: auto;
|
||||
|
||||
> button {
|
||||
> button,
|
||||
> a,
|
||||
> .btn {
|
||||
width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
// 确保按钮有足够的点击区域
|
||||
min-height: 44px;
|
||||
// iOS Safari 修复:确保按钮可点击
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0.1);
|
||||
touch-action: manipulation;
|
||||
// iOS Safari 修复:防止文本选择影响点击
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
-webkit-touch-callout: none;
|
||||
// iOS Safari 修复:确保按钮在层级之上
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
// iOS Safari 修复:确保pointer-events正确
|
||||
pointer-events: auto !important;
|
||||
// iOS Safari 修复:防止transform影响点击
|
||||
-webkit-transform: translateZ(0);
|
||||
transform: translateZ(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user