最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

vue.js - why videojs not re-initialize in vuejs? - Stack Overflow

programmeradmin5浏览0评论

How can I reinitialize Video.js with new options when props.options changes in a Vue.js (Vue 3) component using the watch function?

current code:

const videoPlayer = ref<HTMLVideoElement>()
const player = ref<Player>() 

watch(
() => props.options,
(newOptions) => {
if (player.value) {
  player.value.dispose();
}

nextTick(()=>{
  if (videoPlayer.value) {

  player.value = videojs(videoPlayer.value, newOptions)
  player.value.loop(newOptions.loop)

}
})
},{ deep: true }) 

it shows :

VideoPlayer.vue:162 VIDEOJS: WARN: The element supplied is not included in the DOM  errr in this line 

How can I reinitialize Video.js with new options when props.options changes in a Vue.js (Vue 3) component using the watch function?

current code:

const videoPlayer = ref<HTMLVideoElement>()
const player = ref<Player>() 

watch(
() => props.options,
(newOptions) => {
if (player.value) {
  player.value.dispose();
}

nextTick(()=>{
  if (videoPlayer.value) {

  player.value = videojs(videoPlayer.value, newOptions)
  player.value.loop(newOptions.loop)

}
})
},{ deep: true }) 

it shows :

VideoPlayer.vue:162 VIDEOJS: WARN: The element supplied is not included in the DOM  errr in this line 
Share Improve this question asked Mar 22 at 5:15 ArjitArjit 366 bronze badges 3
  • Please, provide a way to reproduce, needs to be debugged. The error suggests the element could be detached. It looks like this is the case docs.videojs/tech_html5.js#line1385 This is certainly a mistake from videojs side because this is destructive behaviour that couldn't be expected from a cleanup operation – Estus Flask Commented Mar 22 at 8:10
  • Thanks for your comments, I get it now. It's because when I call player.value.dispose(), Video.js removes the video element from the DOM. Since videoPlayer.value is referencing that element, it becomes null, and initializing Video.js again fails. – Arjit Commented Mar 22 at 9:35
  • Yes, what dispose does isn't a common way for libs, this the first time i see something like this. Modifying dom generated by vue should be prevented, what you do in the answer seems to be the right workaround here – Estus Flask Commented Mar 22 at 10:40
Add a comment  | 

1 Answer 1

Reset to default 2

The issue occurs because when calling player.value.dispose(), Video.js removes the <video> element from the DOM. Since videoPlayer.value is referencing that element, it becomes null, and initializing Video.js again fails.

To fix this, instead of referencing the <video> element directly, I created a wrapper <div> (e.g., videoContainer) as a parent container. Then, whenever Video.js is reinitialized, I dynamically add the <video> element as its child.

This ensures that the <video> element is properly recreated before initializing Video.js again.

fixed code:

const videoContainer = ref<HTMLVideoElement>() // ref to parent elem
const player = ref<Player>()

const initPlayer = () => {
  if (!videoContainer.value) return

  // Remove existing video element if present
  videoContainer.value.innerHTML = ''

  // Create a new video element dynamically
  const videoElement = document.createElement('video')
  videoElement.className = 'video-js vjs-youtube'

  // Append the new video element to the container
  videoContainer.value.appendChild(videoElement)

  // Initialize Video.js on the new video element
  nextTick(() => {
    player.value = videojs(videoElement, props.options)
    player.value.loop(props.options.loop)
  })
}


// Initialize video.js when the component is mounted
onMounted(() => {
  initPlayer()
})

// Watch for changes in the options prop
watch(
  () => props.options,
  (newOptions) => {
    if (player.value) {
      // now its remove the dynamically created video elem insted of ref elem
      player.value.dispose()
    }
    // re-initialize of videojs with new opions
    initPlayer()
  },
  { deep: true }
)

// Destroy video.js when the component is unmounted
onBeforeUnmount(() => {
  if (player.value) {
    player.value.dispose()
  }
})
</script>


<template>
  <div ref="videoContainer"></div>//this is the wraper element
</template>
发布评论

评论列表(0)

  1. 暂无评论