主要是靠咋没的audio对象,我就不多说废话了,也不会说,直接上代码;

HTML

<!DOCTYPE html>
<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>迷你音乐播放器</title><!-- 字体图标库 --><link rel="stylesheet" href="../fonts/css/font-awesome.css"><link rel="stylesheet" href="../css/网页迷你音乐播放器.css"></head><body><div class="container"><div class="bg"></div><div class="bg-mask"></div><div class="player"><div class="player-track"><div class="album-name">红模仿</div><div class="track-name">周杰伦 - 红模仿</div><div class="track-time"><div class="current-time">00:00</div><div class="total-time">03:50</div></div><div class="progress-box"><div class="hover-time">00:36</div><div class="progress-bar"></div></div></div><div class="player-content"><div class="album-cover"><img src="../image/周杰伦 - 红模仿.jpg" alt="" class="active"></div><div class="play-controls"><div class="control"><div class="button play-prev"><i class="fa fa-step-backward"></i></div></div><div class="control"><div class="button play-pause"><i class="fa fa-play"></i></div></div><div class="control"><div class="button play-next"><i class="fa fa-step-forward"></i></div></div><div class="control"><div class="button play-select"><label class="SelectYse"></label></div></div></div><div class="play-controlsTwo"><label><input type="checkbox" hidden><span></span><i class="indicator"></i></label></div></div></div></div><script src="../javascript/jquery-3.6.0.min.js"></script><script src="../javascript/网页迷你音乐播放器.js"></script></body>
</html>

CSS

* {/* 初始化 */margin: 0;padding: 0;
}body {/* 100%窗口高度 */height: 100vh;/* 弹性布局 居中显示 */display: flex;justify-content: center;align-items: center;
}.container {width: 430px;min-height: 100px;
}/* 模糊背景图 */
.bg {/* 固定定位 */position: fixed;top: -40px;right: -40px;bottom: -40px;left: -40px;background: url('../image/周杰伦 - 红模仿.jpg') no-repeat;background-size: cover;background-position: center;/* 模糊滤镜 */filter: blur(40px);z-index: 1;
}/* 半透明白色遮罩层 */
.bg-mask {position: fixed;top: 0;right: 0;bottom: 0;left: 0;background: rgba(255, 255, 255, 0.5);z-index: 2;
}.player {position: relative;z-index: 3;width: 100%;min-height: 100px;height: 100px;
}/* 歌曲信息轨道区域 */
.player-track {position: absolute;top: 0;right: 15px;bottom: 0;left: 15px;padding: 13px 22px 10px 184px;background-color: rgba(255, 255, 255, 0.8);border-radius: 15px;/* 改变top时的过渡效果 */transition: top 0.3s ease;
}/* 歌曲信息轨道区域活动态 */
.player-track.active {/* 上移 */top: -95px;
}.album-name {color: #333;font-size: 17px;font-weight: bold;overflow: hidden;white-space: nowrap;text-overflow: ellipsis;
}.track-name {color: #888;font-size: 13px;margin: 3px 0 12px 0;
}.track-time {height: 12px;line-height: 12px;margin-bottom: 4px;overflow: hidden;
}.current-time,
.total-time {color: #ff668f;font-size: 11px;transition: 0.3s ease;
}.current-time {float: left;
}.total-time {float: right;
}/* 播放进度区域 */
.progress-box {position: relative;height: 4px;transition: height 0.3s ease;background-color: #ead2d7;border-radius: 4px;cursor: pointer;
}.progress-box:hover {height: 8px;border-radius: 8px;
}/* 悬停进度条显示时间 */
.hover-time {position: absolute;top: -30px;background-color: rgba(0, 0, 0, 0.8);color: #FFFFFF;font-size: 12px;padding: 5px 6px;border-radius: 4px;display: none;
}/* 已播放的进度条颜色 */
.progress-bar {position: absolute;top: 0;right: 0;bottom: 0;left: 0;background-color: #fd6d94;border-radius: 4px;z-index: 1;width: 0;/* 改变width时的过渡效果 */transition: width 0.2s ease;
}.player-content {position: relative;min-height: 100px;height: 100%;transition: height 0.3s ease;background-color: #FFFFFF;border-radius: 15px;z-index: 2;box-shadow: 0 30px 80px #656565;
}/* 封面 */
.album-cover {width: 115px;height: 115px;border-radius: 50%;position: absolute;top: -40px;left: 40px;box-shadow: 0 0 0 10px #FFFFFF;overflow: hidden;transition: 0.3s ease;
}/* 唱片中间的小圆点 */
.album-cover::before {content: "";width: 20px;height: 20px;background-color: #d6dee6;position: absolute;top: 50%;right: 0;bottom: 0;left: 0;border-radius: 50%;margin: -10px auto auto auto;box-shadow: inset 0 0 0 2px #FFFFFF;z-index: 1;
}/* 封面活动态 */
.album-cover.active {top: -60px;box-shadow: 0 0 0 4px #fff7f7,0 30px 50px -15px #afb7c1;
}.album-cover img {display: block;width: 100%;height: 0%;object-fit: cover;opacity: 0;
}.album-cover img.active {height: 100%;opacity: 1;
}/* 播放时封面旋转 */
.album-cover.active img.active {/* 执行动画:动画名 时长 线性的 无限次播放 */animation: rotateAlbumCover 5s linear infinite;
}/* 控制区 */
.play-controls {width: 255px;height: 100px;float: right;overflow: hidden;display: flex;align-items: center;padding-right: 2px;
}.play-controlsTwo {width: 100%;height: 58px;position: absolute;bottom: 0px;z-index: -1;display: none;justify-content: center;border-radius: 15px;overflow: hidden;box-sizing: border-box;padding: 0px 9px 9px 9px;
}.control {flex: 1;
}.control .button {width: 54px;height: 75px;display: flex;justify-content: center;align-items: center;background-color: #FFFFFF;border-radius: 6px;cursor: pointer;transition: 0.2s ease;
}.control .button i {color: #d6dee6;font-size: 30px;transition: 0.2s ease;
}.control .button:hover {background-color: #d6d6de;
}.control .button:hover i {color: #FFFFFF;
}.button>label {position: relative;width: 35px;height: 5px;cursor: pointer;display: block;border-radius: 2.5px;background-color: #d6dee6;
}.button>label::before,
.button>label::after {width: 35px;height: 5px;display: block;z-index: 1;cursor: pointer;background-color: #d6dee6;border-radius: 2.5px;content: "";position: absolute;left: 0;
}.button>label::before {top: -10px;
}.button>label::after {top: 10px;
}.control>.button:hover>.SelectYse,
.control>.button:hover>label::before,
.control>.button:hover>label::after {background-color: #FFFFFF;
}.button>.SelectYse::before,
.SelectYse::after {transition: top 0.5s;
}.button>.SelectNo {background: transparent;
}.button>.SelectNo::before,
.button>.SelectNo::after {transition: transform 0.5s;
}.button>.SelectNo::before {top: 0px;transform: rotate(-45deg);
}.button>.SelectNo::after {top: 0px;transform: rotate(45deg);
}.play-controlsTwo>label {/* 相对定位 */position: relative;margin: 5px 0;cursor: pointer;
}.play-controlsTwo>label:before {content: "播放本地歌曲";position: absolute;top: 0px;left: -165px;width: 165px;text-align: center;font-weight: bold;line-height: 42px;font-size: 24px;
}.play-controlsTwo>label::after {content: "播放动漫歌曲";position: absolute;top: 0px;right: -166px;width: 165px;text-align: center;font-weight: bold;line-height: 42px;font-size: 24px;
}.play-controlsTwo>label>span {position: relative;display: block;width: 80px;height: 40px;background-color: #FFFFFF;border-radius: 40px;/* 内阴影 */box-shadow: inset 0 2px 15px rgba(0, 0, 0, 0.2),inset 0 2px 2px rgba(0, 0, 0, 0.2),inset 0 -1px 1px rgba(0, 0, 0, 0.2);
}.play-controlsTwo>label>.indicator {position: absolute;left: 0;top: 0;width: 40px;height: 40px;background: linear-gradient(to bottom, #FFFFFF, #eff1f2);border-radius: 50%;box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5),inset 0 1px 1px rgba(255, 255, 255, 0.1);transform: scale(0.9);transition: 0.5s;
}.play-controlsTwo>label>input:checked~.indicator {left: 40px;
}.play-controlsTwo>label>input:checked~span {background-color: #d6dee6;
}/* 定义动画 */
@keyframes rotateAlbumCover {0% {transform: rotateZ(0);}100% {transform: rotateZ(360deg);}
}

JavaScript

// 要操作的元素
let play_pause = document.querySelector('.play-pause'),player_track = document.querySelector('.player-track'),album_cover = document.querySelector('.album-cover'),bg = document.querySelector('.bg'),album_name = document.querySelector('.album-name'),track_name = document.querySelector('.track-name'),track_time = document.querySelector('.track-time'),current_time = document.querySelector('.current-time'),total_time = document.querySelector('.total-time'),progress_box = document.querySelector('.progress-box'),hover_time = document.querySelector('.hover-time'),progress_bar = document.querySelector('.progress-bar'),player_content = document.querySelector('.player-content'),play_prev = document.querySelector('.play-prev'),play_next = document.querySelector('.play-next'),play_select = document.querySelector('.play-select'),play_select_label = document.querySelector('.play-select>label'),play_controlsTwo = document.querySelector('.play-controlsTwo'),play_controlsTwo_input = document.querySelector('.play-controlsTwo>label>input');// 动漫歌曲播放记录
let comic_name = new Array();
// 歌曲信息数组
let track_names = ['周深 - 大鱼', '徐心愉 - 雾里 (完整女声版)', '萧忆情 - 朝辞白帝城 (Live)', '温亮亮 - 相信我们会创造奇迹', '鞠婧祎 - 红昭愿 (Live)','蒋家驹 - 佛系少年', '周杰伦 - 红模仿', '刘凤瑶 - 感官先生', '周杰伦 - 夜曲', '焦迈奇 - 我的名字', '周杰伦 - 本草纲目'
];// 定义变量
let progress_t, //鼠标在进度条上悬停的位置progress_loc, //鼠标在进度条上悬停的音频位置c_m, //悬停音频位置(分钟)ct_minutes, //悬停播放位置(分)ct_seconds, //悬停播放位置(秒)cur_minutes, //当前播放时间(分)cur_seconds, //当前播放时间(秒)dur_minutes, //音频总时长(分)dur_seconds, //音频总时长(秒)play_progress, //播放进度State = false, //播放状态labelInput = false, //播放哪种歌曲jilushu = 0; //记录动漫记录中的上下首// 初始化歌曲下标
const array = new Uint32Array(1);
maxUint = 0xffffffff //maxUint为最大的可能值
const randomNum = crypto.getRandomValues(array)[0] / maxUint;
let cur_index = Math.floor((4 - 0 + 1) * randomNum + 0) - 1;// 初始化
function initPlayer() {audio = new Audio(); //创建音频对象audio.loop = false; //不循环播放selectTrack(0);// 绑定播放暂停按钮的点击事件play_pause.addEventListener('click', playPause);// 进度条鼠标移动事件progress_box.addEventListener('mousemove', function(e) {showHover(e);});// 进度条鼠标离开事件progress_box.addEventListener('mouseout', hideHover);// 进度条点击事件progress_box.addEventListener('click', playFromClickedPos);// 音频播放位置改变事件audio.addEventListener('timeupdate', updateCurTime);// 上一首按钮点击事件play_prev.addEventListener('click', function() {selectTrack(-1);});// 下一首按钮点击事件play_next.addEventListener('click', function() {selectTrack(1);});play_select.addEventListener('click', UIadjustment);play_controlsTwo_input.addEventListener('change', networkingANDswitch);
}//判断设备是否联网,动漫歌曲开关是否打开
function networkingANDswitch() {if (this.checked === true) {if (navigator.onLine) { //正常工作labelInput = true;} else { //执行离线状态时的任务this.checked = false;alert('你的设备未联网');}} else {labelInput = false;}if (audio.currentTime == 0 && audio.paused === true)selectTrack(1);
}//单击菜单时调整界面
function UIadjustment() {if (play_select_label.className == 'SelectYse') {play_select_label.classList.remove('SelectYse');play_select_label.classList.add('SelectNo');player_content.style.height = '158%';setTimeout(function() {play_controlsTwo.style.display = 'flex';}, 300);} else {play_select_label.classList.remove('SelectNo');play_select_label.classList.add('SelectYse');play_controlsTwo.style.display = 'none';player_content.style.height = '100%';}
}// 播放暂停
function playPause() {setTimeout(function() {if (audio.paused) {player_track.classList.add('active');play_pause.querySelector('.fa').classList = 'fa fa-pause';album_cover.classList.add('active');audio.play();State = true;} else {player_track.classList.remove('active');play_pause.querySelector('.fa').classList = 'fa fa-play';album_cover.classList.remove('active');audio.pause();State = false;}}, 100);
}// 显示悬停播放位置弹层
function showHover(e) {// 计算鼠标在进度条上的悬停位置(当前鼠标的X坐标-进度条在窗口中的left位置)progress_t = e.clientX - progress_box.getBoundingClientRect().left;// 计算鼠标在进度条上悬停时的音频位置// audio.duration 音频总时长progress_loc = audio.duration * (progress_t / progress_box.getBoundingClientRect().width);// 将悬停音频位置转为分钟c_m = progress_loc / 60;ct_minutes = Math.floor(c_m); //分ct_seconds = Math.floor(progress_loc - ct_minutes * 60); //秒if (ct_minutes < 10) {ct_minutes = '0' + ct_minutes;}if (ct_seconds < 10) {ct_seconds = '0' + ct_seconds;}if (isNaN(ct_minutes) || isNaN(ct_seconds)) {hover_time.innerText = '--:--';} else {hover_time.innerText = ct_minutes + ':' + ct_seconds;}// 设置悬停播放位置弹层的位置并显示hover_time.style.left = progress_t + 'px';hover_time.style.marginLeft = '-20px';hover_time.style.display = 'block';
}// 隐藏悬停播放位置弹层
function hideHover() {hover_time.innerText = '00:00';hover_time.style.left = '0px';hover_time.style.marginLeft = '0px';hover_time.style.display = 'none';
}// 从点击的位置开始播放
function playFromClickedPos() {// 设置当前播放时间audio.currentTime = progress_loc;// 设置进度条宽度progress_bar.style.width = progress_t + 'px';// 隐藏悬停播放位置弹层hideHover();
}// 改变当前播放时间
function updateCurTime() {// 当前播放时间(分)cur_minutes = Math.floor(audio.currentTime / 60);// 当前播放时间(秒)cur_seconds = Math.floor(audio.currentTime - cur_minutes * 60);// 音频总时长(分)dur_minutes = Math.floor(audio.duration / 60);// 音频总时长(秒)dur_seconds = Math.floor(audio.duration - dur_minutes * 60);// 计算播放进度play_progress = audio.currentTime / audio.duration * 100;cur_minutes = cur_minutes < 10 ? '0' + cur_minutes : cur_minutes;cur_seconds = cur_seconds < 10 ? '0' + cur_seconds : cur_seconds;dur_minutes = dur_minutes < 10 ? '0' + dur_minutes : dur_minutes;dur_seconds = dur_seconds < 10 ? '0' + dur_seconds : dur_seconds;// 设置播放时间if (isNaN(cur_minutes) || isNaN(cur_seconds)) {current_time.innerText = '00:00';} else {current_time.innerText = cur_minutes + ':' + cur_seconds;}// 设置总时长if (isNaN(dur_minutes) || isNaN(dur_seconds)) {total_time.innerText = '00:00';} else {total_time.innerText = dur_minutes + ':' + dur_seconds;}// 设置进度条宽度progress_bar.style.width = play_progress + '%';// 播放完毕if (play_progress == 100) {//自动播放下一首selectTrack(1);//恢复样式// play_pause.querySelector('.fa').classList='fa fa-play';// progress_bar.style.width='0px';// current_time.innerText='00:00';// player_track.classList.remove('active');// album_cover.classList.remove('active');}
}// 切换歌曲(flag: 0=初始, 1=下一首, -1=上一首)
function selectTrack(flag) {if (labelInput === false) {if (flag == 0 || flag == 1) {if (cur_index == (track_names.length - 1)) {cur_index = 0;} else {++cur_index;}} else {if (cur_index == 0) {cur_index = (track_names.length - 1);} else {--cur_index;}}if (cur_index > -1 && cur_index < track_names.length) {try {if (flag == 0) {play_pause.querySelector('.fa').classList = 'fa fa-play';} else if (State == true) {play_pause.querySelector('.fa').classList = 'fa fa-pause';}progress_bar.style.width = '0px';current_time.innerText = '00:00';total_time.innerText = '00:00';// 当前专辑名let cur_album = track_names[cur_index];// 当前歌曲信息(歌手 - 歌名)let cur_track_name = track_names[cur_index];// 设置音频路径和判断文件是否正常加载audio.src = '../mp3/' + cur_album + '.mp3?PC' + new Date().getTime();setTimeout(function() {if (audio.readyState == 0) {audio.src = '../wav/' + cur_album + '.wav?PC' + new Date().getTime();setTimeout(function() {if (audio.readyState == 0) {audio.src = '../flac/' + cur_album + '.flac?PC' + new Date().getTime();setTimeout(function() {if (audio.readyState == 0) {selectTrack(1);} else {AudioNormal();}}, 333);} else {AudioNormal();}}, 333);} else {AudioNormal();}}, 334);// audio.onerror=function(){}function AudioNormal() {// 当切换上一首,下一首时,判断是否播放if (flag != 0 && State == true) {audio.play();}// 设置专辑名album_name.innerText = cur_album;// 设置歌曲信息track_name.innerText = cur_track_name;// 设置封面document.querySelector('img').src = '../image/' + cur_album + '.jpg';// 将封面设置为背景大图bg.style.backgroundImage = 'url(' + document.querySelector('img').src + ')';document.querySelector('img').onerror = function() {// 设置封面document.querySelector('img').src = '../image/迷你音乐.png';// 将封面设置为背景大图bg.style.backgroundImage = 'url(' + document.querySelector('img').src + ')';throw new Error('图片路径有误');}}} catch (e) {console.log('程序抛出异常');}} else {// 切换溢出专辑数组时, 恢复cur_indexif (flag == 0 || flag == 1) {--cur_index;} else {++cur_index;}}} else {if (flag == 0 || flag == 1) {if (jilushu >= comic_name.length) {$.ajax({type: 'GET',url: 'https://anime-music.jijidown.com/api/v2/music',success: function(msg) {audio.src = msg.res.play_url;if (State == true) {audio.play();}// 设置专辑名album_name.innerText = msg.res.title;// 设置歌曲信息track_name.innerText = msg.res.title;let comic_names = {title: msg.res.title,url: msg.res.play_url};comic_name.push(comic_names);jilushu = comic_name.length;}});} else {audio.src = comic_name[jilushu].url;if (State == true) {audio.play();}// // 设置专辑名album_name.innerText = comic_name[jilushu].title;// // 设置歌曲信息track_name.innerText = comic_name[jilushu].title;jilushu += 1;}} else {if (jilushu - 2 >= 0) {audio.src = comic_name[jilushu - 2].url;if (State == true) {audio.play();player_track.classList.add('active');album_cover.classList.add('active');}// // 设置专辑名album_name.innerText = comic_name[jilushu - 2].title;// // 设置歌曲信息track_name.innerText = comic_name[jilushu - 2].title;jilushu -= 1;}}document.querySelector('img').src = '../image/迷你音乐.png';bg.style.backgroundImage = 'url(../image/迷你音乐.png)';}
}// 初始化播放器
initPlayer();

百度网盘领取完整资源

链接:https://pan.baidu.com/s/1JN8zQjwmk3bjpjgDazRo7A 

提取码:q3m0

注:代码来源各大平台,我只是修改了代码,原作者已忘记,gitee平台上误打误撞下载到的。

这是我的个人小站https://www.zhiqinzhe.com

用js创建audio对象实现网页迷你音乐播放器相关推荐

  1. html中加入音乐播放器,HTML网页添加音乐播放器做背景音乐代码-标签audio

    是 HTML 5 的一个新标签,定义声音,比如音乐或其他音频流. 调用格式: src="http://sc1.111ttt.com/2016/1/02/04/195040016323.mp3 ...

  2. 个人小作品之迷你音乐播放器(移动端)

    关于viewport viewport是用户网页的可视区域,中文可称为"可视区". 手机浏览器是将页面放在一个虚拟的窗口(viewport)中,通常这个窗口比屏幕宽,这样就不用把每 ...

  3. html实现网页左下角音乐播放器

    html实现网页左下角音乐播放器 效果图如下: 实现代码如下: <!DOCTYPE html> <html lang="en"> <head>& ...

  4. C#、.NET迷你音乐播放器

    闲来没事自己做了一个基于WindowsMediaPlayer的迷你音乐播放器,界面如下图 功能简介: 1.循环模式:顺不播放 axWMusicPlayer.settings.setMode(" ...

  5. 迷你音乐播放器v1.0正式上线!

    迷你音乐播放器V1.0正式上线! 版本介绍: 1.随机播放切换开关(通过点击专辑图片) 2.通过拖动歌曲名及艺术家名调整歌曲播放进度 3.手机浏览访问支持熄屏播放 4.暂不支持在线搜索功能 快来一起分 ...

  6. Flash版(迷你音乐播放器mp3Player1.0 Beta1 )附源码

    迷你音乐播放器mp3Player1.0 Beta1  ================= //What's new: 主要功能特色: 1.支持歌曲名称,歌手名称以及专辑等关键字搜索. 2.支持随机搜索 ...

  7. html音乐的url,网页制作音乐播放器代码实现及html与url(4页)-原创力文档

    说明: html 和 URL 其实都说的一种地址,如果想在网页中插入 一段代码,以下插入的是音乐播放器代码,都需要 URL 这个地址, 当然你可以在百度里面找到.以前做了一个网页就是以下的这些代码, ...

  8. 仿网易云网页版音乐播放器,实现歌词随歌曲进行滚动高亮

    引言 前几天在使用网易云网页版听歌时,看着那个页面的歌词随歌曲进行高亮,突然也想自己手动地去实现一下,于是呢,就仿照了网易云音乐的网页自己也写了个页面.效果图如下: 当然了,此处不做css的样式介绍, ...

  9. [HTML5]简单网页本地音乐播放器

    既然HTML5提出与本地交互方便,就想写个HTML5的本地音乐播放器.一开始问题主要集中在怎么读取本地文件路径,我想肯定可以用JS实现去操作本地文件(因为node.js很容易实现读取本地文件,但是原生 ...

最新文章

  1. oracle增量备份如何恢复,【Oracle】增量备份和全库备份怎么恢复数据库
  2. 《Effective C#》读书笔记——条目10:使用可选参数减少方法重载的数量C#语言习惯...
  3. PMP 第七章 项目成本管理
  4. 毕业年限不长的前端焦虑和突破方法
  5. [前台]---图片上传和校验
  6. Azure SQL Database (1) 用户手册
  7. js webpack 解决跨域问题_详解webpack-dev-server使用http-proxy解决跨域问题
  8. Effective Objective-C 2.0 — 第二条:类的头文件中尽量少引入其他头文件
  9. T-SQL 函数概述
  10. 春晚鬼畜 B 站日排行最高,赵本山:我的时代还没有结束!
  11. 恶心的下载站点:52z.com
  12. 海康威视流媒体服务器配置心得
  13. PS时间轴制作动态图
  14. urllib库如何设置代理如何传递并保存cookie【python爬虫入门进阶】(02-3)
  15. consul报错:consul at least one health check on one instance is failing
  16. Mac 自动化执行脚本 Expect
  17. ChatGPT连接企微
  18. 社群运营怎么做更有效?
  19. python模拟登录qq邮箱爬取_python模拟登录qq邮箱
  20. B站 bilibili 视频、分区、up主数据合集

热门文章

  1. 如何通过 WhatsApp 开展营销活动?
  2. 【bzoj1905】捉迷藏(线段树)
  3. 本土英雄的退场和归来:Micromax教给了在印中国手机厂商哪些事?
  4. bigemap大地图软件功能对比分析
  5. linux下git和github搭建使用教程
  6. 分享一个统计 Android 模块构建时长的脚本工具
  7. 【开发技术】2万字详细介绍Docker 和 web项目的部署监控,docker部署,拉取kafana,prometheus镜像监控
  8. 龙讯系列视频转换,LT9211,LT8918,功能:lvds转BT656,lvds转mipi(CSI\DSI)RGB转MIPI(DSI\CSI) BT656\601\1120转HDMI1.4\DVI
  9. JAVA SE (7)
  10. GD32450i-EVAL学习笔记 1 - 准备工作