这段代码里的原生js怎么转成vue3啊
写了半天全是错
这段代码是想通过鼠标滑轮来控制视频的进度
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>苹果网站效果</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div class="container">
<video src="./video.webm"></video>
<div class="txt-item">
撒旦飒飒大<span>苏打实打</span> 实大苏打实打实的反对德里克十分激烈对抗放进了口袋精神分裂的
</div>
<div class="txt-item">
<div class="line"></div>
<div class="txt">
的时间反抗<span>类毒素解</span>放路口的就是浪费空间独立思考解放立刻搭街坊立刻决定离开房间地方大师傅大幅度随风倒十分
</div>
</div>
<div class="txt-item">
<div class="line"></div>
的房间里<span>电视机分</span>厘卡的就是浪费空间领导的洛杉矶发了大家分厘卡九点十六分雕刻技法角度来说
</div>
<div class="txt-item">
肯定就浪费了<span>扩大解释法</span>律框架的绿色开放的链接发来看的房间里的就是浪费的房间里的开发建设
</div>
</div>
<script>
// 原理,一个视频,根据滚动距离与整个body高度的比值 设置 对应视频的当前播放位置
const videoEl = document.querySelector('video')
const txtItems = document.querySelectorAll('.txt-item')
let duration = 0 // 视频总时长
videoEl.load() // 刚开始就让视频重新加载一下,有些时候会因为没加载导致下面的事件没触发
videoEl.addEventListener('durationchange', function(e){
duration = videoEl.duration
})
function showTxt(percent){
txtItems.forEach(dom => {
dom.className = 'txt-item'
})
// 当时常到百分之几时,对应的文字出现,这个随便调
if(percent > 5 && percent <= 33){
txtItems[0].className = 'txt-item active'
}else if(percent > 45 && percent <= 58){
}else if(percent > 45 && percent <= 58){
txtItems[1].className = 'txt-item active'
}else if(percent > 69 && percent <= 85){
txtItems[2].className = 'txt-item active'
}else if(percent > 90){
txtItems[3].className = 'txt-item active'
}
}
function updateCurrentTime(){
// 滚动的距离占总高度的多少,那当前时间就是总时长的多少 比如滚动的距离占body的50%那么,当前的时间就应该是总时长的50%
const percent = Math.ceil(window.scrollY) / (document.body.offsetHeight - window.innerHeight)
videoEl.currentTime = duration * percent
showTxt(percent*100)
}
document.addEventListener('scroll', updateCurrentTime)
</script>
</body>
</html>
这是部分是css
```css
<style>
body {
width: 100%;
height: 600vh;
margin: 0;
background-color: #000;
}
.container {
width: 1000px;
height: 100vh;
margin: 0 auto;
position: sticky;
top: 0;
color: #fff;
display: flex;
flex-direction: column;
}
video {
width: 400px;
display: block;
margin: auto;
}
.txt-item {
position: absolute;
width: 280px;
font-weight: bold;
color: gray;
transition: all .8s linear;
letter-spacing: 1px;
text-align: center;
font-size: 13px;
opacity: 0;
}
.txt-item span {
color: yellowgreen;
}
.txt-item.active {
opacity: 1;
}
.txt-item:nth-child(2) {
top: 80%;
left: 50%;
transform: translateX(-50%);
}
.txt-item:nth-child(3) {
width: 230px;
padding-top: 15px;
top: 60%;
left: 60%;
}
.txt-item:nth-child(3) .txt {
transition: all .3s linear;
transform: translateY(50px);
}
.txt-item:nth-child(3) .line {
border-top: 1px solid gray;
position: absolute;
top: 0;
right: 0;
width: 0;
transition: all .5s linear;
}
.txt-item:nth-child(3).active .txt {
transform: translateY(0);
}
.txt-item:nth-child(3).active .line {
width: 300px;
}
.txt-item:nth-child(4) {
top: 75%;
left: 58%;
}
.txt-item:nth-child(4) .line {
position: absolute;
left: -20px;
border-left: 1px solid gray;
height: 0;
bottom: 0;
transition: all .5s;
}
.txt-item:nth-child(4).active .line {
height: 130px;
}
.txt-item:nth-child(5) {
top: 80%;
left: 50%;
transform: translateX(-50%);
}
</style>
不知道你这个问题是否已经解决, 如果还没有解决的话:由于自己看直播突发奇想想做个弹幕的效果,在这里采用js来实现相关前端的功能,框架也不是特别重要。话不多说直接开始。
我的思路是设置一个screen类来存放可能需要引用的视频,而我的弹幕是用相关的div小盒子来进行存放输入的数据的。
<template>
<div class="barrage" :style="{ height: wrapperHeight + 'px' }">
<div class="screen" v-show="showBarrage">
<template v-for="(item, index) in barrArr">
<div class="barrItem" :key="index" v-show="true">
{{ item }}
</div>
</template>
</div>
<div class="btn_screen" @click="showbarr"><div class="btn"></div></div>
<div class="input_fixed">
<input type="text" v-model="input_value" />
<button @click="addBarrArr(input_value)">😊</button>
</div>
</div>
</template>
模板这里很简单就是一个输入框,一个按钮,以及做了一个滑动开关来打开关闭弹幕。关于弹幕数据我是将其放入一个数组中,通过遍历动态的读取相关的数据。
其实我们弹幕的思路就是
addBarrArr(value) {
let _this = this;
_this.$set(_this.barrArr, _this.barrArr.length, value);
setTimeout(() => {
let barr = document.getElementsByClassName("barrItem");
let barritem = barr[barr.length - 1];
Object.assign(barritem.style, {
visibility: "hidden",
right: -barritem.offsetWidth + "px",
top: this.randomTop() + "px",
color: this.getRandomColor()
});
barritem.style.visibility = "visible";
this.leftAnimate(barritem);
}, 10);
this.input_value = "";
},
这里我t通过Vm.set将数据加到数组中,并将最新添加的数据盒子加入相关样式。通过absolute定位使其脱流,因为一开始我们需要隐藏其样式,不然可能会出现在页面中闪一下这样的Bug。这里通过randomTop()和getRandomColor()来给随机的top值和字体颜色。由于是从右往左的弹幕滚动,所以我设置right的值,我们一开始需要将其隐藏然后慢慢的进入可视区,因为我们没有单独设置每个数据盒子的宽度,因为这样效果很差,所以采用自适应用内容来撑开盒子,那么就有个问题我们无法通过style来得到盒子的width值,因为他是一直为空,在由于我们需要将其显示在屏幕右侧的外面,那么就需要设给right给一个盒子宽度的负值,这样我们盒子的左侧边距就可以和我们屏幕又侧边线重合。我们可以通过offesetWidth来获取这个盒子的宽度来替代style.width。
盒子的位置设置好后我们就需要来给他加入动画效果了。在这里setInterval()就可以完成我们想要的效果,可是这需要设置时长,如果时间过长或者过短都会出现不流畅的效果,那么我们就可以在这里采用H5的一个新的API:requireAnimationFrame()。这个API不需要传入时间,会由系统自动分配时间,从而达到相对流畅的效果。
leftAnimate(value) {
let rightNum = Number(this.$utils.getNumber(value.style.right, "px"));
rightNum++;
if (rightNum < document.documentElement.clientWidth) {
requestAnimationFrame(() => {
value.style.right = rightNum + "px";
this.leftAnimate(value);
});
} else {
// console.log(value.parentNode);
value.parentNode.removeChild(value);
}
},
我们获取当前初始的right值,通过递增来使其值不断变大,显示在屏幕中,然后当其刚好出屏幕时,就结束动画,因为只是前端的展现效果,所以我在结束后会将弹幕删除来简化内容。
这样我们的主要内容就完成了,其实功能相对还是不难的,希望对大家有帮助,这只是我想到的一个实现,肯定还会有更好的!
在这里附上产生随机颜色
getRandomColor() {
let r = Math.random() * 256;
let g = Math.random() * 256;
let b = Math.random() * 256;
let color = `rgb(${r},${g},${b})`;
return color;
},
这里我是用rgb()的颜色格式当然还有很多其他的样式,就不一一介绍了。
由于问题描述不明确,无法给出具体的代码段和出错信息,需要更多细节才能给出准确的建议。关于Vue3的理解程度和原生JS的熟悉程度也需要更多信息才能回答。
你把body里的放到 template里 style 也拿出来放 style里。 js可以放到 script里 应该也能运行,vue里 用原生js 也可以,只不过不提倡,可能会出现问题。 顶多就是,docunment 的方法换成 ref 获取dom元素。然后 变量可以也用ref 声明响应式数据(有必要的话)
<template>
<div>
<video ref="video"></video>
<div v-for="(item, index) in txtItems" :key="index" :class="{ 'txt-item': true, 'active': activeItem === index }">{{ item }}</div>
</div>
</template>
<script>
import { ref, onMounted } from 'vue'
export default {
setup() {
const videoEl = ref(null)
const txtItems = ref(['text1', 'text2', 'text3', 'text4'])
const activeItem = ref(-1)
let duration = 0
function showTxt(percent) {
activeItem.value = -1
if (percent > 5 && percent <= 33) {
activeItem.value = 0
} else if (percent > 45 && percent <= 58) {
activeItem.value = 1
} else if (percent > 69 && percent <= 85) {
activeItem.value = 2
} else if (percent > 90) {
activeItem.value = 3
}
}
function updateCurrentTime() {
const percent = Math.ceil(window.scrollY) / (document.body.offsetHeight - window.innerHeight)
videoEl.value.currentTime = duration * percent
showTxt(percent * 100)
}
onMounted(() => {
videoEl.value.load()
videoEl.value.addEventListener('durationchange', (e) => {
duration = videoEl.value.duration
})
document.addEventListener('scroll', updateCurrentTime)
})
return {
videoEl,
txtItems,
activeItem
}
}
}
</script>
回答采用文心一言:
<script>
import { ref, onMounted, onUnmounted } from 'vue';
export default {
setup() {
const videoEl = ref(null);
const txtItems = ref([]);
const duration = ref(0);
const loadVideo = () => {
videoEl.value.load();
videoEl.value.addEventListener('durationchange', () => {
duration.value = videoEl.value.duration;
});
};
const showTxt = (percent) => {
txtItems.value.forEach((dom) => {
dom.className = 'txt-item';
});
// 当时常到百分之几时,对应的文字出现,这个随便调
if (percent > 5 && percent <= 33) {
txtItems.value[0].className = 'txt-item active';
} else if (percent > 45 && percent <= 58) {
} else if (percent > 45 && percent <= 58) {
txtItems.value[1].className = 'txt-item active';
} else if (percent > 69 && percent <= 85) {
txtItems.value[2].className = 'txt-item active';
} else if (percent > 90) {
txtItems.value[3].className = 'txt-item active';
}
};
const updateCurrentTime = () => {
// 滚动的距离占总高度的多少,那当前时间就是总时长的多少 比如滚动的距离占body的50%那么,当前的时间就应该是总时长的50%
const percent = Math.ceil(window.scrollY) / (document.body.offsetHeight - window.innerHeight);
videoEl.value.currentTime = duration.value * percent;
showTxt(percent * 100);
};
onMounted(() => {
document.addEventListener('scroll', updateCurrentTime);
loadVideo();
});
onUnmounted(() => {
document.removeEventListener('scroll', updateCurrentTime);
videoEl.value.removeEventListener('durationchange', loadVideo);
});
return { videoEl, txtItems, duration };
},
};
</script>