# 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
Item 1
Item 2
Item 3
``` **属性说明**: - `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
Item 1
``` **属性说明**: - `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
Item 1
``` ### 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 是一个功能全面、高度可定制的焦点管理框架,特别适合需要复杂键盘导航的应用场景。通过合理的配置和使用,可以大大简化焦点管理的复杂度,提升用户体验和开发效率。 框架的模块化设计和丰富的扩展点使其能够适应各种复杂需求,而内置的性能优化机制则确保了在大规模应用中的流畅运行。