個(gè)人總結(jié)的一些js工具代碼
/* eslint-disable */
// 如果是在vue項(xiàng)目中引入的話,上面的注釋用來避免vue中的eslint語法檢查
// 使用方法盈简,在html中通過script標(biāo)簽引入, <script src="./js/myTool.js"></script>维蒙,不管是vue項(xiàng)目還是普通項(xiàng)目贡这,可全局使用
// 在vue的main.js文件中通過import './assets/js/myTool' 的方式引入,全局使用
// 在vue組件中使用的話轻黑,import '../../assets/js/myTool',只能在當(dāng)前組件中使用
(function(){
// ******判斷一個(gè)變量是否是dom元素******
// 首先要對(duì)HTMLElement進(jìn)行類型檢查,因?yàn)榧词乖谥С諬TMLElement
// 的瀏覽器中移迫,類型卻是有差別的,在Chrome,Opera中HTMLElement的
// 類型為function管行,此時(shí)就不能用它來判斷了
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';
}
// ******獲取整數(shù)隨機(jī)數(shù)******
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
}
// ******時(shí)間格式化函數(shù)******
function dateFmt(fmt, dateVal) {
if (typeof(fmt) != 'string') return '格式化參數(shù)有誤厨埋!';
// 如果剛開始傳入的時(shí)間參數(shù)是一個(gè)小于30*24*3600*1000毫秒數(shù)的數(shù)字,那么應(yīng)該是求一個(gè)時(shí)間差值(否則就是求日期格式化)捐顷,求時(shí)間差需要對(duì)東八區(qū)的小時(shí)數(shù)進(jìn)行額外處理,因?yàn)閚ew Date(毫秒數(shù))是帶著時(shí)區(qū)值的荡陷,并且北京時(shí)間要比格林威治時(shí)間快8個(gè)小時(shí),所以格式化后小時(shí)上會(huì)多出8小時(shí),應(yīng)減去迅涮。
// 當(dāng)然生成的該對(duì)象不僅可能是時(shí)間废赞,也可能是格林尼治一月份日期(參數(shù)中加上年月日就可以了)。
if((typeof(dateVal) === 'number') && dateVal < 30 * 24 * 3600 * 1000 && !fmt.includes('M')) {//該條件用于判定是否是求時(shí)間差
dateVal = new Date(dateVal - 8 * 3600 * 1000);
}
return fmtDate(fmt, dateVal);
// 用于格式化日期(或時(shí)間差)的方法
function fmtDate(fmt, dateVal) {
// 校驗(yàn)參數(shù)并對(duì)象化日期參數(shù)(轉(zhuǎn)成日期對(duì)象)
let date;
if(dateVal || dateVal === 0) {
date = new Date(dateVal);
}else {
date = new Date();
}
if (date.toString() == 'Invalid Date') return '時(shí)間參數(shù)有誤';
// 單獨(dú)處理年數(shù)
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);
}
// 獲取其余時(shí)間值
let dates = {
'M' : date.getMonth() + 1,
'd' : date.getDate(),
'h' : date.getHours(),
'm' : date.getMinutes(),
's' : date.getSeconds()
}
// 處理替換剩余時(shí)間值叮姑,并返回結(jié)果
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;
}
}
// ******函數(shù)防抖******
/**
解釋:函數(shù)防抖是優(yōu)化高頻率執(zhí)行js代碼的一種手段蛹头,可以讓被調(diào)用的函數(shù)在一
次連續(xù)的高頻率操作過程中只被調(diào)用執(zhí)行一次,降低其執(zhí)行頻率戏溺。
作用:減少代碼執(zhí)行次數(shù)渣蜗,提升網(wǎng)頁性能
應(yīng)用場(chǎng)景:oninput、onmousemove旷祸、onscroll耕拷、onresize等高頻事件
(這類事件雖然高頻,但是還有一個(gè)特點(diǎn)托享,就是人為觸發(fā)的骚烧,就是可能快可能慢;
但是像視頻或音樂的播放闰围,這種持續(xù)高頻但是又不受人為控制的赃绊,這種事件不適合用函數(shù)防抖,
而要用函數(shù)節(jié)流羡榴。因?yàn)楹瘮?shù)防抖是如果不停的觸發(fā)碧查,定時(shí)器會(huì)不停的被清除創(chuàng)建,
定時(shí)器里面的函數(shù)(除最后一次定時(shí)器創(chuàng)建的會(huì)被執(zhí)行外)有可能永遠(yuǎn)都不會(huì)執(zhí)行;
而函數(shù)節(jié)流則是加了雙重開關(guān)忠售,定時(shí)器中函數(shù)至少執(zhí)行過才會(huì)被清除然后再次設(shè)定传惠,所以里面的函數(shù)一定會(huì)執(zhí)行,
所以總體會(huì)被執(zhí)行n次稻扬。所以說函數(shù)節(jié)流應(yīng)用范圍更廣)
*/
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);
}
}
// ******函數(shù)節(jié)流******
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);
}
}
// ******勻速動(dòng)畫******
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);
}
}
// ******緩動(dòng)動(dòng)畫******
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);
}
}
// ******格式化播放次數(shù)******
function fmtPlayCount(playCount){// 格式化推薦歌單后臺(tái)數(shù)據(jù)中的播放次數(shù)數(shù)據(jù)
if((playCount + "").length > 8) {
return (playCount/100000000).toFixed(1) + '億';
}else if((playCount + "").length > 4) {
return (playCount / 10000).toFixed(1) + '萬';
}else {
return playCount;
}
}
// ******創(chuàng)建進(jìn)度條******
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 // 當(dāng)前進(jìn)度條百分比
this.callBefores = [] // 事件之前要執(zhí)行的方法數(shù)組
this.callBacks = [] // 事件之后要執(zhí)行的方法
setTimeout(() => {
// 延遲獲取寬度卦方,防止沒有渲染完獲取的不準(zhǔn)確。
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';
// 初始化小圓點(diǎn)樣式
// 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);
}
// 因?yàn)樵卦赿isplay: none狀態(tài)下是無法一定能通過getComputedStyle獲取到數(shù)據(jù)的泰佳,有可能會(huì)返回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);
}
});
}
// 設(shè)置進(jìn)度條的顏色及圓角樣式(背景色、漸變背景色汽绢、前景色吗跋、漸變前景色、圓點(diǎn)色宁昭、徑向漸變圓點(diǎn)色跌宛、進(jìn)度條是否圓角)
barCss ({barCor, barGradCor, lineCor, lineGradCor, dotCor, dotRadiCor, cirRadius}) {
// 因?yàn)閷捀呤茄舆t獲取的,并且同時(shí)重置了樣式积仗,所以樣式設(shè)置必須在獲取寬高以后設(shè)置疆拘,否則會(huì)被再次重置
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;
}
})
}
// 注:要想拖動(dòng)小圓點(diǎn)必須要執(zhí)行該初始化事件方法
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;
// 回調(diào)函數(shù)里面兩個(gè)參數(shù):一個(gè)是當(dāng)前進(jìn)度條比例,一個(gè)是當(dāng)前進(jìn)度條寬度
// 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){
// 回調(diào)函數(shù)里面兩個(gè)參數(shù):一個(gè)是當(dāng)前進(jìn)度條比例寂曹,一個(gè)是當(dāng)前進(jìn)度條寬度
// 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){
// 回調(diào)函數(shù)里面兩個(gè)參數(shù):一個(gè)是當(dāng)前進(jìn)度條比例哎迄,一個(gè)是當(dāng)前進(jìn)度條寬度
// 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){
// 回調(diào)函數(shù)里面兩個(gè)參數(shù):一個(gè)是當(dāng)前進(jìn)度條比例渺氧,一個(gè)是當(dāng)前進(jìn)度條寬度
// 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){
// 回調(diào)函數(shù)里面兩個(gè)參數(shù):一個(gè)是當(dāng)前進(jìn)度條比例旨涝,一個(gè)是當(dāng)前進(jìn)度條寬度
// 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) {// 防止點(diǎn)擊“點(diǎn)”的時(shí)候也執(zhí)行
that.oLine.style.width = event.offsetX + 'px';
that.linePercent = parseInt(getComputedStyle(that.oLine).width) / that.barWidth
// 回調(diào)函數(shù)里面兩個(gè)參數(shù):一個(gè)是當(dāng)前進(jìn)度條比例,一個(gè)是當(dāng)前進(jìn)度條寬度
// 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);
}
// 更新進(jìn)度條進(jìn)度的方法(參數(shù)寬度既可以是百分比也可以是決定寬度值)
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);
}
// ******創(chuàng)建高亮關(guān)鍵字方法******
function lightKeywords(keyword, html) {
let reg = new RegExp(`(${keyword})`, 'g');
return html.replace(reg, "<span class='keyword'>$1</span>");
}
// ******Storage的存嚷卤场(數(shù)組形式)******
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) {// 歌曲對(duì)象數(shù)組贩耐,{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監(jiān)聽,因?yàn)槿绻獑为?dú)監(jiān)聽一個(gè)對(duì)象的一個(gè)屬性潮太,該對(duì)象初始的時(shí)候就要有該屬性
this.fmtCurrentTime = 0;
this.callBacks = [] // 存儲(chǔ)跟隨播放要執(zhí)行的所有回調(diào)函數(shù)
if(musicLists) {this.initMusicLists(musicLists)}
this._listenCanPlay();
}
// 監(jiān)聽歌曲是否可以播放(內(nèi)部調(diào)用)
_listenCanPlay(canPlay) {
//監(jiān)聽歌曲加載
// this.oAudio.oncanplay = null;
let that = this;
// 不用oncanplay監(jiān)聽管搪,因?yàn)樘O果的safari瀏覽器不會(huì)自動(dòng)加載歌曲資源
// this.oAudio.oncanplay = function(){
this.oAudio.ondurationchange = function(){
// 初始化音樂時(shí)長(zhǎng)
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();//播放音樂
};
}
// 監(jiān)聽歌曲播放
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)
});
}
}
}
// 額外添加跟隨播放要執(zhí)行的回調(diào)函數(shù)
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);
}
// 監(jiān)聽歌曲是否播放完
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;
//將歌詞字符串轉(zhuǎn)化為對(duì)象(內(nèi)部調(diào)用)
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;
}
}
// 同步高亮當(dāng)前歌詞
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(){//設(shè)置靜音按鈕的點(diǎn)擊事件
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;
}
// 初始化音樂進(jìn)度條
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;
}
// 根據(jù)歌曲索引查找id
findSongId(index) {
return this.musicLists[index].id;
}
// 根據(jù)歌曲id查找索引
findSongIndex(songId) {
return this.musicLists.findIndex(function(ele){
return ele.id === songId;
})
}
}
window.isDOM = isDOM; // 判斷是否是dom對(duì)象
window.dateFmt = dateFmt; // 格式化日期或者時(shí)長(zhǎng)
window.debounce = debounce; // 函數(shù)防抖
window.throttle = throttle; // 函數(shù)節(jié)流
window.linearAnimation = linearAnimation; // 線性動(dòng)畫
window.easeAnimation = easeAnimation; // 緩動(dòng)動(dòng)畫
window.fmtPlayCount = fmtPlayCount; // 格式化播放量
window.Progress = Progress; // 進(jìn)度條對(duì)象
window.isPc = isPc; // 判斷是否電腦端
window.lightKeywords = lightKeywords; // 高亮關(guān)鍵字
window.ZLLocalData = ZLLocalData; // 本地存儲(chǔ)方法
window.ZLAudio = ZLAudio; // 音頻播放器對(duì)象
window.getRandomInt = getRandomInt; // 獲取隨機(jī)整數(shù)
})();