效果:
知识抢先看:
动态创建节点指的是通过 JavaScript 操作 DOM 来生成 HTML 元素并插入到页面中
document.createElement
: 创建新的 HTML 元素节点。// 创建一个 <div> 元素 const div = document.createElement('div'); // 设置其属性 div.id = 'myDiv'; div.className = 'container'; div.textContent = 'This is a dynamically created div'; // 添加到 body 中 document.body.appendChild(div);//创建嵌套元素 // 创建父节点 const parentDiv = document.createElement('div'); parentDiv.className = 'parent';// 创建子节点 const childSpan = document.createElement('span'); childSpan.textContent = 'I am a child element';// 将子节点插入父节点 parentDiv.appendChild(childSpan);// 将父节点插入到页面 document.body.appendChild(parentDiv);//动态插入到特定位置 const newDiv = document.createElement('div'); newDiv.textContent = 'Inserted before existing content';const referenceNode = document.getElementById('existingElement'); referenceNode.parentNode.insertBefore(newDiv, referenceNode);
node.appendChild
: 将新创建的元素添加为父节点的子节点。// 当需要动态创建并插入大量节点时,直接操作 DOM 可能导致性能问题。DocumentFragment 是一个轻量级的文档片段,可以减少对 DOM 的多次操作 const fragment = document.createDocumentFragment();for (let i = 0; i < 100; i++) {const div = document.createElement('div');div.textContent = `Item ${i + 1}`;fragment.appendChild(div); }// 一次性插入到 DOM document.body.appendChild(fragment);
parentNode.insertBefore
: 在指定节点前插入新节点。node.removeChild
: 删除子节点。const element = document.getElementById('myDiv'); if (element) {element.parentNode.removeChild(element); // 删除该节点 }
element.innerHTML
: 设置或获取 HTML 内容。//⚠️ 注意:innerHTML 会替换节点内的所有内容,不适用于复杂 DOM 操作 const container = document.createElement('div'); container.innerHTML = `<ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul> `; document.body.appendChild(container);
①在index.html引入路径
<script type="text/javascript" src="/static/js/EasyPlayer-pro.js"></script>
②封装视频组件
<template><div class="easy-player-container"><!-- 为每个播放器容器添加唯一的类 --><div id="player_box1" class="player-box"></div></div>
</template><script>
/* global EasyPlayerPro */
export default {name: 'EasyPlayerPro',props: {initialConfig: {type: Object,default: () => ({}),},},data () {return {player: '',playerInstances: {}, // 存储播放器实例config: {hasAudio: true,isLive: true,MSE: false,WCS: false,...this.initialConfig,},};},beforeUnmount () {this.destroyAllPlayers();},methods: {// 设置视频 URL,如果播放器不存在则创建新播放器setVideoUrl (url, id, changeId) {this.player = changeId;const videoObject = { url, id };const player = this.playerInstances[id];if (player) {player.play(url).catch(e => {console.error(`播放失败 (播放器${id}):`, e);this.$emit('play-error', e);});} else {this.createPlayer(id, url);}},// 创建单个播放器实例createPlayer (id, url) {if (this.playerInstances[id]) {console.log(`播放器 ${id} 已存在,不重复创建`);return;}this.$nextTick(() => {setTimeout(() => {const container = document.getElementById(`${this.player}`)if (!container || !(container instanceof Element)) {console.error(`未找到有效容器,ID: ${id}`);return;}const player = new EasyPlayerPro(container, {demuxType: "webrtc",isLive: this.config.isLive,// 是否直播bufferTime: 0.2,// 缓冲时间stretch: false, // 是否拉伸MSE: this.config.MSE,// 是否使用MSEWCS: this.config.WCS,// 是否使用WCShasAudio: true,// 是否有音频// hasVideo: true,// 是否有视频// hasSubtitle: true,// 是否有字幕watermark: {// 水印text: { content: 'easyplayer-pro' },right: 10,top: 10,},});player.play(url).then(() => {this.$emit('play-started', id);}).catch((e) => {console.error(`播放失败 (播放器${id}):`, e);this.$emit('play-error', e);});// 添加事件监听player.on("fullscreen", (flag) => {this.$emit('fullscreen-change', flag);});player.on('playbackRate', (rate) => {player.setRate(rate);this.$emit('rate-change', rate);});player.on('playbackSeek', (data) => {this.$emit('seek', data);});this.playerInstances[id] = player;}, 100); // 延迟100毫秒});},// 销毁所有播放器实例destroyAllPlayers () {Object.keys(this.playerInstances).forEach(id => {this.destroyPlayer(id);});},// 销毁单个播放器实例destroyPlayer (id) {const player = this.playerInstances[id];if (player) {player.destroy();delete this.playerInstances[id];}}},
};
</script><style scoped>
.easy-player-container {width: 100%;background: #000;height: 100%;position: relative;
}.player-box {background: #000;
}
</style>
J
③应用
<template><div class="video-box"><EasyWebRTC ref="videoRef"></EasyWebRTC></div>
</template>
<script>
import EasyWebRTC from "@/components/EasyWebRTC.vue";//引入自己存储的封装组件路径
let url = "指定播放的url路径"
onMounted(() => {nextTick(() => {if (videoRef.value) {const containerId = `videoId`videoRef.value.setVideoUrl(url, containerId, containerId)const parentEle = document.getElementsByClassName('video-box')if (parentEle) {const targetChild = parentEle.querySelector('#player_box1');if (targetChild) {targetChild.id = `${containerId}`; // 修改 id} else {console.warn('未找到 id 为 "player_box1" 的孙子节点');}} else {console.warn('未找到父元素:', `${containerId}`);}} else {console.error("EasyPlayerRef 未挂载");}})
})
</script>