原生js实现歌词本

/** * Created by Administrator on 2017/4/30. */// 1.       歌词在一个矩形区域内显示// 2.       当前歌词行高亮// 3.       在矩形显示区域中部固定位置显示当前歌词行// 4.       当前歌词行切换到下一行时,下一行歌词高亮,并逐步移动到当前歌词行位置// 5.       初始显示时歌词第一行顶住显示区域,当前歌词行未到达显示矩形区域的中部固定高亮位置时,不需要移动// 6.       歌词尾行到达显示区域后,不需要移动// 7.       用户可通过鼠标或者滚动条滚动歌词// 8.       用户滚动歌词后,若当前歌词行被移动到矩形显示区域外,下一行歌词需定位到当前歌词行位置

<!DOCTYPE HTML><html lang=zh-cn><head>   <meta charset=utf-8>   <title>滚动歌词demo</title>   <style>      * {         margin: 0px;         padding: 0px;      }

body {         width: 100%;         height: 100%;         overflow: hidden;      }

.box {         margin: 100px auto 0 auto;         width: 400px;      }

.lrc {         position: relative;         width: 300px;         height: 200px;         overflow-y: auto;         background-color: #ccc      }

.lrc li {         display: block;         padding: 5px 0;      }

.z-crt {         color: #0f0;      }

.ctrl {         margin: 0 auto;         padding-left: 100px;         width: 300px;      }   </style></head><body><div class="box">   <audio id="bgMusic" src="yichangyouxiyichagmeng.mp3"></audio></div><div class="box" id="box">   <ul class="lrc" id="lrc">   </ul></div><script language="javascript">   function playMusic() {// 经解析后的歌词      var __lis = [{"offset": 500, "text": "一场游戏一场梦"},         {"offset": 1000, "text": "演唱:王杰"},         {"offset": 3000, "text": "不要谈什么分离"},         {"offset": 6000, "text": "我不会因为这样而哭泣"},         {"offset": 8000, "text": "那只是昨夜的一场梦而已"},         {"offset": 9000, "text": "不要说愿不愿意"},         {"offset": 12000, "text": "我不会因为这样而在意"},         {"offset": 14000, "text": "那只是昨夜的一场游戏"},         {"offset": 15000, "text": "那只是一场游戏一场梦"},         {"offset": 18000, "text": "虽然你影子还出现我眼里"},         {"offset": 24000, "text": "在我的歌声中早已没有你"},         {"offset": 25000, "text": "只是一场游戏一场梦"},         {"offset": 26000, "text": "不要把残缺的爱留在这里"},         {"offset": 30000, "text": "在俩个人的世界里不该有你"},         {"offset": 32000, "text": "oh.为什么道别离说什么在一起"},         {"offset": 33000, "text": "如今虽然没有你我还是我自己"},         {"offset": 35000, "text": "说什么此情永不愈"},         {"offset": 36000, "text": "说什么我爱你"},         {"offset": 38000, "text": "如今依然没有你我还是我自己"},         {"offset": 39000, "text": "那只是一场游戏一场梦"},         {"offset": 40000, "text": "虽然你影子还出现我眼里"},         {"offset": 42000, "text": "在我的歌声中早已没有你"},         {"offset": 44000, "text": "只是一场游戏一场梦"},         {"offset": 46000, "text": "不要把残缺的爱留在这里"},         {"offset": 48000, "text": "在俩个人的世界里不该有你"},         {"offset": 50000, "text": "oh.为什么道别离说什么在一起"},         {"offset": 52000, "text": "说什么此情永不愈"},         {"offset": 54000, "text": "说什么我爱你"},         {"offset": 56000, "text": "如今依然没有你我还是我自己"},         {"offset": 58000, "text": "为什么道别离说什么在一起"},         {"offset": 60000, "text": "如今虽然没有你我还是我自己"},         {"offset": 62000, "text": "说什么此情永不愈"},         {"offset": 64000, "text": "说什么我爱你"},         {"offset": 66000, "text": "如今依然没有你我还是我自己"}];

var __eul = document.getElementById("lrc");      (function () {         for (var i = 0; i < __lis.length; i++) {            var eli = document.createElement("li");            eli.innerText = __lis[i].text;            __eul.appendChild(eli);         }      })();

var __freq = 30; // 滚动频率(ms)      var __fraction = 2 / 5; // 高亮显示行在歌词显示区域中的固定位置百分比

/**       * 当前歌词行(lineno)滚动       */      var __go = function (_lineno) {         var _time;         if (_lineno === 0) {            _time = __lis[_lineno].offset;         } else {            _time = __lis[_lineno].offset - __lis[_lineno - 1].offset;         }         var _timer = setTimeout(__go.bind(this, _lineno + 1), _time);

// 高亮下一行歌词         if (_lineno > 0) {            __eul.children[_lineno - 1].setAttribute("class", "");         }         var _ep = __eul.children[_lineno];         _ep.setAttribute("class", "z-crt");

// 满足需求5,6         var _scrollTop;         if (_ep.offsetTop < __eul.clientHeight * __fraction) {            _scrollTop = 0;         } else if (_ep.offsetTop > (__eul.scrollHeight - __eul.clientHeight * (1 - __fraction))) {            _scrollTop = __eul.scrollHeight - __eul.clientHeight;         } else {            _scrollTop = _ep.offsetTop - __eul.clientHeight * __fraction;         }

// 如用户拖动滚动条导致当前显示行超出显示区域范围,下一行直接定位到当前显示行         if (__eul.scrollTop > (_scrollTop + __eul.clientHeight * __fraction)            || (__eul.scrollTop + __eul.clientHeight * __fraction) < _scrollTop) {            __eul.scrollTop = _scrollTop;         } else { // 单行滚动            // 获取滚动步长            var _step = Math.ceil(Math.abs(__eul.scrollTop - _scrollTop) / (_time / __freq));            __scroll(__eul.scrollTop, _scrollTop, _step);         }

};      /**       * 歌词单行滚动实现       */      __scroll = function (_crt, _dst, _step) {         if (Math.abs(_crt - _dst) < _step) {            return;         }         if (_crt < _dst) {            __eul.scrollTop += _step;            _crt += _step;         } else {            __eul.scrollTop -= _step;            _crt -= _step;         }         setTimeout(__scroll.bind(this, _crt, _dst, _step), __freq);      };

__go(0);

}

setTimeout(playMusic, 36000);

//背景音乐播放/* function audio3() {      var a = document.getElementById(‘bgMusic‘);      a.play();   }   audio3();*/</script></body></html>
时间: 2024-08-26 09:46:57

原生js实现歌词本的相关文章

利用原生JS实现网页1920banner图滚动效果

内容描述:随着PC设备硬件性能的进步和分辨率的不断提高,现在主流网站逐渐开始采用1920banner图,为适应这一趋势,博主设计了1920banner图的滚动效果,代码利用了原生JS实现了1920banner图的切换效果,并针对低分辨率电脑设备进行了适配,实现了JS代码与HTML代码的完全分离,符合w3c的标准使用规范,希望能给各位开发者朋友以帮助和参考.如发现有缺陷和不足,欢迎大家予以指正,如有更好的意见或解决方法,可在评论区交流互动.一下为代码内容: <!DOCTYPE html> <

原生JS写的ajax函数

参照JQuery中的ajax功能,用原生JS写了一个ajax,功能相对JQuery要少很多,不过基本功能都有,包括JSONP. 调用的方式分为两种: 1. ajax(url, {}); 2. ajax({}); 调用的方法参照JQuery的ajax,只是 不需要写$.ajax ,只需要写 ajax 就可以了. 代码如下: !function () { var jsonp_idx = 1; return ajax = function (url, options) { if (typeof url

原生js自动触发事件

熟悉jquery的童鞋都知道在jq中有一个方法可以自动触发事件,那就是trigger(),那么通过原生js又怎么模拟触发呢? js中添加一个主动触发事件的方法有dispatch.该方法能模拟用户行为,如点击(click)操作等. 标准使用dispatchEvent方法,IE6/7/8则使用fireEvent方法. dispatchEvent() 方法给节点分派一个合成事件. 语法如下: dispatchEvent(eventObj) eventObj 参数是一个描述事件的 ActionScrip

使用原生js的scrollTop,刷新进入页面定位到某一个dom元素

原生js的scrollTop即可,与jquery方法的区别是jquery做了兼容封装.我想要实现的功能是时间定位,根据当前时间定位到滚动区的时间位置.页面为移动端页面,上下固定位置,中部为1小时4格的选择区域,从0点到24点. 开始我想发出现了偏差,总想定位到某个dom,这样使得scrollTop一直是0,怎么设置都不行,后来仔细分析才发现要设置在超出当前可视区域的dom上才可以. 所以设置在外层overflow-x:scroll;的dom上即可,根据时间匹配dom位置,根据索引及每格的高度计算

原生JS封装运动框架

昨天我们说了一下原生JS中常用的兼容性写法,今天我们来说一下运动框架. 正常情况下我们要写一个运动的效果会用到tween.js这么一个插件,这个东西不是一般人写出来的,因为里面涉及的运动效果都是经过一堆数学的函数运算出来的,我们平常人是写不出来的,所有我们就自己封装一个运动框架,有什么问题改起来也方便,下面我们就开始封装. 首先,我们先写一个div,设置一些简单的样式,我们就拿这个div举例子,如下代码: #div{ width: 100px; height: 100px; background

常用原生JS兼容写法

在我们前端开发中,经常会遇到兼容性的问题,因为要考虑用户会使用不同的浏览器来访问你的页面,你要保证你做的网页在任何一个浏览器中都能正常的运行,下面我就举几个常用原生JS的兼容写法: 1:添加事件方法 addHandler:function(element,type,handler){  if(element.addEventListener){//检测是否为DOM2级方法   element.addEventListener(type, handler, false);  }else if (e

原生js实现数据双向绑定

最近接触了vue,在谈到vue等等的mvvm框架之前,先了解什么是数据双向绑定以及如何利用原生JS实现数据双向绑定 单向数据绑定 指先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成HTML代码,然后把这段HTML代码插入到文档流里 缺点:一旦HTML代码生成就没有办法改变,如果有新数据重新传入,就必须重新把模板和数据整合到一起插入到文档流中 数据双向绑定 数据模型和视图之间的双向绑定,用户在视图上的修改会自动同步到数据模型中,同样的,如果数据模型中的值发生变化,也会同步到视图中去

原生JS与jQuery操作DOM有什么异同点?

本文和大家分享的主要是原生JS与jQuery操作DOM相关内容,一起来看看吧,希望对大家学习javascript有所帮助. 一.创建元素节点 1.1 原生 JS 创建元素节点 document.createElement("p"); 1.2 jQuery 创建元素节点 $('<p></p>');` 二.创建并添加文本节点 2.1 原生JS创建文本节点 document.createTextNode("Text Content"); 通常创建文

原生 js 左右切换轮播图

使用方法: 可能很多人对轮播图感兴趣,下面奉上本人的 原生 js 轮播代码复制 js 到页面的最底部,样式在 css 里改,js 基本不用动,有什么不懂的可以 加本人 QQ172360937 咨询 或者留言都可以,这个是用 原生写的 轮播图,样式可以写自己喜欢的样式,什么都不用改,只改变样式就行,页面结构的id 要与js的相对应li随便加.li 随便加的意思就是说你可以加无数个图片.每个li 里装一个图片,或者是其他什么元素, <!doctype html> <html lang=&qu