videojs / video.js

Video.js - open source HTML5 video player
https://videojs.com
Other
38.09k stars 7.45k forks source link

No MenuItem elements in DOM #8517

Closed rudachenkoev closed 11 months ago

rudachenkoev commented 11 months ago

Description

Hey, everybody. Please help me with the problem that menu items don't appear in the DOM after adding. I am using Vue.js 2 and plugin version ^8.6.1. What am I doing wrong?

setupPlayer () {
      if (!this.$refs.videoPlayer) return false
      this.player = videojs(this.$refs.videoPlayer, this.options, () => {

        let MenuItem = videojs.getComponent('MenuItem')
        let MenuButton = videojs.getComponent('MenuButton')

        let settingButton = new MenuButton(this.player)
        settingButton.setIcon('cog')

        let settingMenu = settingButton.createMenu()
        for (let quality of this.options.scaledFiles) {
          let qualityItem = new MenuItem(this.player, { label: quality.resolution })
          settingMenu.addItem(qualityItem)
        }
        settingButton.on('click', () => settingMenu.show())
        this.player.getChild('ControlBar').addChild(settingButton)
      })
    }

photo_2023-12-12 18 58 12

Reduced test case

https://no.url.com

Steps to reproduce

  1. Creating MenuButton
  2. Create menu inside MenuButton using .createMenu()
  3. Add MenuItem using .addItem()

Errors

No errors

What version of Video.js are you using?

^8.6.1

Video.js plugins used.

No response

What browser(s) including version(s) does this occur with?

Chrome 120.0.6099.71

What OS(es) and version(s) does this occur with?

Macos

welcome[bot] commented 11 months ago

πŸ‘‹ Thanks for opening your first issue here! πŸ‘‹

If you're reporting a 🐞 bug, please make sure you include steps to reproduce it. We get a lot of issues on this repo, so please be patient and we will get back to you as soon as we can. To help make it easier for us to investigate your issue, please follow the contributing guidelines.

amtins commented 11 months ago

@rudachenkoev what about something like?

function setupPlayer() {
  if (!this.$refs.videoPlayer) return false;
  this.player = videojs(this.$refs.videoPlayer, this.options, () => {
    let MenuItem = videojs.getComponent('MenuItem');
    let MenuButton = videojs.getComponent('MenuButton');

    MenuButton.prototype.createItems = function (
      options = this.options.scaledFiles
    ) {
      const items = [];

      for (let quality of options) {
        items.push(new MenuItem(this.player(), { label: quality.resolution }));
      }

      return items;
    };

    let settingButton = new MenuButton(this.player);
    settingButton.setIcon('cog');

    this.player.getChild('ControlBar').addChild(settingButton);
  });
}
rudachenkoev commented 11 months ago

@amtins thank you for your reply your option worked for me, just with a few minor changes perhaps this will also be useful for someone else

MenuButton.prototype.createItems = function (options = this.options.scaledFiles) { ... } => MenuButton.prototype.createItems = (options = this.options.scaledFiles) => { ... }

items.push(new MenuItem(this.player(), { label: quality.resolution })); => items.push(new MenuItem(this.player, { label: quality.resolution }));

mister-ben commented 11 months ago

The reason it didn't work is settingButton.createMenu() will create a new but detached menu DOM. It doesn't return or replace the original one. let settingMenu = settingButton.menu; should work in your original code.

rudachenkoev commented 11 months ago

@mister-ben yeah, it really works, thanks perhaps you can give some more advice on the "selected" option in MenuItem I want to highlight one of the options as active, but none of the following options helped me:

  1. qualityItem.selected(true)
  2. let qualityItem = new MenuItem(this.player, { label: quality.resolution, selected: true })
rudachenkoev commented 11 months ago

figured it out. To make MenuItem with selectable option you need to add the option selectable: true - new MenuItem(this.player, { label: quality.resolution, selectable: true }) although there is nothing about it in the documentation