一步一步实战HTML音乐播放器

在这里我用HTML5从头开始一步一步来制作一个简约的音乐播放器,大家可以参考一下,接下来正式开始。


音乐播放器效果


播放器分析

这里将播放器分两块来做:

  • 视图层(html + css)
  • 逻辑层 ( js )

视图层分析

视图中包含:

  • 播放器容器
    • 播放器名称
    • 音乐专辑图
    • 音乐信息
      • 歌曲名
      • 歌手
      • 专辑名
    • 控制区
      • 上一曲
      • 播放
      • 下一曲
    • 播放进度条
    • 播放时间
      • 当前时间
      • 歌曲总时间
    • 音频控件
  • 页面背景

逻辑层分析

逻辑层处理包括:

  • 加载歌单
  • 渲染歌曲信息
    • 专辑图
    • 歌曲名
    • 歌手
    • 专辑名
    • 歌曲时长
    • 歌曲音频地址
  • 监听控制按钮
    • 播放按钮 (修改播放状态)
    • 上一曲(判断歌单边界,重新渲染歌曲信息)
    • 下一曲(判断歌单边界,重新渲染歌曲信息)
  • 定时器
    • 同步歌曲当前时间和播放进度条
    • 歌曲播放完,自动切换下一曲

好了,播放器基本分析完成,接下来开始编码了,先进行视图层的编写。


视图层结构编写

根据我在上面的视图层分析,来构建HTML结构。

建立index.html,结构编码如下:

<!-- 页面背景 -->
<body><!-- 播放器容器 --><div class="player"><!-- 播放器名称 --><div class="header">音乐播放器</div><!-- 音乐专辑图 --><div class="albumPic"></div><!-- 音乐信息  --><div class="trackInfo"><!-- 歌曲名 --><div class="name"></div><!-- 歌手 --><div class="artist"></div><!-- 专辑名 --><div class="album"></div></div><!-- 播放进度条 --><div class="progress"></div><!-- 控制区  --><div class="controls"><!-- 播放 --><div class="play"><i class="icon-play"></i></div><!-- 上一曲 --><div class="previous"><i class="icon-previous"></i></div><!-- 下一曲 --><div class="next"><i class="icon-next"></i></div></div>      <!-- 播放时间  --><div class="time"><!-- 当前时间 --><div class="current"></div><!-- 歌曲总时间 --><div class="total"></div></div><!-- 音频控件 --><audio id="audio"><source src=""></audio></div>
</body>

好了,结构编写完毕,接下来编写视图层样式。


视图层样式编写

:这里我是用LESS写的CSS,后面我会贴出完整代码,或者到 CSDN CODE 下载源码

先重置标记样式:

html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed, 
figure, figcaption, footer, header, hgroup, 
menu, nav, output, ruby, section, summary,
time, mark, audio, video {margin: 0;padding: 0;border: 0;font-size: 100%;font: inherit;vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section {display: block;
}
body {line-height: 1;
}
ol, ul {list-style: none;
}
blockquote, q {quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {content: '';content: none;
}
table {border-collapse: collapse;border-spacing: 0;
}

设置body

//这里主要设置背景和flex布局,用于播放器垂直居中
@body-bg: #111;html,body{height: 100%;
}body{background-color: @body-bg;display: flex;align-items: center;justify-content: center;color: #fff;font: 16px "微软雅黑";
}

设置播放器容器 .player

//主要设置播放器的大小、背景颜色、定位等信息
@player-bg: lighten(@body-bg, 10%);
@player-w: 375px;
@player-h: 550px;.player{width: @player-w;height: @player-h;background-color: @player-bg;border-radius: 10px;position: relative;
}

设置播放器名称.header样式:

.player{    .header{padding: 15px 0;text-align: center;}
}

专辑图.albumPic样式:

.player{.albumPic{background-image: url(http://p3.music.126.net/SR9eFEjRB0NsscxN7-fHMw==/3344714372906000.jpg); //这里先放一张临时图片,用于看效果,编写完成后,把这条属性删除即可background-size: cover; //背景模式width: @player-w * 0.72; //通过计算设置宽高,可直接用百分比height: @player-w * 0.72;margin: auto; //居中border-radius: 10px;}
}

专辑信息区域样式:

.player{.trackInfo{text-align: center;padding: 20px 0 15px;font-size: 14px;white-space: nowrap;//单独将歌曲名设置一下大小.name{font-size: 24px;margin-bottom: 10px;font-weight: bold;}}
}

播放进度条样式:

.player{.progress{width: 30%; //这里用于看效果,制作完成后,设置为0height: 20%;position: absolute; //用绝对定位放到播放器容器最下面和最左面bottom: 0;left: 0;background-image: linear-gradient(top, rgba(255, 255, 255, 0), #0099FF); //背景采用从上到下的线性渐变border-bottom-left-radius: 10px;border-bottom-right-radius: 10px;opacity: .4;}
}

按钮控制区域样式设置:

.player{.controls{//位置方面不用再额外设置了,按照对上面的设置,当前控制区的位置正好position: relative;//播放按钮同样采用flex布局,用于对内部的网络字体按钮垂直居中.play{cursor: pointer;width: 75px;height: 75px;border: 2px solid #ccc;border-radius: 50%; //加个圆框margin: auto;display: flex;align-items:center;justify-content:center;color: #fff;font-size: 35px;&:hover{font-size: 40px; //鼠标经过变大字体}}//上、下一曲 共用样式.btn(){cursor: pointer;position: absolute;         top: 25px;font-size: 30px;&:hover{font-size: 32px;}}//设置一下按钮位置.previous{  .btn;       left: 60px;}.next{.btn;right: 60px;}}
}

播放时间区域设置:

.player{.time{width: @player-w - 40px; //计算pdding后的宽度,可自行计算display: flex;position: absolute;bottom: 0;padding: 20px;align-items: center;justify-content: space-between; //两端分布}
}

好了,通过上面的样式设置,播放器的视图层已完毕,看下效果(三个播放控制按钮是引用的字体):

接下来开始编写逻辑层。


逻辑层编写

逻辑层用到了Jquery和歌曲清单数据playlist.js,先引用一下:

<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/playlist.js"></script>

playlist.js就是一堆json的歌单数据,数据是从网易云音乐上获取的,基本内容如下:

//因为做静态页有跨域问题,所以就直接把数据拿出来赋值给`playlist`这个对象上了,下面只保留了需要用到的数据对象
var playlist = {"result": {"tracks": [{"name": "歌曲名","artists": [{"name": "演唱者",}],"album": {"name": "专辑名","picUrl":专辑图","duration": 时长(ms),"mp3Url": "音乐地址"},...//等等等],},
};

网易云音乐歌单json数据接口:http://music.163.com/api/playlist/detail?id=xxx

建立index.js,开始编码:

先定义一个播放状态对象playStatus

//当前播放器状态
var playStatus = {currentTrackLen: playlist.result.tracks.length, //歌单歌曲数currentTrackIndex: 0, //当前播放的歌曲索引,默认加载第一首歌currentTime: 0, //当前歌曲播放的时间currentTotalTime: 0, //当前歌曲的总时间playStatus: true, //true为播放状态,false为暂停状态
};

因为要用到时间的转换,所以编写一个时间转换函数:

var timeConvert = function(timestamp){var minutes = Math.floor(timestamp / 60);var seconds = Math.floor(timestamp - (minutes * 60));if(seconds < 10) {seconds = '0' + seconds;}timestamp = minutes + ':' + seconds;return timestamp;
};

接下来编写一个对象,内部方法是控制播放器的:

//播放器控制方法对象
var playerControls = {//歌曲基本信息设置trackInfo: function(args){//playerlist是playlist.js中的歌单数据,根据需求进行数据读取即可var obj = playlist.result.tracks[playStatus.currentTrackIndex];args = args || {name:obj.name,artist:obj.artists[0].name,album:obj.album.name,albumPic:obj.album.picUrl + '?param=270y270',total:obj.duration,src: obj.mp3Url,};$('.player .trackInfo .name').text(args.name);$('.player .trackInfo .artist').text(args.artist);$('.player .trackInfo .album').text(args.album);   $('.player .albumPic').css('background','url(' + args.albumPic + ')');         $('.player .time .total').text(timeConvert(args.total / 1000)); //因为歌单数据中的播放长度用ms表示的,所以这里 / 1000playStatus.currentTotalTime = Math.floor(args.total / 1000);$('#audio source').attr('src',args.src); //切换音乐通过修改<source>中的src},//播放、暂停状态处理playStatus: function(){$('.player .controls .play i').attr('class', 'icon-' + (playStatus.playStatus?'pause':'play'));if(playStatus.playStatus){//用jquery获取<audio>对象,必须加上[0]$('#audio')[0].play();}else{$('#audio')[0].pause();}},//当前时间和进度处理playTime: function(){$('.player .time .current').text(timeConvert(playStatus.currentTime));$('.player .progress').css('width', playStatus.currentTime / playStatus.currentTotalTime * 100 + '%'); //同步进度条}};

还剩下一个初始化方法了:

var init = function(){//置一下歌曲信息和播放状态playerControls.trackInfo();     playerControls.playStatus();//播放按钮事件监听$('.player .controls .play').click(function(){//修改播放状态playStatus.playStatus = !playStatus.playStatus; //置播放信息playerControls.playStatus();});//上一曲按钮事件监听$('.player .controls .previous').click(function(){//边界判断if(playStatus.currentTrackIndex - 1 < 0){alert('已经没有上一首了');}else{playStatus.currentTrackIndex --;}//此处切换歌曲功能,原来打算采用直接修改src的方法实现,但是修改src后,之前播放的音乐还继续播放着,切换后的音乐却不播放,所以最终采用移除<audio>,再加入<audio>的方式来切换音乐$('#audio').remove();$('.player').append('<audio id="audio"><source src=""></audio>');  //更新音轨信息和播放状态       playerControls.trackInfo();playerControls.playStatus();});//下一曲按钮事件监听$('.player .controls .next').click(function(){if(playStatus.currentTrackIndex + 1 >= playStatus.currentTrackLen){alert('已经没有下一首了');}else{playStatus.currentTrackIndex ++;}//换src的方法没法切换声音,试了好几种方法都不行,只能删了再重建了$('#audio').remove();$('.player').append('<audio id="audio"><source src=""></audio>');          playerControls.trackInfo();playerControls.playStatus();});//用时钟来实时修改当前播放时间及播放完当前曲目自动下一曲setInterval(function(){playStatus.currentTime = $('#audio')[0].currentTime;           playerControls.playTime();if(playStatus.currentTime >= playStatus.currentTotalTime){$('.player .controls .next').click();}}, 300);
};

其后,再加入init()执行一下就OK了。


完整代码

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>H5音乐播放器</title><link rel="stylesheet" type="text/css" href="css/index.css"><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/playlist.js"></script><script type="text/javascript" src="js/index.js"></script>
</head>
<body><div class="player"><div class="header">音乐播放器</div><div class="albumPic"></div><div class="trackInfo"><div class="name"></div><div class="artist"></div><div class="album"></div></div><div class="progress"></div><div class="controls"><div class="play"><i class="icon-play"></i></div><div class="previous"><i class="icon-previous"></i></div><div class="next"><i class="icon-next"></i></div></div>      <div class="time"><div class="current"></div><div class="total"></div></div><audio id="audio"><source src=""></audio></div>
</body>
</html>

index.css

@import 'reset.css';
@import 'fonts.css';
html,
body {height: 100%;
}
body {background-color: #111111;display: -webkit-box;display: -webkit-flex;display: -ms-flexbox;display: flex;-webkit-box-align: center;-webkit-align-items: center;-ms-flex-align: center;align-items: center;-webkit-box-pack: center;-webkit-justify-content: center;-ms-flex-pack: center;justify-content: center;color: #fff;font: 16px "微软雅黑";
}
.player {width: 375px;height: 550px;background-color: #2b2b2b;border-radius: 10px;position: relative;
}
.player .header {padding: 15px 0;text-align: center;
}
.player .albumPic {background-size: cover;width: 270px;height: 270px;margin: auto;border-radius: 10px;
}
.player .trackInfo {text-align: center;padding: 20px 0 15px;font-size: 14px;white-space: nowrap;
}
.player .trackInfo .name {font-size: 24px;margin-bottom: 10px;font-weight: bold;
}
.player .progress {width: 0;height: 20%;position: absolute;bottom: 0;left: 0;background-image: -webkit-linear-gradient(top, rgba(255, 255, 255, 0), #0099ff);background-image: linear-gradient(top, rgba(255, 255, 255, 0), #0099ff);border-bottom-left-radius: 10px;border-bottom-right-radius: 10px;opacity: .4;
}
.player .controls {position: relative;
}
.player .controls .play {cursor: pointer;width: 75px;height: 75px;border: 2px solid #ccc;border-radius: 50%;margin: auto;display: -webkit-box;display: -webkit-flex;display: -ms-flexbox;display: flex;-webkit-box-align: center;-webkit-align-items: center;-ms-flex-align: center;align-items: center;-webkit-box-pack: center;-webkit-justify-content: center;-ms-flex-pack: center;justify-content: center;color: #fff;font-size: 35px;
}
.player .controls .play:hover {font-size: 40px;
}
.player .controls .previous {cursor: pointer;position: absolute;top: 25px;font-size: 30px;left: 60px;
}
.player .controls .previous:hover {font-size: 32px;
}
.player .controls .next {cursor: pointer;position: absolute;top: 25px;font-size: 30px;right: 60px;
}
.player .controls .next:hover {font-size: 32px;
}
.player .time {width: 335px;display: -webkit-box;display: -webkit-flex;display: -ms-flexbox;display: flex;position: absolute;bottom: 0;padding: 20px;-webkit-box-align: center;-webkit-align-items: center;-ms-flex-align: center;align-items: center;-webkit-box-pack: justify;-webkit-justify-content: space-between;-ms-flex-pack: justify;justify-content: space-between;
}

index.js

$().ready(function(){//当前播放器状态var playStatus = {currentTrackLen: playlist.result.tracks.length,currentTrackIndex: 0,currentTime: 0,currentTotalTime: 0,playStatus: true,};//播放器控制方法var playerControls = {//歌曲基本信息trackInfo: function(args){var obj = playlist.result.tracks[playStatus.currentTrackIndex];args = args || {name:obj.name,artist:obj.artists[0].name,album:obj.album.name,albumPic:obj.album.picUrl + '?param=270y270',total:obj.duration,src: obj.mp3Url,};$('.player .trackInfo .name').text(args.name);$('.player .trackInfo .artist').text(args.artist);$('.player .trackInfo .album').text(args.album);   $('.player .albumPic').css('background','url(' + args.albumPic + ')');         $('.player .time .total').text(timeConvert(args.total / 1000));playStatus.currentTotalTime = Math.floor(args.total / 1000);$('#audio source').attr('src',args.src);},//播放、暂停状态处理playStatus: function(){$('.player .controls .play i').attr('class', 'icon-' + (playStatus.playStatus?'pause':'play'));if(playStatus.playStatus){$('#audio')[0].play();}else{$('#audio')[0].pause();}},//当前时间和进度处理playTime: function(){$('.player .time .current').text(timeConvert(playStatus.currentTime));$('.player .progress').css('width', playStatus.currentTime / playStatus.currentTotalTime * 100 + '%');}};var timeConvert = function(timestamp){var minutes = Math.floor(timestamp / 60);var seconds = Math.floor(timestamp - (minutes * 60));if(seconds < 10) {seconds = '0' + seconds;}timestamp = minutes + ':' + seconds;return timestamp;};(function(){playerControls.trackInfo();     playerControls.playStatus();$('.player .controls .play').click(function(){playStatus.playStatus = !playStatus.playStatus; playerControls.playStatus();});$('.player .controls .previous').click(function(){if(playStatus.currentTrackIndex - 1 < 0){alert('已经没有上一首了');}else{playStatus.currentTrackIndex --;}$('#audio').remove();$('.player').append('<audio id="audio"><source src=""></audio>');          playerControls.trackInfo();playerControls.playStatus();});$('.player .controls .next').click(function(){if(playStatus.currentTrackIndex + 1 >= playStatus.currentTrackLen){alert('已经没有下一首了');}else{playStatus.currentTrackIndex ++;}//换src的方法没法切换声音,试了好几种方法都不行,只能删了再重建了$('#audio').remove();$('.player').append('<audio id="audio"><source src=""></audio>');          playerControls.trackInfo();playerControls.playStatus();});setInterval(function(){playStatus.currentTime = $('#audio')[0].currentTime;           playerControls.playTime();if(playStatus.currentTime >= playStatus.currentTotalTime){$('.player .controls .next').click();}}, 300);})();});

代码下载

下载完整源码


博客名称:王乐平博客

博客地址:http://blog.lepingde.com

CSDN博客地址:http://blog.csdn.net/lecepin

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401683.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实战React音乐播放器

上篇文章《一步一步实战HTML音乐播放器》中&#xff0c;我用HTMLJS CSS的方式一步步实现了一个音乐播放器&#xff0c;因为最近接触了一下React&#xff0c;感觉挺不错的&#xff0c;在这里我用React的方式实现一个同样的音乐播放器。 播放器功能 自动显示 专辑图片、歌手名、…

ASP.NET MVC5+EF6+EasyUI 后台管理系统(40)-精准在线人数统计实现-【过滤器+Cache】...

系列目录 上次的探讨没有任何结果&#xff0c;我浏览了大量的文章和个别系统的参考&#xff01;决定用Cache来做&#xff0c;这可能有点难以接受但是配合mvc过滤器来做效果非常好&#xff01; 由于之前的过滤器我们用过了OnActionExecuting这个方法来判断权限 现在在方法被执行…

理解关键的渲染路径

本文转载自&#xff1a;《Understanding the Critical Rendering Path》,原文地址&#xff1a;https: //bitsofco.de/understanding-the-critical-rendering-path/ 当浏览器从服务器接收到一个HTML页面的请求时&#xff0c;到屏幕上渲染出来要经过很多个步骤。浏览器完成这一系…

Openfire3.9.3源代码导入eclipse中开发配置指南(转载)

看到这篇文章的的网友应该已经安装了jdk,eclipse&#xff0c;我就不在安装这些开发工具上赘述了&#xff0c;附载一下openfire的下载地址&#xff1a;http://www.igniterealtime.org/downloads/index.jsp。1、下载源码openfire_src_3_9_3.zip&#xff0c;目前最新的版本是3.9.3…

Gulp在前端的常用操作实例

以前在做代码优化的时候&#xff0c;一般都用一些网上的在线工具来完成&#xff0c;写LESS的时候&#xff0c;一般用Koala来编译&#xff0c;感觉用起来也挺不错的。但是现在构建工具的出现&#xff0c;让以前做的那些繁琐操作变的更方便一些了&#xff0c;我在这里也用构建工具…

深入了解CSS字体度量,行高和vertical-align

本文英文出处:http: //iamvdo.me/en/blog/css-font-metrics-line-height-and-vertical-align 著作权归作者所有。 转载自https: //www.w3cplus.com/css/css-font-metrics-line-height-and-vertical-align.html line-height和vertical-align在CSS中是两个简单的属性。如此简单&…

HTML5 Canvas制作雷达图实战

雷达图又叫蜘蛛网图&#xff0c;是一种对各项数据查看很明显的表现图&#xff0c;在很多游戏中&#xff0c;对游戏中的每个角色的分析图一般也用这种图。 下面&#xff0c;用HTML5的Cavas来实现雷达图。 效果 一、创建Canvas var mW 400; var mH 400; var mCtx null;var c…

AlphaBlend

AlphaBlend实现透明效果&#xff0c;只是仅仅能针对某块区域进行alpha操作&#xff0c;透明度可设。 TransparentBlt能够针对某种颜色进行透明&#xff0c;只是透明度不可设。 AlphaBlend&#xff1a; BLENDFUNCTION bn; bn.AlphaFormat 0; bn.BlendFlags 0; bn.BlendOp AC_…

ECMAScript 6网页样式修正器

最近在看ES6这一方面的图书&#xff0c;在搜索的过程中发现了《ECMAScript 6 入门-阮一峰》&#xff0c;感觉还不错。因为我个从比较喜欢看纸质的书&#xff0c;就想把这本书给打印下来。 但是网页版的《ECMAScript 6 入门-阮一峰》设置的样式只适合在网页上查看&#xff0c;并…

PWA(Progressive Web App)入门系列:(一)PWA简介

前言 PWA做为一门Google推出的WEB端的新技术&#xff0c;好处不言而喻&#xff0c;但目前对于相关方面的知识不是很丰富&#xff0c;这里我推出一下这方面的入门教程系列&#xff0c;提供PWA方面学习。 什么是PWA PWA全称Progressive Web App&#xff0c;直译是渐进式WEB应用…

Vue DevTools可使用修正方法

因为工作要求&#xff0c;目前主要在用Vue.js技术栈做开发&#xff0c;调试是必不可少的&#xff0c;这里会用的Vue DevTools的调试工具&#xff0c;问题就出在这里&#xff0c;当用Vue DevTools做调试时&#xff0c;很多时候都不能用&#xff0c;提示没有监测到Vue&#xff0c…

ZRender实现粒子网格动画实战

注&#xff1a;本博文代码基于ZRender 3.4.3版本开发&#xff0c;对应版本库地址&#xff1a;ZRender 库。 效果 实现分析 通过上面显示的效果图&#xff0c;可以看出&#xff0c;这种效果就是在Canvas中生成多个可移动的点&#xff0c;然后根据点之间的距离来确定是否连线&am…

CSS动画实战:创建一个太极Loading图

这里主要是使用CSS的animation和伪类来构建&#xff0c;分析设定关键帧的执行顺序和时间段。 效果 动画分析 首先通过效果对动画执行进行一下分析&#xff1a; 边框的四条边进行按顺序动画加载 。矩形边框变为圆行边框。太极图内部图案渐渐出现。太极图旋转。整个动画逆序执…

PWA(Progressive Web App)入门系列:(二)相关准备

前言 在上一章中&#xff0c;对PWA的相关概念做了基本介绍&#xff0c;了解了PWA的组成及优势。为了能够更快的进入PWA的世界&#xff0c;这一章主要对在PWA开发中&#xff0c;需要注意的问题&#xff0c;运行的环境及调试工具做介绍说明。 浏览器要求 因为目前各浏览器对于…

PWA(Progressive Web App)入门系列:(三)PWA关键技术Manifest

前言 前面说过&#xff0c;让Web App能够达到Native App外观体验的主要实现技术就是PWA中的manifest技术&#xff0c;本章会详细说明manifest的实现&#xff0c;及各个参数的具体含义&#xff0c;还将了解如何定义Web App的启动图标、启动样式等。 简介 manifest是一种简单的…

利用百度LBS做一个小Demo

为什么80%的码农都做不了架构师&#xff1f;>>> 申请ak&#xff08;即获取密钥&#xff09;http://lbsyun.baidu.com/apiconsole/key?applicationkey 去这儿注册一个开发者账号即可拼写发送http请求的url譬如这样的调用http://api.map.baidu.com/geocoder/v2/?ad…

PWA(Progressive Web App)入门系列:(四)Promise

前言 这一章说一下ES6的Promise对象。为什么要在PWA系列的文章中讲Promise呢&#xff1f;因为PWA中的许多技术API中都是以Promise返回的方式返回的&#xff0c;为了对后续章节中PWA技术API更好的理解&#xff0c;这里就来说一个Promise对象。 Promise出现的背景 在JavaScrip…

图文详解如何搭建Windows的Android C++开发环境

原地址:http://www.apkbus.com/android-18595-1-1.html ////TITLE:// 图文详解如何搭建Windows的Android C开发环境&#xff08;一&#xff09;//AUTHOR:// norains//DATE:// Thursday 14-April-2011//Environment:// Cygwin 1.7.9// Android NDK r5//1. 下载A…

PWA(Progressive Web App)入门系列:(五)Web Worker

前言 在说Service Worker前有必要说一下Web Worker&#xff0c;因为Service Worker本身就属于Web Worker的延伸&#xff0c;大部分功能也是基于Web Worker进行的扩展。 背景 众所周知&#xff0c;JavaScript引擎是以单线程调度的方式进行&#xff0c;我们无法同时运行多个Ja…

Glob Patterns匹配模式使用

前段时间在用workbox时&#xff0c;在做precache时&#xff0c;匹配模式基于的是Glob Pattern模式&#xff0c;于是就看了下相关文档。 下面翻译一下node-glob的使用&#xff0c;原文&#xff1a;https://github.com/isaacs/node-glob#glob-primer Glob 像在shell里面&#x…