私人tool.js

个人总结的一些js工具代码

/* eslint-disable */
// 如果是在vue项目中引入的话,上面的注释用来避免vue中的eslint语法检查
// 使用方法,在html中通过script标签引入, <script src="./js/myTool.js"></script>,不管是vue项目还是普通项目,可全局使用
// 在vue的main.js文件中通过import './assets/js/myTool' 的方式引入,全局使用
// 在vue组件中使用的话,import '../../assets/js/myTool',只能在当前组件中使用

(function(){
  // ******判断一个变量是否是dom元素******
  // 首先要对HTMLElement进行类型检查,因为即使在支持HTMLElement
  // 的浏览器中,类型却是有差别的,在Chrome,Opera中HTMLElement的
  // 类型为function,此时就不能用它来判断了
  const isDOM = ( typeof HTMLElement === 'object' ) ?
      function(obj){
          return obj instanceof HTMLElement;
      } : 
      function(obj){
          return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';
      }


  // ******获取整数随机数******
  function getRandomInt(min, max) {
      min = Math.ceil(min);
      max = Math.floor(max);
      return Math.floor(Math.random() * (max - min + 1)) + min; //The maximum is inclusive and the minimum is inclusive 
    }


  // ******时间格式化函数******
  function dateFmt(fmt, dateVal) {
      if (typeof(fmt) != 'string') return '格式化参数有误!';       
      // 如果刚开始传入的时间参数是一个小于30*24*3600*1000毫秒数的数字,那么应该是求一个时间差值(否则就是求日期格式化),求时间差需要对东八区的小时数进行额外处理,因为new Date(毫秒数)是带着时区值的,并且北京时间要比格林威治时间快8个小时,所以格式化后小时上会多出8小时,应减去。
      // 当然生成的该对象不仅可能是时间,也可能是格林尼治一月份日期(参数中加上年月日就可以了)。
      if((typeof(dateVal) === 'number') && dateVal < 30 * 24 * 3600 * 1000 && !fmt.includes('M')) {//该条件用于判定是否是求时间差
          dateVal = new Date(dateVal - 8 * 3600 * 1000);
      }

      return fmtDate(fmt, dateVal);
      
      // 用于格式化日期(或时间差)的方法
      function fmtDate(fmt, dateVal) {
          // 校验参数并对象化日期参数(转成日期对象)
          let date;
          if(dateVal || dateVal === 0) {
              date = new Date(dateVal);                
          }else {
              date = new Date();
          }
          if (date.toString() == 'Invalid Date') return '时间参数有误';

          // 单独处理年数
          let year = date.getFullYear() + '';
          let reg = /y+/g;
          let mYear = fmt.match(reg);
          if(mYear) {
              let mYearStr = mYear[0];
              year = year.substr(4 - mYearStr.length);
              fmt = fmt.replace(mYearStr, year);
          }
          
          // 获取其余时间值
          let dates = {
              'M' : date.getMonth() + 1,
              'd' : date.getDate(),
              'h' : date.getHours(),
              'm' : date.getMinutes(),
              's' : date.getSeconds()
          }

          // 处理替换剩余时间值,并返回结果
          let regs = /[Mdhms]+/g;
          let rst = fmt.replace(regs, function (mth) {
              let item = mth[0];
              let value = dates[item];
              if(!value && value != 0) return ""; 
              if(mth.length == 1) {
                  return dates[mth];
              }else {
                  return ('00' + value).substr(String(value).length);
              }

          })
          let result = {
              year: year,
              month: dates.M,
              day: dates.d,
              hour: dates.h,
              minute: dates.m,
              second: dates.s
          }
          result.fmtTimeStr = rst;
          return result;
      }
              
  }


  // ******函数防抖******
  /**
   解释:函数防抖是优化高频率执行js代码的一种手段,可以让被调用的函数在一
   次连续的高频率操作过程中只被调用执行一次,降低其执行频率。
   作用:减少代码执行次数,提升网页性能
   应用场景:oninput、onmousemove、onscroll、onresize等高频事件
   (这类事件虽然高频,但是还有一个特点,就是人为触发的,就是可能快可能慢;
   但是像视频或音乐的播放,这种持续高频但是又不受人为控制的,这种事件不适合用函数防抖,
   而要用函数节流。因为函数防抖是如果不停的触发,定时器会不停的被清除创建,
   定时器里面的函数(除最后一次定时器创建的会被执行外)有可能永远都不会执行;
   而函数节流则是加了双重开关,定时器中函数至少执行过才会被清除然后再次设定,所以里面的函数一定会执行,
   所以总体会被执行n次。所以说函数节流应用范围更广)
   */
  function debounce(fn,delay) {
      let timeId = null;
      return function (params) {
          let args = arguments;
          let self = this;
          timeId && clearTimeout(timeId);
          timeId = setTimeout(function(){
              fn.apply(self, args);
          },delay || 1000);
      }
  }


  // ******函数节流******
  function throttle(fn,delay) {
      let timeId = null;
      let flag = true;
      return function () {
          if(!flag) return;
          flag = false;
          timeId && clearTimeout(timeId);

          let args = arguments;
          let self = this;
          timeId = setTimeout(function(){
              flag = true;
              fn.apply(self, args);
          },delay || 1000);
      }
  }


  // ******匀速动画******
  function linearAnimation(ele, attrs) {
      for(let attr in attrs){
          if(!ele.anmTimer) {ele.anmTimer = {}}
          ele.anmTimer[attr] && clearInterval(ele.anmTimer[attr]);
          let styles = ele.currentStyle || getComputedStyle(ele);
          let begin = parseFloat(styles[attr]);
          let suffix = styles[attr].replace(/[^A-z]/ig, '');
          let target = parseFloat(attrs[attr]);
          let step = +((target - begin) * 0.05).toFixed(3);

          ele.anmTimer[attr] = setInterval(function(){
              begin += step;
              if(Math.abs((target - begin).toFixed(2)) <= Math.abs(step)) {
                  clearInterval(ele.anmTimer[attr]);
                  begin = target;
              }
              ele.style[attr] = begin + suffix;

          },100);

      }

  }


  // ******缓动动画******
  function easeAnimation(ele,attrs) {
      for(let attr in attrs){
          if(!ele.anmTimer) {ele.anmTimer = {}}
          ele.anmTimer[attr] && clearInterval(ele.anmTimer[attr]);
          let styles = ele.currentStyle || getComputedStyle(ele);
          let begin = parseFloat(styles[attr]);
          let suffix = ("" + styles[attr]).replace(/[^A-z]/gi, '');
          let target = parseFloat(attrs[attr]);
          let minSpace = Math.abs(((target - begin) * 0.02).toFixed(3));

          ele.anmTimer[attr] = setInterval(function () {
              step = +((target - begin) * 0.3).toFixed(3);
              
              if((Math.abs(+(target - begin).toFixed(2)) <= minSpace)){
                  ele.style[attr] = target + suffix;
                  clearInterval(ele.anmTimer[attr]);
                  return
              }
              begin += step;
              ele.style[attr] = begin + step + suffix;

          },100);
      }
  }


  // ******格式化播放次数******
  function fmtPlayCount(playCount){// 格式化推荐歌单后台数据中的播放次数数据
      if((playCount + "").length > 8) {
          return (playCount/100000000).toFixed(1) + '亿';
      }else if((playCount + "").length > 4) {
          return (playCount / 10000).toFixed(1) + '万';
      }else {
          return playCount;
      }
  }
  
  
  // ******创建进度条******
  class Progress {
      constructor(bar) {
          this.oBar = isDOM(bar) ? bar : document.querySelector(bar);
          const oBarstyles = this.oBar.currentStyle || getComputedStyle(this.oBar)
          if (oBarstyles.backgroundColor === 'rgba(0, 0, 0, 0)') {
            this.oBar.style.backgroundColor = '#aaa';
          }
          // this.oBar.style.cssText = `background: #aaa;`;
          this.oLine = document.createElement('div');
          this.oDot = document.createElement('div');
          this.oLine.appendChild(this.oDot);
          this.oBar.innerHTML = '';
          this.oBar.appendChild(this.oLine);
          this.linePercent = 0 // 当前进度条百分比
          this.callBefores = [] // 事件之前要执行的方法数组
          this.callBacks = [] // 事件之后要执行的方法

          setTimeout(() => {
              // 延迟获取宽度,防止没有渲染完获取的不准确。
              this.barHeight = parseInt(getComputedStyle(this.oBar).height);
              this.barWidth = parseInt(getComputedStyle(this.oBar).width);

              // 初始化前景样式
              // this.oLine.style.cssText = `width: 0; height: 100%; background: #eee; position: relative;`;
              this.oLine.style.width = '0';
              this.oLine.style.height = '100%';
              this.oLine.style.backgroundColor = '#eee';
              this.oLine.style.position = 'relative';
              // 初始化小圆点样式
              // this.oDot.style.cssText = `width: ${this.barHeight * 2}px; height: ${this.barHeight * 2}px; background: #eee; position: absolute; right: ${-this.barHeight / 2}px; top: ${- this.barHeight / 2}px; border-radius: 50%;`;
              this.oDot.style.width = `${this.barHeight * 2}px`;
              this.oDot.style.height = `${this.barHeight * 2}px`;
              this.oDot.style.backgroundColor = '#eee';
              this.oDot.style.position = 'absolute';
              this.oDot.style.right = `${-this.barHeight / 2}px`;
              this.oDot.style.top = `${- this.barHeight / 2}px`;
              this.oDot.style.borderRadius = '50%';

          }, 200);
      }
      // 因为元素在display: none状态下是无法一定能通过getComputedStyle获取到数据的,有可能会返回auto,所以其他方法如果用到宽度的话,
      // 需要先判断一下,没有值得话,需要等待获取。
      getSureData(cb,params) {
          let that = this;
          // if(that.barWidth >= 0) return;
          
          return new Promise(function(resolve, reject){
              if(that.barWidth >= 0) {
                  resolve(that.barWidth);
              }else {
                  let timer = setInterval(function(){
                      that.barWidth = parseInt(getComputedStyle(that.oBar).width);
                      if(that.barWidth >= 0) {
                          clearInterval(timer);
                          // cb.call(that,params);
                          resolve(that.barWidth)
                      }
                  }, 200);
              }
          });
      }

      // 设置进度条的颜色及圆角样式(背景色、渐变背景色、前景色、渐变前景色、圆点色、径向渐变圆点色、进度条是否圆角)
      barCss ({barCor, barGradCor, lineCor, lineGradCor, dotCor, dotRadiCor, cirRadius}) {
        // 因为宽高是延迟获取的,并且同时重置了样式,所以样式设置必须在获取宽高以后设置,否则会被再次重置
        this.getSureData().then((barWidth) => {
          barCor && (this.oBar.style.background = barCor);
          barGradCor && (this.oLine.style.background = `linear-gradient(${barGradCor})`);
          lineCor && (this.oLine.style.background = lineCor);
          lineGradCor && (this.oLine.style.background = `linear-gradient(${lineGradCor})`);
          dotCor && (this.oDot.style.background = dotCor);
          dotRadiCor && (this.oDot.style.background = `radial-gradient(${dotRadiCor})`);
          if(cirRadius) {
              this.oBar.style.borderRadius = this.barHeight / 2 + 'px';
              this.oLine.style.borderRadius = this.barHeight / 2 + 'px';
          }else {
              this.oBar.style.borderRadius = 0;
              this.oLine.style.borderRadius = 0;
          }
        })
      }

      // 注:要想拖动小圆点必须要执行该初始化事件方法
      initEvents ({callBefore, callBack} = {}) {
          // let isPcClient = isPc();
          // console.log(isPcClient);
          // let downEventName = isPcClient ? 'mousedown' : 'touchstart';
          // let moveEventName = isPcClient ? 'mousemove' : 'touchmove';
          // let upEventName = isPcClient ? 'mousedown' : 'touchend';

          // if(!(this.barWidth >= 0)) {
          //     this.getSureData(this.initEvents,{callBefore, callBack});
          //     return;
          // } ;

          let that = this;
          this.getSureData().then(function(){
              if(isPc()) {
                  that.oDot.onmousedown = function(event){
                      event = event || window.event;
                      // 回调函数里面两个参数:一个是当前进度条比例,一个是当前进度条宽度
                      // callBefore && callBefore(that.linePercent, that.oLine.style.width);
                      callBefore && that.callBefores.push(callBefore)
                      if(that.callBefores.length) {
                        that.callBefores.forEach((fn) => {
                          fn.call(that, that.linePercent, that.oLine.style.width)
                        })
                      }
                      let oldX = event.pageX;
                      let oldLineWidth = parseInt(getComputedStyle(that.oLine).width);
                      document.onmousemove = function(event){
                          let curLineWidth = oldLineWidth + (event.pageX - oldX);
                          if (curLineWidth < 0) {
                              curLineWidth = 0
                          }else if(curLineWidth > that.barWidth) {
                              curLineWidth = that.barWidth;
                          }
                          that.oLine.style.width = curLineWidth + 'px';
                          that.linePercent = parseInt(getComputedStyle(that.oLine).width) / that.barWidth
                      }
                      document.onmouseup = function(event){
                        // 回调函数里面两个参数:一个是当前进度条比例,一个是当前进度条宽度
                        // callBack && callBack(that.linePercent, that.oLine.style.width);
                        callBack && that.callBacks.push(callBack)
                        if(that.callBacks.length) {
                          that.callBacks.forEach((fn) => {
                            fn.call(that, that.linePercent, that.oLine.style.width)
                          })
                        }
                        document.onmousemove = null;
                        document.onmouseup = null;
                      }
                      if(event.stopPropagation) {
                          event.stopPropagation();
                      }else {
                          event.cancelBubble = true;
                      }
                  }
  
              }else {
                  that.oDot.ontouchstart = function(event){
                      // 回调函数里面两个参数:一个是当前进度条比例,一个是当前进度条宽度
                      // callBefore && callBefore(that.linePercent, that.oLine.style.width);
                      callBefore && this.callBefores.push(callBefore)
                      if(that.callBefores.length) {
                        that.callBefores.forEach((fn) => {
                          fn.call(that, that.linePercent, that.oLine.style.width)
                        })
                      }
                      let oldX = event.targetTouches[0].pageX;// 注意这里采用pageX不要用sreenX;否则有些问题;
                      let oldLineWidth = parseFloat(getComputedStyle(that.oLine).width);
                      document.ontouchmove = function(event){
                          let curLineWidth = (event.targetTouches[0].pageX - oldX) + oldLineWidth;// 注意这里采用pageX不要用sreenX;否则有些问题;
                          if (curLineWidth < 0) {
                              curLineWidth = 0
                          }else if(curLineWidth > that.barWidth) {
                              console.log(that.barWidth, '宽度');
                              curLineWidth = that.barWidth;
                          }
                          that.oLine.style.width = curLineWidth + 'px';
                          that.linePercent = parseInt(getComputedStyle(that.oLine).width) / that.barWidth
                      }
                      document.ontouchend = function(event){
                          // 回调函数里面两个参数:一个是当前进度条比例,一个是当前进度条宽度
                          // callBack && callBack(that.linePercent, that.oLine.style.width);
                          callBack && that.callBacks.push(callBack)
                          if(that.callBacks.length) {
                            that.callBacks.forEach((fn) => {
                              fn.call(that, that.linePercent, that.oLine.style.width)
                            })
                          }
                          document.ontouchmove = null;
                          document.ontouchend = null;
                      }
                  }
                  
              }
              
              that.oBar.addEventListener('click', function(event){
                  // 回调函数里面两个参数:一个是当前进度条比例,一个是当前进度条宽度
                  // callBefore && callBefore(that.linePercent, that.oLine.style.width);
                  callBefore && that.callBefores.push(callBefore)
                  if(that.callBefores.length) {
                    that.callBefores.forEach((fn) => {
                      fn.call(that, that.linePercent, that.oLine.style.width)
                    })
                  }
                  event = event || window.event;
                  if(event.target !== that.oDot) {// 防止点击“点”的时候也执行
                      that.oLine.style.width =  event.offsetX + 'px';
                      that.linePercent = parseInt(getComputedStyle(that.oLine).width) / that.barWidth
                      // 回调函数里面两个参数:一个是当前进度条比例,一个是当前进度条宽度
                      // callBack && callBack(that.linePercent, that.oLine.style.width);
                      callBack && that.callBacks.push(callBack)
                      if(that.callBacks.length) {
                        that.callBacks.forEach((fn) => {
                          fn.call(that, that.linePercent, that.oLine.style.width)
                        })
                      }
                  }
                  if(event.stopPropagation) {
                      return event.stopPropagation();
                  }else {
                      event.cancelBubble = true;
                  }
              })
          })
          
      }


      // 额外添加事件
      addEvents ({callBefore, callBack}) {
        typeof(callBefore) === 'function' && this.callBefores.push(callBefore);
        typeof(callBack) === 'function' && this.callBacks.push(callBack);
      }


      // 更新进度条进度的方法(参数宽度既可以是百分比也可以是决定宽度值)
      updateProgress (width, callBefore, callBack) {
          // if(!(this.barWidth >= 0)) {
          //     this.getSureData(this.updateProgress,width);
          //     return;
          // } ;
          let that = this;
          this.getSureData().then(function(){
              callBefore && callBefore(that.linePercent / that.barWidth, that.oLine.style.width);
              width = parseFloat(width);
              if (width <= 1) {
                that.linePercent = width;
                that.oLine.style.width = that.barWidth * width + 'px';
              }else {
                that.linePercent = width / that.barWidth;
                that.oLine.style.width = width + 'px';
              }
              callBack && callBack(that.linePercent, that.oLine.style.width);
          })
      }
  } 


  // ******判断是不是电脑端******
  function isPc() {
      return !/iPhone|Android|Mobile/.test(window.navigator.userAgent);
  }


  // ******创建高亮关键字方法******
  function lightKeywords(keyword, html) {
      let reg = new RegExp(`(${keyword})`, 'g');
      return html.replace(reg, "<span class='keyword'>$1</span>");
  }


  // ******Storage的存取(数组形式)******
  ZLLocalData = {
      getSession: function(key) {
          let str = sessionStorage.getItem(key);
          if (!str) return
          let arr = JSON.parse(str);
          return arr;
      },
      setSession: function(key, value, flag) {
          // flag为true表示完全添加和覆盖,否则就是差异添加
          if (flag) {
            localStorage.setItem(key, JSON.stringify(value))
            return
          }
          value = JSON.stringify(value);
          let storage = sessionStorage.getItem(key);
          if(storage && storage.length > 2) {
              let index = storage.indexOf(value);
              if(index === 1) return;
              if(index > -1) {
                  storage = storage.replace(',' + value, "");
              }
              storage = storage.replace('[','[' + value + ',');
          }else {
              storage = `[${value}]`;
          }
          sessionStorage.setItem(key, storage);
      },
      removeSession: function (key, value) {
          // 如果flag为真表示完全删除,否则是差异删除
          if (flag) {
            localStorage.removeItem(key)
            return
          }
          
          if(value) {
              value = JSON.stringify(value);
              let storage = sessionStorage.getItem(key);
              let index = storage.indexOf(value);
              if(index < 0) return;
              storage = storage.replace(value, "");
              storage = storage.replace(',,', ",");
              storage = storage.replace(/^\[,/g, "[");
              storage = storage.replace(/,\]$/g, "]");
              if(storage !== '[]') {
                  sessionStorage.setItem(key, storage);
                  return;
              }
          } 
          sessionStorage.removeItem(key);
      },


      getStorage: function(key) {
          let str = localStorage.getItem(key);
          if (!str) return
          let arr = JSON.parse(str);
          return arr;
      },

      setStorage: function(key, value, flag) {
        // flag为true表示完全添加和覆盖,否则就是差异添加
          if (flag) {
            localStorage.setItem(key, JSON.stringify(value))
            return
          }

          value = JSON.stringify(value);
          let storage = localStorage.getItem(key);
          if(storage && storage.length > 2) {
              let index = storage.indexOf(value);
              if(index === 1) return;
              if(index > -1) {
                  storage = storage.replace(',' + value, "");
              }
              storage = storage.replace('[','[' + value + ',');
          }else {
              storage = `[${value}]`;
          }
          localStorage.setItem(key, storage);
      },

      removeStorage: function (key, value, flag) {
          // 如果flag为真表示完全删除,否则是差异删除
          if (flag) {
            localStorage.removeItem(key)
            return
          }

          if(value) {
              value = JSON.stringify(value);
              let storage = localStorage.getItem(key);
              let index = storage.indexOf(value);
              if(index < 0) return;
              storage = storage.replace(value, "");
              storage = storage.replace(',,', ",");
              storage = storage.replace(/^\[,/g, "[");
              storage = storage.replace(/,\]$/g, "]");
              if(storage !== '[]') {
                  localStorage.setItem(key, storage);
                  return;
              }
          } 
          localStorage.removeItem(key);
      }
  }


  // ******音乐播放器******(需要jquery支持)
  class ZLAudio {
      constructor(musicLists) {// 歌曲对象数组,{id:99, song:"生如夏花", songer: '朴树', url: '', lyricStr(可选): '歌词字符串'}
          this.oAudio = document.createElement('audio');
          this.oAudio.innerText = '您的浏览器不支持播放';
          // $('body').append(this.oAudio);
          this.$Audio = $(this.oAudio);
          this.isCanPlay = false;
          this.playMode = 'loop';
          this.lyricLiHeight = 0;
          this.musicProgress = null;
          this.currentTime = 0; // 这里写出来是为了照顾vue中,方便watch监听,因为如果要单独监听一个对象的一个属性,该对象初始的时候就要有该属性
          this.fmtCurrentTime = 0;
          this.callBacks = [] // 存储跟随播放要执行的所有回调函数
          
          if(musicLists) {this.initMusicLists(musicLists)}
          this._listenCanPlay();
      }

      // 监听歌曲是否可以播放(内部调用)
      _listenCanPlay(canPlay) {
          //监听歌曲加载
          // this.oAudio.oncanplay = null;
          let that = this;
          // 不用oncanplay监听,因为苹果的safari浏览器不会自动加载歌曲资源
          // this.oAudio.oncanplay = function(){
          this.oAudio.ondurationchange = function(){
              // 初始化音乐时长
              that.fmtDuration = dateFmt('mm:ss', that.oAudio.duration * 1000).fmtTimeStr;
              that.duration = that.oAudio.duration;
              that.isCanPlay = true;
              canPlay && canPlay(that.duration);
              that.oAudio.play();//播放音乐
          };
      }

      // 监听歌曲播放
      listenPlay(cb) {
          let that = this;
          this.oAudio.ontimeupdate = function(){
              that.currentTime = that.oAudio.currentTime;
              that.fmtCurrentTime = dateFmt('mm:ss', that.oAudio.currentTime * 1000).fmtTimeStr;
              if(that.musicProgress) {
                  that.musicProgress.updateProgress(that.oAudio.currentTime / that.oAudio.duration);
              }

              cb && that.addEvents(cb);
              if (that.callBacks.length) {
                that.callBacks.forEach(fn => {
                  fn.call(that, that.fmtCurrentTime, that.fmtDuration)
                });
              }
          }
      }


      // 额外添加跟随播放要执行的回调函数
      addEvents (callBack) {
        typeof(callBack) === 'function' && this.callBacks.push(callBack);
      }

      // 加载(播放)歌曲
      loadMusic(curSongId,url,cb) {
          if(this.curMusicId && this.curMusicId === curSongId) return;
          let curSongIndex = this.findSongIndex(curSongId);
          let that = this;
          url = this.musicLists[curSongIndex].url || url;
          if (!url) return
          if(typeof url === 'string') {
              that.oAudio.src = url;
          }else if(url.constructor.name === 'Array') {//{url: '', type: ''}
              let musicHtml = '';
              url.forEach(function(ele){
                  musicHtml += `<source src="${ele.url}" type="audio/${ele.type}">`;
              });
              that.oAudio.html(musicHtml);
              that.oAudio.load();
          }
          that.curMusicId = curSongId;
          cb && cb(curSongId);
      }


      // 监听歌曲是否播放完
      listenPlayEnd(cb) {
          this.oAudio.onended = cb;
      }

      // 初始化音乐列表
      initMusicLists(musicLists) {
          this.musicLists = musicLists;
          this.curSongId = this.musicLists[0].id;
      }
      
      // 歌词处理
      handleLyrics(curSongId,lyricStr,cb) {
          if(this.curLyricId && this.curLyricId === curSongId) return;
          let that = this;
          let lyricsObj = _lyricHandle(lyricStr);
          let lyricsHtml = "";
          let i = 0;
          for(let key in lyricsObj) {
              let tiemStr = dateFmt('mm:ss', + key * 1000 ).fmtTimeStr;
              lyricsHtml += `<li id="zl-${key}" time=${tiemStr} offset=${i}>${lyricsObj[key]}</li>`;
              i++;
          }
          that.lyrics = lyricsObj;
          that.lyricsHtml = lyricsHtml;
          that.curLyricId = curSongId;
          cb && cb(lyricObj);
          return lyricsHtml;
          
          //将歌词字符串转化为对象(内部调用)
          function _lyricHandle(lyricStr){
              let reg = /\[(.+)\](.+)/g;
              let lyricObj = {};
              lyricStr.replace(reg, function($,$1,$2){
                  let time = $1.substr(0,2) * 60 + Math.round(+$1.substr(3));
                  lyricObj[time] = $2.trim();
              })
              return lyricObj;
          }
      }
      // 同步高亮当前歌词
      lightActiveLyric (lyricWrapper, className, color) {
        this.oLyricWrapper = isDOM(lyricWrapper) ? lyricWrapper : document.querySelector(lyricWrapper);
        className = className || 'active';
        if (color && typeof(color) === 'string') {
          this.oLyricWrapper.style.color = color;
        }
        this.$Audio.on('timeupdate', () => {
          console.log(this.currentTime)
          console.log('#zl-' + Math.round(this.currentTime))
          $('#zl-' + Math.round(this.currentTime)).addClass(className).siblings().removeClass(className)
        })

      }

      // 初始化音量条
      initVolumeProgress(selector,cb,muteBtn) {
          this.volumeProgress = new Progress(selector);
          this.oAudio.volume = 0.5;
          this.volumeProgress.updateProgress(this.oAudio.volume);
          let that = this;
          muteBtn && $(muteBtn).click(function(){//设置静音按钮的点击事件
              if(that.oAudio.volume === 0){
                  that.oAudio.volume = that.volume;
              }else {
                  that.volume = that.oAudio.volume;
                  that.oAudio.volume = 0;
              }
              return false;
          });
          this.volumeProgress.initEvents({callBack: function(value){
              that.oAudio.volume = value;
              that.volume = value;
              cb && cb(that.oAudio.volume);
          }})
          return that.volumeProgress;
      }

      // 初始化音乐进度条
      initMusicProgress(selector,cb) {
          this.musicProgress = new Progress(selector);
          let that = this;
          that.musicProgress.initEvents({callBack: function(widthPercent){
              that.oAudio.currentTime = isNaN(that.oAudio.duration) ? 0 : that.oAudio.duration * widthPercent;
              that.currentTime = that.oAudio.currentTime;
              cb && cb(widthPercent);
          }});
          return that.musicProgress;
      }

      // 根据歌曲索引查找id
      findSongId(index) {
          return this.musicLists[index].id;
      }

      // 根据歌曲id查找索引
      findSongIndex(songId) {
          return this.musicLists.findIndex(function(ele){
              return ele.id === songId;
          })
      }
  } 




  window.isDOM = isDOM; // 判断是否是dom对象
  window.dateFmt = dateFmt; // 格式化日期或者时长
  window.debounce = debounce; // 函数防抖
  window.throttle = throttle; // 函数节流
  window.linearAnimation = linearAnimation; // 线性动画
  window.easeAnimation = easeAnimation; // 缓动动画
  window.fmtPlayCount = fmtPlayCount; // 格式化播放量
  window.Progress = Progress; // 进度条对象
  window.isPc = isPc; // 判断是否电脑端
  window.lightKeywords = lightKeywords; // 高亮关键字
  window.ZLLocalData = ZLLocalData; // 本地存储方法
  window.ZLAudio = ZLAudio; // 音频播放器对象
  window.getRandomInt = getRandomInt; // 获取随机整数
})();

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342