npm package: @rockywu/epgjs
Description: 用于传统EPG焦点选择偏移等行为
Author: rockywu 吴佳雷
Latest version: 0.0.9

## @rockywu/epgjs

**专注于大屏EPG业务中的焦点移动解决方案**

> 背景：

从事大屏电视EPG Web开发，在开发过程中遇到大量的焦点选择的行为。在前期开发过程中焦点均使用Id进行定位，各个方向上的焦点元素固定，当使用自定义排版、模板不固定时，发现现有的焦点获取方式已经无法满足业务变更的需求，顾开发了该焦点选择库`epgjs`

> 目标：

* 提供开发效率
* 支持任意模板
* 减少焦点选择代码
* 支持多图层功能
* 支持为在元素的各种事件
	* `default` 设为默认焦点
	* `click`  确认/点击行为
	* `left` 向左移动
	* `right` 向右移动
	* `up` 向上移动
	* `down` 向下移动
	* `focus` 从另一个元素移动到当前元素上时
	* `beforefocus` 从另一个元素移动到当前元素之前时
	* `blur` 已离开当前元素上时
	* `beforeblur` 即将离开当前元素上时
	* `back` 触发遥控器返回按钮时
* 支持画布滚动（内置滚动动画）
* 解决画布层级关系


### Install

```
npm install --save @rockywu/epgjs
```

### Usage

> Browser

```
<script type="text/javascript" src="./epgjs.min.js"></script>
```

> Npm

```
import epgjs  from '@rockywu/epgjs' 
//or
let epgjs = require('@rockywu/epgjs')
```
### Demo

```
	var epg = window.epgjs({
		//遥控器按键触发间隔
		interval: 100,
		//事件前缀
		prefix: "@",
        keyNumbers: null, //自定义数字事件（见下方存在默认配置）
        keyActions: null, //自定义按键事件（见下方存在默认配置）
	})
	//注册画布
	epg.registerView({
		//元素选择器(支持jQuery选择器）
		selector: ".btn, div.item, .form[name=xxx]",
		// 画布根节点
		root: "#container",
		//注册立即扫描
		autoLoad: true
	}, {
	//业务代码
	})
	
```

```
/**
 * 为元素添加自定义事件例子
 * 定定义@left @right @up @down 属性却未绑定函数时，默认约定阻止该方向上的移动
 * html中 当焦点移动到#btn2上时，上下左右方向均无法移动
 */
<div id="container">
   <button id="bt1" class="btn" @click="btnClick" @left="btnLeft" @right="btnRight">01</button>
   <button id="bt2" class="btn" @left @right @down @up>02</button>
   <div class="item">03</div>
</div>
<script type="text/javascript">
    var epg = window.epgjs({
		//遥控器按键触发间隔
		interval: 100,
		//事件前缀
		prefix: "@"
	})
    //注册画布
	epg.registerView({
		//元素选择器(支持jQuery选择器）
		selector: ".btn, div.item, .form[name=xxx]",
		// 画布根节点
		root: "#container",
		//注册立即扫描
		autoLoad: true
	}, {
        /**
         * 为按钮添加click事件,事件名完全可自定义
         * options参数解构
         *  {
         *   //下一个焦点元素
         *   nexter: nexter || null,
         *   //当前焦点元素
         *   pointer: pointer || null,
         *   //上一个焦点元素
         *   laster: lastPonter || null,
         *   //当前视图对象
         *   viewer: this,
         *   //事件名
         *   event: eventName || null 
         *  }
         */
        btnClick: function(options) {
            console.log(options)
        },
        //Promise返回值触发左移行为
        btnLeft: function(options) {
            console.log(options);
            //返回true不阻止后续行为
            return Promise.reslove(true)
        },
        //手动触发next触发左移行为
        btnRight: function(options, next) {
            console.log(options);
            //延迟1秒左移行为
            setTimeout(function() {
                next();
            }, 1000);
        }
	})
</script>

```

### 事件介绍

> 焦点发生改变是触发事件顺序

举例：当前焦点为A,焦点将移动到B焦点时，生命周期触发顺序

**Y（代表可以中断后续事件执行）**

**N（代表不可以中断后续事件执行）**

* `beforeblur` A即将失焦点时触发（Y）
* `beforefocus` B即将获得焦点时触发 （Y）
* `left`/`right`/`up`/`down` 是通过方向键行为触发焦点变化时触发（Y）
* `blur` A焦点已失去焦点（N）
* `focus` B焦点已获得焦点（N）
* `scroll` 待完善

> `click` 独立事件（N）

在当前焦点上按下`确定按键`时触发

> `back` 独立事件（N）

在当前焦点上按下`返回按键`时触发

### 焦点变更示意图

![epgjs-lifecycle.jpg](https://gitee.com/wujialei/xmepg/raw/master/packages/epgjs/imgs/epgjs-lifecycle.jpg)



### API

> epgjs 初始化参数配置

`var EPG = new epgjs(options);`

* options.interval  `Number` 遥控器按键触发间隔
* options.prefix  `String` 元素上事件名前缀，默认为：`@`, 例：`@left`、`@default` 等
* options.keyNumbers `Object` 遥控器数字按键配置设置
* options.keyActions `Object` 定义遥控器事件 

以下配置中的按键数字值均可按照各平台差异进行修改，也可新增其他自定义事件

  ```
	//默认值 options.keyNumbers
	const keyNumbers = {
    KC_0: 0, //数字按键 0 
    KC_1: 1, //数字按键 1 
    KC_2: 2, //数字按键 2 
    KC_3: 3, //数字按键 3 
    KC_4: 4, //数字按键 4 
    KC_5: 5, //数字按键 5 
    KC_6: 6, //数字按键 6 
    KC_7: 7, //数字按键 7 
    KC_8: 8, //数字按键 8 
    KC_9: 9, //数字按键 9 
	}

	//默认值 keyActions
	const keyActions = {
    KC_0: [48], //数字按键 0 
    KC_1: [49], //数字按键 1 
    KC_2: [50], //数字按键 2 
    KC_3: [51], //数字按键 3 
    KC_4: [52], //数字按键 4 
    KC_5: [53], //数字按键 5 
    KC_6: [54], //数字按键 6 
    KC_7: [55], //数字按键 7 
    KC_8: [56], //数字按键 8 
    KC_9: [57], //数字按键 9 
    KC_OK: [13],  //按键 确定
    KC_BACK: [
        8,
        32, /*空格键*/
        45, /*兼容云平台*/
        340, /*ipannel 返回*/
        1249, /*兼容烽火盒子*/
    ], //按键 返回
    KC_LEFT: [
        37,
        3,  /*ipannel*/
    ], //按键 向左
    KC_RIGHT: [
        39,
        4,  /*ipannel*/
    ], //按键 向左
    KC_UP: [
        38,
        1,  /*ipannel*/
    ], //按键 向上
    KC_DOWN: [
        40,
        2, /*ipannel*/
    ], //按键 向下
    KC_PAGEUP: [33], //上一页
    KC_PAGEDOWN: [34], //下一页
    KC_VOLUP: [259], //音量 +
    KC_VOLDOWN: [260], //音量减
    KC_MUTE: [263], //静音键
	}
	```

> EPG Apis

* `EPG.registerView(options, scope); ` 注册新的画布
	* options.root `String`  画布的css选择器，例：`#container`
	* options.selector `String` 元素的css选择器，例：`.btn, div.item, .btn[name=xxx]`等，
	* options.autoScan `Boolean` 是否自动扫描画布 默认为：`true`
* `EPG.scan()` 立即扫描当前画布上下所有元素
* `EPG.click()` 立即触发确认按钮行为
* `EPG.back()` 立即触发返回按钮行为
* `EPG.move(direction)` 立即触发指定方向上的移动行为
	* direction 枚举`left`,`right`,`up`,`down`
* `EPG.moveTo(target)` 立即选中target元素为新焦点
	* target `String` 移动到目标元素的css选择器或Element对象
* `EPG.getCssPath(target)` 获取元素的csspath
	* target `String` 移动到目标元素的css选择器或Element对象
* `EPG.getCurrentView()` 获取当前正在操作的画布对象
* `EPG.closeCurrentView` 关闭当前正在操作的画布对象（当且仅当画布大于1时）