/**
* @file menu.js
*/
從 '../component.js' 導入組件;
從“全局/文檔”導入文檔;
import * as Dom from '../utils/dom.js';
import * as Events from '../utils/events.js';
從“鍵碼”導入鍵碼;
/**
* Menu組件用於構建彈出菜單,包括字幕和
* 字幕選擇菜單。
*
* @extends 組件
*/
類菜單擴展組件{
/**
* 創建此類的一個實例。
*
* @param {Player} 播放器
* 這個組件應該附加到的播放器
*
* @param {對象} [選項]
* 選項名稱和值的對象
*
*/
構造函數(播放器,選項){
超級(播放器,選項);
如果(選項){
this.menuButton_ = options.menuButton;
}
this.focusedChild_ = -1;
this.on('keydown', (e) => this.handleKeyDown(e));
// 所有菜單項實例共享菜單容器提供的相同模糊處理程序。
this.boundHandleBlur_ = (e) => this.handleBlur(e);
this.boundHandleTapClick_ = (e) => this.handleTapClick(e);
}
/**
* 將事件偵聽器添加到 {@link MenuItem}。
*
* @param {Object} 組件
* 要添加偵聽器的 `MenuItem` 實例。
*
*/
addEventListenerForItem(組件){
if (!(component instanceof Component)) {
返回;
}
this.on(component, 'blur', this.boundHandleBlur_);
this.on(component, ['tap', 'click'], this.boundHandleTapClick_);
}
/**
* 從 {@link MenuItem} 中移除事件偵聽器。
*
* @param {Object} 組件
* 用於移除偵聽器的 `MenuItem` 實例。
*
*/
removeEventListenerForItem(組件){
if (!(component instanceof Component)) {
返回;
}
this.off(component, 'blur', this.boundHandleBlur_);
this.off(component, ['tap', 'click'], this.boundHandleTapClick_);
}
/**
* 該方法將在添加組件時間接調用
* 在組件通過 addItem 添加到新菜單實例之前。
* 在這種情況下,原始菜單實例將刪除該組件
* 通過調用 `removeChild`。
*
* @param {Object} 組件
* `MenuItem` 的實例
*/
removeChild(組件){
if (typeof component === 'string') {
組件 = this.getChild(組件);
}
this.removeEventListenerForItem(組件);
super.removeChild(組件);
}
/**
* 添加一個 {@link MenuItem} 到菜單。
*
* @param {Object|string} 組件
* 要添加的 `MenuItem` 的名稱或實例。
*
*/
添加項目(組件){
const childComponent = this.addChild(component);
如果(子組件){
this.addEventListenerForItem(childComponent);
}
}
/**
* 創建“菜單”的 DOM 元素。
*
* @return {元素}
* 創建的元素
*/
創建El() {
常量 contentElType = this.options_.contentElType || 'ul';
this.contentEl_ = Dom.createEl(contentElType, {
className: 'vjs-menu-content'
});
this.contentEl_.setAttribute('角色', '菜單');
const el = super.createEl('div', {
追加:this.contentEl_,
類名:'vjs-menu'
});
el.appendChild(this.contentEl_);
// 防止點擊冒泡。需要菜單按鈕,
// 對父級的點擊很重要
Events.on(el, 'click', function(event) {
事件.preventDefault();
event.stopImmediatePropagation();
});
返回 el;
}
處置(){
this.contentEl_ = null;
this.boundHandleBlur_ = null;
this.boundHandleTapClick_ = null;
super.dispose();
}
/**
* 當 `MenuItem` 失去焦點時調用。
*
* @param {EventTarget~Event} 事件
* 導致調用此函數的 `blur` 事件。
*
* @listens 模糊
*/
句柄模糊(事件){
常量 relatedTarget = event.relatedTarget ||文檔.activeElement;
// 當用戶在菜單外點擊時關閉彈出菜單
如果 (!this.children().some((元素) => {
返回 element.el() === 相關目標;
})) {
const btn = this.menuButton_;
如果 (btn && btn.buttonPressed_ && relatedTarget !== btn.el().firstChild) {
btn.unpressButton();
}
}
}
/**
* 當單擊或點擊 `MenuItem` 時調用。
*
* @param {EventTarget~Event} 事件
* 導致調用此函數的 `click` 或 `tap` 事件。
*
* @listens 點擊,點擊
*/
handleTapClick(事件){
// 取消按下關聯的 MenuButton,並將焦點移回它
如果(this.menuButton_){
這個.menuButton_.unpressButton();
const childComponents = this.children();
如果 (!Array.isArray(childComponents)) {
返回;
}
const foundComponent = childComponents.filter(component => component.el() === event.target)[0];
如果(!foundComponent){
返回;
}
// 如果項目是標題設置項目,則不要聚焦菜單按鈕
// 因為焦點會移動到別處
if (foundComponent.name() !== 'CaptionSettingsMenuItem') {
這個.menuButton_.focus();
}
}
}
/**
* 處理此菜單上的 `keydown` 事件。這個偵聽器被添加到構造函數中。
*
* @param {EventTarget~Event} 事件
* 菜單上發生的 `keydown` 事件。
*
* @listens 按鍵
*/
handleKeyDown(事件){
// 向左和向下箭頭
if (keycode.isEventKey(event, 'Left') || keycode.isEventKey(event, 'Down')) {
事件.preventDefault();
事件.stopPropagation();
這個.stepForward();
// 向上和向右箭頭
} else if (keycode.isEventKey(event, 'Right') || keycode.isEventKey(event, 'Up')) {
事件.preventDefault();
事件.stopPropagation();
這個.stepBack();
}
}
/**
* 移動到鍵盤用戶的下一個(下)菜單項。
*/
向前一步() {
讓 stepChild = 0;
如果(this.focusedChild_!==未定義){
stepChild = this.focusedChild_ + 1;
}
this.focus(stepChild);
}
/**
* 移動到鍵盤用戶的上一個(更高)菜單項。
*/
退後() {
讓 stepChild = 0;
如果(this.focusedChild_!==未定義){
stepChild = this.focusedChild_ - 1;
}
this.focus(stepChild);
}
/**
* 將焦點放在 `Menu` 中的 {@link MenuItem} 上。
*
* @param {對象|字符串} [item=0]
* 子項集的索引。
*/
焦點(項目= 0){
const children = this.children().slice();
const haveTitle = children.length && children[0].hasClass('vjs-menu-title');
如果(有標題){
兒童班次();
}
如果(孩子。長度> 0){
如果(項目 < 0){
項目 = 0;
} else if (item >= children.length) {
item = children.length - 1;
}
this.focusedChild_ = item;
兒童[項目].el_.focus();
}
}
}
Component.registerComponent('Menu', Menu);
導出默認菜單;