component(组件)

video.js播放器的架构以组件为中心。Player类和所有表示Player控件和其他UI元素的类都继承自Component类。这种体系结构使得在DOM的树形结构中构造Video.js播放器的UI界面变得很容易。


什么是组件?

组件是具有以下功能的JavaScript对象:

  • 在几乎所有情况下,一个关联的DOM元素。
  • 与Player对象的关联。
  • 管理任何数量的子组件的能力。
  • 侦听和触发事件的能力。
  • 初始化和处置的生命周期。


创建一个组件

video.js组件可以被继承并向Video.js注册,以添加新的功能和UI到播放器。

这是一个创建组件的例子,我们使用了一个JSBin来演示如何创建一个组件,该组件用于在播放器的顶部显示标题。

此外,还有一些方法值得认识:

videojs.getComponent(String name):从Video.js检索组件构造函数。

videojs.registerComponent(String name, Function Comp):向Video.js注册组件构造函数。

videojs.extend(Function component, Object properties):提供原型继承,可用于扩展组件的构造函数,并返回具有给定属性的新构造函数。

// 为播放器添加一个按钮
var player = videojs('some-video-id');
var Button = videojs.getComponent('Button');
var button = new Button(player, {
  clickHandler: function(event) {
    videojs.log('Clicked');
  }
});

console.log(button.el());

上面的代码输出

<div class="video-js">
  <div class="vjs-button">Button</div>
</div>

将新按钮添加到播放器

// 添加按钮到播放器
var player = videojs('some-video-id');
var button = player.addChild('button');

console.log(button.el());
// 会生成上面的html


子组件

简单例子

当子组件被添加到父组件时,Video.js将子组件的元素插入到父组件的元素中。

例如,添加这样的组件:

// 添加一个"BigPlayButton"组件到播放器. 
player.addChild('BigPlayButton');

产生一个如下所示的DOM:

<div class="video-js">
  <div class="vjs-big-play-button"></div>
</div>

相反,删除子组件将从DOM中删除子组件的元素:

player.removeChild('BigPlayButton');
产生一个如下所示的DOM:
<div class="video-js">
</div>

使用选项

为子构造函数传递选项,为子代传递选项。

var player = videojs('some-vid-id');
var Component = videojs.getComponent('Component');
var myComponent = new Component(player);
var myButton = myComponent.addChild('MyButton', {
  text: 'Press Me',
  buttonChildExample: {
    buttonChildOption: true
  }
});
初始化组件时,还可以通过选项添加子项。

注意:包括一个“name”键,如果两个相同类型的子组件需要不同的选项,则将使用该键。

// MyComponent来自上面的例子
var myComp = new MyComponent(player, {
  children: ['button', {
    name: 'button',
    someOtherOption: true
  }, {
    name: 'button',
    someOtherOption: false
  }]
});


事件监听

使用 on

var player = videojs('some-player-id');
var Component = videojs.getComponent('Component');
var myComponent = new Component(player);
var myFunc = function() {
  var myComponent = this;
  console.log('myFunc called');
};

myComponent.on('eventType', myFunc);
myComponent.trigger('eventType'); 

myFunc的上下文将是myComponent,除非它被绑定。可以将侦听器添加到另一个元素或组件。

var otherComponent = new Component(player);

// myComponent/myFunc is from the above example
myComponent.on(otherComponent.el(), 'eventName', myFunc);
myComponent.on(otherComponent, 'eventName', myFunc);

otherComponent.trigger('eventName');
// logs 'myFunc called' twice

使用 off

var player = videojs('some-player-id');
var Component = videojs.getComponent('Component');
var myComponent = new Component(player);
var myFunc = function() {
  var myComponent = this;
  console.log('myFunc called');
};
myComponent.on('eventType', myFunc);
myComponent.trigger('eventType');
// logs 'myFunc called'

myComponent.off('eventType', myFunc);
myComponent.trigger('eventType');
// does nothing

如果myFunc被排除,所有事件类型的监听器将被删除。如果排除了eventType,则将从组件中删除所有侦听器。您可以使用off来删除添加到其他元素或组件的监听器:

myComponent.on(otherComponent...

在这种情况下,事件类型和侦听器功能都是必需的。

var otherComponent = new Component(player);

// myComponent/myFunc is from the above example
myComponent.on(otherComponent.el(), 'eventName', myFunc);
myComponent.on(otherComponent, 'eventName', myFunc);

otherComponent.trigger('eventName');
// logs 'myFunc called' twice
myComponent.off(ootherComponent.el(), 'eventName', myFunc);
myComponent.off(otherComponent, 'eventName', myFunc);
otherComponent.trigger('eventName');
// does nothing

Using one

var player = videojs('some-player-id');
var Component = videojs.getComponent('Component');
var myComponent = new Component(player);
var myFunc = function() {
  var myComponent = this;
  console.log('myFunc called');
};
myComponent.one('eventName', myFunc);
myComponent.trigger('eventName');
// logs 'myFunc called'

myComponent.trigger('eventName');
// does nothing
您还可以将侦听器添加到将仅触发一次的另一个元素或组件。
var otherComponent = new Component(player);

// myComponent/myFunc is from the above example
myComponent.one(otherComponent.el(), 'eventName', myFunc);
myComponent.one(otherComponent, 'eventName', myFunc);

otherComponent.trigger('eventName');
// logs 'myFunc called' twice

otherComponent.trigger('eventName');
// does nothing

Using trigger

var player = videojs('some-player-id');
var Component = videojs.getComponent('Component');
var myComponent = new Component(player);
var myFunc = function(data) {
  var myComponent = this;
  console.log('myFunc called');
  console.log(data);
};
myComponent.one('eventName', myFunc);
myComponent.trigger('eventName');
// logs 'myFunc called' and 'undefined'

myComponent.trigger({'type':'eventName'});
// logs 'myFunc called' and 'undefined'

myComponent.trigger('eventName', {data: 'some data'});
// logs 'myFunc called' and "{data: 'some data'}"

myComponent.trigger({'type':'eventName'}, {data: 'some data'});
// logs 'myFunc called' and "{data: 'some data'}"


默认组件树

Video.js播放器的默认组件结构如下所示:

Player
├── MediaLoader (has no DOM element)
├── PosterImage
├── TextTrackDisplay
├── LoadingSpinner
├── BigPlayButton
├── LiveTracker (has no DOM element)
├─┬ ControlBar
│ ├── PlayToggle
│ ├── VolumePanel
│ ├── CurrentTimeDisplay (hidden by default)
│ ├── TimeDivider (hidden by default)
│ ├── DurationDisplay (hidden by default)
│ ├─┬ ProgressControl (hidden during live playback, except when liveui: true)
│ │ └─┬ SeekBar
│ │   ├── LoadProgressBar
│ │   ├── MouseTimeDisplay
│ │   └── PlayProgressBar
│ ├── LiveDisplay (hidden during VOD playback)
│ ├── SeekToLive (hidden during VOD playback)
│ ├── RemainingTimeDisplay
│ ├── CustomControlSpacer (has no UI)
│ ├── PlaybackRateMenuButton (hidden, unless playback tech supports rate changes)
│ ├── ChaptersButton (hidden, unless there are relevant tracks)
│ ├── DescriptionsButton (hidden, unless there are relevant tracks)
│ ├── SubtitlesButton (hidden, unless there are relevant tracks)
│ ├── CaptionsButton (hidden, unless there are relevant tracks)
│ ├── SubsCapsButton (hidden, unless there are relevant tracks)
│ ├── AudioTrackButton (hidden, unless there are relevant tracks)
│ ├── PictureInPictureToggle
│ └── FullscreenToggle
├── ErrorDisplay (hidden, until there is an error)
├── TextTrackSettings
└── ResizeManager (hidden)

特定组件详细信息

播放切换

将PlayToggle有一个选项replay可以显示或隐藏重播图标。可以通过传递设置,{replay: false}因为在视频结束播放后会显示默认的行为重播图标。
如何隐藏重播图标的示例
let player = videojs('myplayer', {
  controlBar: {
    playToggle: {
      replay: false
    }
  }
});

音量面板

该VolumePanel包括MuteToggle和VolumeControl组件,如果不支持的数量的变化,这将被隐藏。有一个重要的选择VolumePanel,可以使您VolumeControl垂直出现在上MuteToggle。这可以通过将被设置VolumePanel {inline: false}为默认的行为是一个水平VolumeControl有{inline: true}。
垂直的例子 VolumeControl
let player = videojs('myplayer', {
  controlBar: {
    volumePanel: {
      inline: false
    }
  }
});

文字音轨设定

文本轨道设置组件仅在使用模拟文本轨道时可用。

调整大小经理

playerresize当播放器大小更改时,此新组件负责触发事件。它使用ResizeObserver(如果可用)或提供了polyfill。使用ResizeObserver时,它没有任何元素。如果ResizeObserver不可用,它将回退到iframe元素,并通过防抖动处理程序监听其resize事件。
ResizeObserver polyfill可以像这样传递:
var player = videojs('myplayer', {
  resizeManager: {
    ResizeObserver: ResizeObserverPoylfill
  }
});
要强制使用iframe后备广告,请null输入ResizeObserver:
var player = videojs('myplayer', {
  resizeManager: {
    ResizeObserver: null
  }
});
ResizeManager也可以像这样被禁用:
var player = videojs('myplayer', {
  resizeManager: false
});



上一篇:audio tracks(音轨) 下一篇:debugging(调试)