JS实现滚动歌词

当我们调用接口获取到歌词时,后端一般会提前给我们加上时间前缀,在利于我们进行后续操作的同时,我们也必须过河拆桥得把这个东西给删除掉,否则会影响美观,这点使用正则表达式就可以

`   let reg = /\[(\d{2}:\d{2})\.\d{2,3}\](.+)/;`

然后我们要做的是创建两个数组,用foreach把时间戳部分和字幕部分分别放进去,利用下标让他们一一对应。

这时有一个问题,就是我们不知道字母具体有多长,而且直接在div里放插值表达式会是没有换行的,最开始我用
textarea解决了这两个问题,但后来发现这个东西是可以删除的,而且还有样式上的种种问题,后期操作也很难进行,所以只能动态创建


```javascript
  `let ul = document.querySelector('ul');
                        let frg = document.createDocumentFragment()
	lrc.forEach(function(a) {
                            let li = document.createElement('li')
                            li.innerText = a;
                        frg.appendChild(li);
                                })
	 ul.appendChild(frg)`

a是每一句歌词

注意,创建节点一点要先创建虚拟节点,再用appendchild添加到尾部

到了这一步,我们就把歌词单独分离出来了,现在我们只要把歌词与时间戳对应就好了

还记得我们之前的timeupdata里每次都要把当前时间存入vuex中吗,就是为了这一步,由于vuex是动态绑定的,每次currenttime更改vuex中的数据都会同步更改,所以我们只要检测vuex中的数据就可以了,这里你就知道为什么之前我说watch和vuex结合很香了,我们使用watch监视vuex中数据的改变,只要改变了就遍历时间戳的索引,找出对应的时间戳的索引,然后将该索引在歌词数组的对应的歌词的类名修改(或者直接修改样式)就可以了,之后我们只要在CSS中修改特定的类名样式就可以更改歌词样式了。但在这之前我们要先将这句歌词前一句的样式恢复,否则会出现一大串都变色的情况。

注意watch有两个参数,分别是变化前和变化后的值,这里我感觉用变化后的值(第二个参数)会丝滑一些。另外,这里vuex的值要放在computed中,放在data中是监视不到的

`computed: {
data () {
return this.$store.state.time;
}
},
``
最后我们要做的,就是让歌词不断滚动上移就可以了,我们可以将最外层的盒子overflow设为scoll,然后在每次时间戳更改时,让歌词的top上移就可以了。

  `that.time.forEach(function(a, i) {
                if (a == n) {
                 ul.style.top =  160- i * 50 + 'px';
                    for (let j = 0; j < ul.children.length; j++) {
                        ul.children[j].style.color= 'white';
                    }
                    ul.children[i].style.color= '#700511';`

这里要注意,最前面的160px是最开始歌词距离顶部的距离,可以看情况修改;50px是一个li标签的高度,但由于存在字体大小,行高等因素,此时这里的行高不一定是你设置的高度,建议使用开发者工具查看一下。

最后,有时候会发生歌手名或歌名过长导致溢出的情况,这里建议大家封装一个函数,当返回的数据超过指定的字数,后面的内容就会用省略号代替。

`strchange: function(m, n) {
                let ms = m + '';
                if (ms.length > n) {
                    let a = ms.slice(0, n - 1);
                    a = a.concat('...')
                        // console.log(a)
                    return a;
                } else {
                    return ms
                }`
m是目标字符串,n是设置的长度

你可能感兴趣的:(javascript)