Javascript 将Iframe传递给SPA中的不同组件(类似于Youtube)
因此,由于Youtube有一段时间可以在页面导航时最小化Youtube播放器的功能,LolEsports.com与Twitch和嵌入式Youtube播放器有类似的功能 我想给我的页面带来一个类似的功能,基本上我的状态如下:Javascript 将Iframe传递给SPA中的不同组件(类似于Youtube),javascript,html,css,vue.js,Javascript,Html,Css,Vue.js,因此,由于Youtube有一段时间可以在页面导航时最小化Youtube播放器的功能,LolEsports.com与Twitch和嵌入式Youtube播放器有类似的功能 我想给我的页面带来一个类似的功能,基本上我的状态如下: 前端的Vue 在子URL上嵌入Youtube播放器 当我离开子URL时,我希望Youtube播放器移动到当前状态的角落,并且仍然在那里 我希望听到一些关于如何实现这一点的灵感,因为当我尝试在不同组件上传递状态重置时,以及播放停止等 我很想听听你的想法。简单的回答是:你不能
- 前端的Vue
- 在子URL上嵌入Youtube播放器
- 当我离开子URL时,我希望Youtube播放器移动到当前状态的角落,并且仍然在那里
我很想听听你的想法。简单的回答是:你不能移动iframe DOM节点而不丢失它的状态,如前所述 答案很长:你有其他选择。我认为你最好的办法是直接在“角落播放器”中播放视频,然后重新设置样式,使其位于页面的正确位置。要做到这一点,您需要自己与DOM进行一些交互,通过在希望视频显示的容器上设置
ref
,您可以轻松地进行交互
最后你会得到这样的结果:
在App.vue中,您有标准的路由器视图
,以及一些包含实际视频的元素
<template>
<div id="app">
<router-view/>
<corner-player/>
</div>
</template>
播放器组件然后使用这两个事件,并确保应用了正确的样式。我不建议像这里这样应用原始css,但这是一个概念证明
<template>
<div class="corner-player" :style="styling" v-if="url">
<iframe
width="1280"
height="540"
:src="url"
frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
</template>
<script>
export default {
name: "CornerPlayer",
data() {
return {
styling: {},
url: "",
defaultStyling: {
border: "3px solid blue",
position: "fixed",
bottom: 0,
right: 0,
height: "150px",
width: "220px"
}
};
},
created() {
this.$bus.$on("play-video", this.playVideo);
this.$bus.$on("move-to-corner-player", this.moveToCornerPlayer);
},
beforeDestroy() {
// Prevent memory leaks
this.$bus.$off("play-video", this.playVideo);
this.$bus.$off("move-to-corner-player", this.moveToCornerPlayer);
},
methods: {
playVideo({ url, styling }) {
this.url = url;
this.styling = styling;
},
moveToCornerPlayer() {
this.styling = {
...this.defaultStyling
};
}
}
};
</script>
<style scoped>
iframe {
width: 100%;
height: 100%;
}
</style>
导出默认值{
姓名:“角落玩家”,
数据(){
返回{
样式:{},
url:“”,
默认样式:{
边框:“3件纯蓝”,
位置:“固定”,
底部:0,
右:0,,
高度:“150px”,
宽度:“220px”
}
};
},
创建(){
this.$bus.$on(“播放视频”,this.playVideo);
this.$bus.$on(“移动到角落玩家”,this.moveToCornerPlayer);
},
在…之前{
//防止内存泄漏
this.$bus.$off(“播放视频”,this.playVideo);
此。$bus。$off(“移动到角落玩家”,此。移动到角落玩家);
},
方法:{
播放视频({url,样式设置}){
this.url=url;
this.style=样式化;
},
moveToCornerPlayer(){
此项。样式设置={
…这是默认样式
};
}
}
};
iframe{
宽度:100%;
身高:100%;
}
您可以在Codesandbox上玩这个:
谢谢Sumurai8!为了使iframe容器更具响应性,我对您的CodeSandbox进行了一些编辑:
因此,现在在滚动和刷新时,容器将缩放并保持在相同的位置。非常感谢您非常有趣的方法,我尝试将其引入我的应用程序,并成功地实现了这一点,我决定不使用事件总线,而是选择Vuex,但我想如果不是为了简单起见,你也会这么做。可能会使用事件总线来处理事件,比如通过时间戳向前跳转,因为如果没有观察者和商店的东西,这是行不通的,除非有更好的方法让我知道:)是的,Vuex也可以工作。在这种情况下,您将处理vuex模块中的状态,而不是组件中的状态。除此之外,同样的情况仍然适用。我同意使用事件跳过视频可能是最好的选择,特别是如果您使用某种库与播放器交互,而不仅仅是用一些神奇的url重新加载iframe。
export default {
name: "child1",
mounted() {
const container = this.$refs.player;
const boundingBox = container.getBoundingClientRect();
this.$bus.$emit("play-video", {
url: "https://www.youtube.com/embed/dW4HCi1zZh8",
styling: {
position: "absolute",
top: `${boundingBox.top}px`,
left: `${boundingBox.left}px`,
width: `${boundingBox.width}px`,
height: `${boundingBox.height}px`,
border: "3px dotted red"
}
});
},
beforeDestroy() {
this.$bus.$emit("move-to-corner-player");
}
};
<template>
<div class="corner-player" :style="styling" v-if="url">
<iframe
width="1280"
height="540"
:src="url"
frameborder="0"
allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture"
allowfullscreen
></iframe>
</div>
</template>
<script>
export default {
name: "CornerPlayer",
data() {
return {
styling: {},
url: "",
defaultStyling: {
border: "3px solid blue",
position: "fixed",
bottom: 0,
right: 0,
height: "150px",
width: "220px"
}
};
},
created() {
this.$bus.$on("play-video", this.playVideo);
this.$bus.$on("move-to-corner-player", this.moveToCornerPlayer);
},
beforeDestroy() {
// Prevent memory leaks
this.$bus.$off("play-video", this.playVideo);
this.$bus.$off("move-to-corner-player", this.moveToCornerPlayer);
},
methods: {
playVideo({ url, styling }) {
this.url = url;
this.styling = styling;
},
moveToCornerPlayer() {
this.styling = {
...this.defaultStyling
};
}
}
};
</script>
<style scoped>
iframe {
width: 100%;
height: 100%;
}
</style>