# focus-html
**Repository Path**: lylxq/focus-html
## Basic Information
- **Project Name**: focus-html
- **Description**: 基于原生js开发的焦点框架
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2024-10-24
- **Last Updated**: 2025-08-11
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# LyFocusFrame 焦点管理框架开发文档
LyFocusFrame 是一个功能强大的 JavaScript 焦点管理框架,专为 TV 端、大屏应用和需要复杂键盘导航的 Web 应用设计。它提供了完整的焦点管理解决方案,包括焦点跳转、滚动居中、虚拟列表、动态 DOM 监听等功能。
## 1. 核心概念
### 1.1 框架组成
LyFocusFrame 由以下几个核心组件构成:
- **焦点框架(FocusSwitch)**: 管理整个焦点系统的容器
- **焦点盒子(FocusBox)**: 焦点容器,管理内部焦点元素的跳转逻辑
- **焦点元素(FocusWidget)**: 可获取焦点的最小单位
- **滚动区域(FocusScroll)**: 支持滚动居中的容器
- **虚拟列表(FocusVirtual)**: 优化长列表性能的虚拟滚动容器
- **跑马灯(FocusMarquee)**: 文字滚动效果支持
### 1.2 关键特性
- **智能焦点导航**: 支持阴影算法和区域算法两种焦点查找方式
- **动态 DOM 监听**: 自动检测 DOM 变化并更新焦点元素
- **虚拟列表优化**: 减少 DOM 节点数量,提升长列表性能
- **滚动居中**: 自动计算并平滑滚动到焦点元素
- **暗焦机制**: 保留上一个焦点的视觉提示
- **高度可配置**: 支持自定义键位映射、焦点样式等
## 2. 快速开始
### 2.1 安装与引入
```html
```
### 2.2 基本使用
```javascript
// 初始化焦点框架
var focusFrame = new LyFocusFrame('containerId', {
// 可选配置
useKeyDown: true, // 是否使用内置键盘监听
commontens: {} // 自定义组件
});
// 初始化焦点框架
var focusSwitch = focusFrame.findSwitch("switch1")
// 手动改变焦点
focusSwitch.onChangeFocus('widgetId');
// 显示/隐藏弹窗
focusFrame.onPopup('popupId', true);
```
## 3. 详细配置
### 3.1 默认配置
框架提供以下默认配置,可通过初始化时传入参数覆盖:
```javascript
var _defConfig = {
keyEnum: { LEFT: "LEFT", UP: "UP", RIGHT: "RIGHT", DOWN: "DOWN", ENTER: "ENTER", BACK: "BACK", HOME: "HOME", BACKSPACE: "BACKSPACE", DEL: "DEL", MENU: "MENU" },
keyDownTimeout: 60, // 按键间隔(ms)
animateTimeout: 200, // 动画时长(ms)
keyMap: {
65: "LEFT", 37: "LEFT", // A键和左箭头
87: "UP", 38: "UP", // W键和上箭头
68: "RIGHT", 39: "RIGHT",// D键和右箭头
83: "DOWN", 40: "DOWN", // S键和下箭头
13: "ENTER", // 回车键
32: "BACK", // 空格键
8: "BACK", // 退格键
36: "HOME", // Home键
12: "BACKSPACE", // Backspace键
280: "DEL", 287: "DEL", // Delete键
18: "MENU", // Alt键
48: 0, 49: 1, 50: 2, 51: 3, 52: 4, // 数字键0-9
53: 5, 54: 6, 55: 7, 56: 8, 57: 9
},
switchClass: "focusSwitch", // 焦点框架类名
boxClass: "focusBox", // 盒子类名
scrollClass: "focusScroll", // 滚动区域类名
virtualClass: "focusVirtual", // 虚拟列表类名
widgetClass: "focusWidget", // 焦点元素类名
marqueeClass: "focusMarquee", // 跑马灯类名
focusClass: "is-focus", // 聚焦样式名
darkFocusClass: "dark-focus" // 暗焦样式名
}
```
### 3.2 自定义配置
初始化时可传入自定义配置:
```javascript
var focusFrame = new LyFocusFrame('containerId', {
keyMap: {
37: "LEFT", 38: "UP", 39: "RIGHT", 40: "DOWN", // 仅使用方向键
13: "ENTER"
},
focusClass: "custom-focus", // 自定义焦点样式
commontens: {
// 自定义组件
"customWidget": function(container, options) {
// 实现自定义组件
this.onFocusChange = function(){}
this.onUpdate = function(){}
this.onCreated = function(){}
this.onDestroy = function(){}
}
}
});
```
## 4. 组件详解
### 4.1 焦点盒子(FocusBox)
焦点盒子是管理一组焦点元素的容器,提供以下功能:
- **焦点缓存**: 记住最后离开时的焦点位置
- **顺序跳转**: 支持按行/列顺序跳转
- **边界控制**: 处理焦点移入/移出事件
**HTML 结构示例**:
```html
```
**属性说明**:
- `f-cache`: 初始缓存焦点ID
- `f-sequencerow`: 每行元素数量,启用顺序跳转
- `f-sequencelink`: 是否在行首尾继续顺序跳转(true/false)
- `f-goleft/f-goright/f-goup/f-godown`: 指定移出时的跳转目标(多个ID用逗号分隔)
- `onleft/onright/onup/ondown`: 移出时的自定义函数
- `onfocus/onblur`: 焦点移入/移出时的回调
### 4.2 焦点元素(FocusWidget)
可获取焦点的最小单位。
**HTML 结构示例**:
```html
Click Me
```
**属性说明**:
- `onenter/onback/onhome/ondel/onmenu`: 按键回调
- `onleft/onright/onup/ondown`: 方向键回调
- `onfocus/onblur`: 焦点变化回调
- `f-cacherect`: 是否缓存位置信息(true/false)
### 4.3 滚动区域(FocusScroll)
支持内容滚动和焦点居中的容器。
**HTML 结构示例**:
```html
```
**属性说明**:
- `f-scroll`: 滚动方向(X/Y)
- `f-offset`: 滚动边距(数字或"center")
- `f-postion`: 滚动位置(start/end)
- `f-scrollbox`: 是否嵌套滚动盒子(true/false)
### 4.4 虚拟列表(FocusVirtual)
优化长列表性能的虚拟滚动容器。
**HTML 结构示例**:
```html
```
**属性说明**:
- `f-scroll`: 滚动方向(X/Y)
- `f-totalsize`: 数据总数
- `f-curindex`: 当前起始索引
- `f-cachesize`: 预渲染区域大小(px)
- `oncreateitem`: 创建列表项的回调函数
## 5. API 参考
### 5.1 LyFocusFrame 方法
| 方法 | 描述 | 参数 | 返回值 |
|------|------|------|--------|
| `onChangeFocus(id)` | 手动改变焦点 | `id`: 焦点元素ID | 无 |
| `onPopup(id, show)` | 显示/隐藏弹窗 | `id`: 弹窗ID, `show`: 布尔值 | 无 |
| `onEmitKeyDown(key, fn)` | 注册键盘事件 | `key`: 键名, `fn`: 回调函数 | 无 |
| `onRemoveKeyDown(key)` | 移除键盘事件 | `key`: 键名 | 无 |
| `onClearKeyDown()` | 清空所有键盘事件 | 无 | 无 |
| `onLock(locked)` | 锁定/解锁焦点 | `locked`: 布尔值 | 无 |
### 5.2 FocusSwitch 方法
| 方法 | 描述 | 参数 | 返回值 |
|------|------|------|--------|
| `onChangeFocus(id)` | 改变焦点 | `id`: 焦点元素ID | 无 |
| `onSetDarkFocus(id)` | 设置暗焦 | `id`: 焦点元素ID | 无 |
| `onLock(locked)` | 锁定/解锁焦点 | `locked`: 布尔值 | 无 |
| `upDataWidget()` | 更新组件列表 | 无 | 无 |
## 6. 事件与回调
### 6.1 内置事件
框架提供以下事件回调属性:
- **onleft/onright/onup/ondown**: 方向键事件
- **onenter/onback/onhome/ondel/onmenu**: 功能键事件
- **onfocus/onblur**: 焦点变化事件
- **onDarkFocusChange**: 暗焦变化事件
**回调函数示例**:
```javascript
// 在HTML中
// 在JS中
function returnNextBox(params) {
// params: {target, key, curWidget, nextWidget}
return "nextBoxId"; // 返回焦点盒子ID或焦点元素ID
}
```
### 6.2 自定义事件
可以通过`onEmitKeyDown`注册自定义键盘事件:
```javascript
focusFrame.onEmitKeyDown('ENTER', function(key) {
console.log('Custom ENTER handler', key);
});
```
## 7. 示例与应用
### 7.1 基础示例
```html
```
### 7.2 滚动列表示例
```html
```
### 7.3 虚拟列表示例
```html
```
### 7.4 弹窗示例
```html
```
## 8. 最佳实践
### 8.1 性能优化
1. **使用虚拟列表**: 对于长列表,使用`FocusVirtual`组件减少DOM节点数量
2. **限制DOM监听范围**: 避免全局监听,只监听必要的容器
3. **缓存位置信息**: 对静态元素设置`f-cacherect="true"`避免重复计算
4. **合理使用动画**: 调整`animateTimeout`平衡流畅度和性能
### 8.2 可维护性
1. **模块化开发**: 将不同功能区域的焦点逻辑分离
2. **统一命名规范**: 遵循一致的类名和ID命名规则
3. **文档化回调**: 为自定义回调函数添加详细注释
4. **版本控制**: 对焦点相关代码进行版本管理
### 8.3 兼容性考虑
1. **键盘兼容**: 确保键位映射支持各种输入设备
## 9. 常见问题
### 9.1 焦点不生效
- **检查类名**: 确保元素添加了正确的类名(`focusWidget`等)
- **验证容器**: 焦点元素必须包含在`focusSwitch`中
- **查看控制台**: 检查是否有JS错误阻止框架初始化
### 9.2 滚动不居中
- **确认方向**: 检查`f-scroll`设置是否正确(X/Y)
- **检查结构**: 确保有`focusScrollContent`和`focusScrollItem`层级
- **验证尺寸**: 确保容器和内容有明确的尺寸
### 9.3 虚拟列表不更新
- **检查回调**: 确保`oncreateitem`返回有效的HTML结构
- **验证总数**: 确认`f-totalsize`设置正确
- **更新索引**: 滚动后检查`f-curindex`是否更新
## 10. 扩展与定制
### 10.1 自定义组件
可以通过`commontens`配置添加自定义组件:
```javascript
var focusApp = new LyFocusFrame('app', {
commontens: {
"customWidget": function:CustomWidget(container, options) {
this.container = container;
this.options = options;
// 实现组件生命周期方法
this.onFocusChange = function(now, prev) {
// 焦点变化处理
};
}
}
});
```
### 10.2 自定义导航算法
可以覆盖默认的阴影算法和区域算法:
```javascript
FocusSwitch.prototype.onShadowAlgorithm = function(widgetItem, widgetList, direction) {
// 实现自定义算法
};
FocusSwitch.prototype.onAreaAlgorithm = function(widgetItem, widgetList, direction) {
// 实现自定义算法
};
```
## 11. 总结
LyFocusFrame 是一个功能全面、高度可定制的焦点管理框架,特别适合需要复杂键盘导航的应用场景。通过合理的配置和使用,可以大大简化焦点管理的复杂度,提升用户体验和开发效率。
框架的模块化设计和丰富的扩展点使其能够适应各种复杂需求,而内置的性能优化机制则确保了在大规模应用中的流畅运行。