如何在VideoJS中添加含控制栏按钮列表的MenuItem?移动端按钮重叠处理
Hey there! Let's tackle your two Video.js questions one by one, with practical code examples and clear explanations.
问题1:创建包含控制栏按钮列表的MenuItem
Video.js's default MenuItem is a single option, but we can extend it to show a dropdown panel with multiple control buttons when clicked. Here's how to implement it step by step:
Extend the base MenuItem component
Usevideojs.extend()to inherit the base MenuItem, then override its element creation method to add a container for buttons and handle the toggle logic.// Custom MenuItem with button list const ButtonListMenuItem = videojs.extend(videojs.getComponent('MenuItem'), { constructor: function(player, options) { // Call parent constructor videojs.getComponent('MenuItem').call(this, player, options); // Initialize button list container this.buttonList = videojs.createEl('div', { className: 'vjs-button-list-container', style: 'display: none;' }); // Add container to MenuItem element this.el().appendChild(this.buttonList); // Toggle visibility on click this.on('click', () => { const isHidden = this.buttonList.style.display === 'none'; this.buttonList.style.display = isHidden ? 'block' : 'none'; }); }, // Method to add buttons to the list addButton(buttonComponent) { this.buttonList.appendChild(buttonComponent.el()); } }); // Register the custom component videojs.registerComponent('ButtonListMenuItem', ButtonListMenuItem);Add buttons to the MenuItem and attach it to the control bar
Create custom control buttons (or reuse existing ones), add them to our custom MenuItem, then place the MenuItem in the control bar.const player = videojs('my-video'); // Example: Create a quality toggle button const qualityButton = player.addChild('Button', { controlText: 'Quality', className: 'vjs-quality-button' }); // Bind click logic qualityButton.on('click', () => { console.log('Toggle quality'); // Add your quality switching logic here }); // Create our custom MenuItem const moreControlsMenu = player.addChild('ButtonListMenuItem', { label: 'More Controls', controlText: 'Additional controls' }); // Add the quality button to the MenuItem's list moreControlsMenu.addButton(qualityButton); // Add the MenuItem to the right side of the control bar player.getChild('ControlBar').addChild(moreControlsMenu, {}, 9);Add basic styling
Don't forget CSS to make the button list display properly:.vjs-button-list-container { position: absolute; bottom: 40px; right: 0; background: rgba(0,0,0,0.8); padding: 10px; border-radius: 4px; z-index: 100; } .vjs-button-list-container .vjs-button { display: block; margin: 5px 0; }
问题2:Fix overlapping control bar buttons on mobile
The core idea here is to listen for window resize events, and dynamically move buttons between the control bar and a MenuItem based on screen size. Here's the implementation plan:
Define breakpoint and movable buttons
Set a mobile breakpoint (e.g., 768px) and list which buttons should be moved to the MenuItem on small screens.Create a MenuItem to hold hidden buttons
Reuse theButtonListMenuItemwe built earlier, or create a simple MenuItem as a container.Listen for resize events and adjust button positions
Write a function to check window width, then move buttons between the control bar and MenuItem as needed.const player = videojs('my-video'); const controlBar = player.getChild('ControlBar'); // List of buttons to move (replace with your actual button components) const movableButtons = [qualityButton, subtitleButton]; // Mobile screen breakpoint const MOBILE_BREAKPOINT = 768; // Create MenuItem for mobile hidden buttons const mobileMenu = player.addChild('ButtonListMenuItem', { label: 'More', controlText: 'Additional options' }); // Function to adjust button positions function adjustControlButtons() { const isMobile = window.innerWidth < MOBILE_BREAKPOINT; movableButtons.forEach(button => { if (isMobile) { // Move button from control bar to MenuItem on mobile if (button.parentComponent() === controlBar) { controlBar.removeChild(button); mobileMenu.addButton(button); } } else { // Move button back to control bar on desktop if (button.parentComponent() === mobileMenu.buttonList) { mobileMenu.buttonList.removeChild(button.el()); controlBar.addChild(button, {}, 5); // Adjust position index as needed } } }); // Show/hide the MenuItem itself mobileMenu.el().style.display = isMobile && movableButtons.length > 0 ? 'block' : 'none'; } // Run once on page load adjustControlButtons(); // Listen for resize with debounce to avoid excessive triggers let resizeTimeout; window.addEventListener('resize', () => { clearTimeout(resizeTimeout); resizeTimeout = setTimeout(adjustControlButtons, 200); });Extra optimizations
- Debounce: The 200ms delay prevents the function from running constantly while dragging the window edge.
- Initial state check: Ensures buttons are in the right place when the page first loads.
- Style tweaks: Make sure the mobile MenuItem's button list doesn't go off-screen (adjust the CSS from the first question if needed).
内容的提问来源于stack exchange,提问作者Rawhani

