马黑黑 发表于 2024-1-27 08:07

保姆级range进度条音频播放器开发教程(二)

<style>
.mum { font-size: 18px; }
.mum pre { padding: 12px; background: #eee; color: blue; font-size: 16px; tab-size: 4; white-space: pre-wrap; word-wrap: break-word; }
.mum a { color: darkred; }
.mum a:hover { color: red; }
.tGreen { color: green; }
.tRed { color: red; }
</style>

<div class="mum">

<h2>保姆级range进度条音频播放器开发教程(二)</h2>
<p>上一节,<a href="https://www.huachaowang.com/forum.php?mod=viewthread&tid=73850&extra=page%3D1" target="_blank">保姆级range进度条音频播放器开发教程(一)</a>,我们通过音频播放时的 timeupdate 事件成功地驱动了滑杆进度条的运行,美中不足的是音频的播放还依赖于 audio 界面按钮来控制。本节,我们将创建自己的按钮,用下面这张图片,可以更换为其他的:</p>
<p><img src="https://638183.freep.cn/638183/small/002_133507167677724892.png" alt="" title="图片尺寸:&#13;128*127"</p>
<p>代码如下:</p>
<pre>
&lt;p&gt;&lt;img id="btnplay" src="图片地址" alt="" title="播放/暂停" /&gt;&lt;p&gt;
</pre>
<p>img 标签是行内标签,所以给它加一个p标签,以确保它独立占领一行。图片尺寸需要一个规范(宽高正比、不要太大、背景透明等等),否则可能不协调,同时图片要和 range 滑杆整合在一起,所以到这里,我们需要设置一下 CSS 层叠样式,用一个容器元素装载进度条和按钮,以便播放器将来用到帖子之时可以把它们当做一个整体随意安置在特定的地方。以下代码,我们设置一个 id 选择器 <span class="tRed">#mplayer</span>,它是容器,其对应的 html 标签将装载 <span class="tRed">#btnplay(按钮)</span>、<span class="tRed">#mprog</span>(input range即进度条),按钮和进度条对应的标签都是 inline-block(行内块) 级别的,它们还要套上 p 标签,因此 CSS 代码还需要规范一下 p 标签的样式。此外,按钮要运行一个关键帧动画,我们为此还需要设置一个 @keyframes 动画。下面是代码和简要的注释说明:</p>
<pre>
<span class="tGreen">/* css代码 */</span>

<span class="tGreen">/* 播放控制器容器样式 */</span>
#mplayer {
        position: absolute;
        text-align: center; <span class="tGreen">/* 文本居中属性 : 令行内元素水平居中 */</span>
        color: white;
}
<span class="tGreen">/* 容器里的p标签样式 */</span>
#mplayer p {
        margin: 0;
        padding: 0;
}
<span class="tGreen">/* 进度条样式 */</span>
#mprog {
        width: 240px;
        accent-color: darkgreen; <span class="tGreen">/* input相关控件强调色 : 改变range默认配色 */</span>
        outline: none;
        cursor: pointer;
}
<span class="tGreen">/* 图片按钮样式 :宽高一致 */</span>
#btnplay {
        width: 80px;
        height: 80px;
        cursor: pointer;
        animation: rotating 6s infinite linear var(--state);
}
<span class="tGreen">/* 关键帧动画 :旋转一周 */</span>
@keyframes rotating { to { transform: rotate(360deg); } }
</pre>
<p>下面就是html代码了,注意我们去掉了上一节 audio 标签的 controls 属性,这样 audio 播放界面就不会出现了,我们将要完全通过图片按钮的点击操作来控制音乐的播放与暂停:</p>
<pre>
&lt;audio id="aud" src="音频地址"&gt;&lt;/audio&gt;
&lt;div id="mplayer"&gt;
        &lt;p&gt;&lt;img id="btnplay" src="图片地址" title="播放/暂停" alt="" /&gt;&lt;/p&gt;
        &lt;p&gt;&lt;input id="mprog" type="range" min="0" step="1" max="100" value="0" title="调节进度" /&gt;&lt;/p&gt;
&lt;/div&gt;
</pre>
<p>接下来,需要介绍 audio 控件的两个方法、一个对象属性,以及元素的单击事件、控制CSS变量值方法,这些都是基于JS的,以下是说明和代码举例:</p>
<pre>
<span class="tGreen">/*① play 和 pause 方法 :播放和暂停 */</span>
aud.play(); <span class="tGreen">/* id 为 aud 的 audio 控件播放音乐 */</span>
aud.pause(); <span class="tGreen">/* aud 暂停播放 */</span>

<span class="tGreen">/*② paused 属性 :audio控件是否暂停中 */</span>
let flag = aud.paused; <span class="tGreen">/* 这将返回 true 或 false,是稍后判断按钮单击是播放还是暂停的依据 */</span>

<span class="tGreen">/*③ onclick 事件 :元素的左键单击事件 */</span>
btnplay.onclick = () => { <span class="tGreen">/*这里做点什么*/</span> }; <span class="tGreen">/* 操作标识为 btnplay 的元素被左键单击 */</span>

<span class="tGreen">/*④ element.style.setProperty 方法 :改变CSS属性和变量值 */</span>
papa.style.setProperty('width', '800px'); <span class="tGreen">/* 设置 papa 元素的宽度 */</span>
btnplay.style.setProperty('--state','paused'); /* 改变 btnplay 元素CSS变量值 :paused 为动画暂停,running 为动画运行 */

<span class="tGreen">/**** 以下是 btnplay 可以运行的单击事件代码,依据 aud.pause 返回值做判断 ****/</span>
btnplay.onclick = () => <span class="tRed">{</span>
        if (aud.paused) { <span class="tGreen">/* 返回 true 时,亦即如果是暂停状态 */</span>
                aud.play(); <span class="tGreen">/* 那就播放 */</span>
                btnplay.style.setProperty('--state', 'running'); <span class="tGreen">/* 并让按钮转动 */</span>
        } else { <span class="tGreen">/* 否则,返回 false 时,亦即如果是播放状态*/</span>
                aud.pause(); <span class="tGreen">/* 那就暂停 */</span>
                btnplay.style.setProperty('--state', 'paused'); <span class="tGreen">/* 并让按钮停下 */</span>
        }
<span class="tRed">}</span>;
</pre>
<p>好,内容有点多,但是实在绕不过去,要能往下继续,就得把上述介绍的知识点消化掉。至此,我们可以整合CSS、html和JS代码,使之成为一个完整的组合,整合的内容包含上一节的JS部分:</p>
<pre>
&lt;style&gt;
#mplayer {
        position: absolute;
        text-align: center;
        color: white;
}
#mplayer p {
        margin: 0;
        padding: 0;
}
#mprog {
        width: 240px;
        accent-color: darkgreen;
        outline: none;
        cursor: pointer;
}
#btnplay {
        width: 80px;
        height: 80px;
        cursor: pointer;
        animation: rotating 6s infinite linear var(--state);
}
@keyframes rotating { to { transform: rotate(360deg); } }
&lt;/style&gt;

&lt;audio id="aud" src="https://music.163.com/song/media/outer/url?id=2113720220"&gt;&lt;/audio&gt;
&lt;div id="mplayer"&gt;
        &lt;p&gt;&lt;img id="btnplay" src="https://638183.freep.cn/638183/small/002_133507167677724892.png" title="播放/暂停" alt="" /&gt;&lt;/p&gt;
        &lt;p&gt;&lt;input id="mprog" type="range" min="0" step="1" max="100" value="0" title="调节进度" /&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;script&gt;

aud.addEventListener('timeupdate', () =&gt; {
        mprog.value = aud.currentTime / aud.duration * mprog.max;
});

btnplay.onclick = () =&gt; {
        if (aud.paused) {
                aud.play();
                btnplay.style.setProperty('--state', 'running');
        } else {
                aud.pause();
                btnplay.style.setProperty('--state', 'paused');
        }
};

&lt;/script&gt;
</pre>
<p>查看效果,可以到这里 <a href="http://mhh.52qingyin.cn/api/pcode/" target="_blank">pencil code</a>运行以上完整代码,或者将代码存为本地文件后运行。音乐没有设置为自动播放,运行后点击一下播放按钮。</p>

</div>

红影 发表于 2024-1-27 09:23

这样分解着讲解真好。{:4_199:}
上一节看懂了audio 标签和滑杆的关联。
这节看懂了用按钮代替audio 标签,以及按钮的设置方式,还有按钮和audio 标签及滑杆的互动等。

红影 发表于 2024-1-27 09:25

在js介绍中的第4条里的这句:papa.style.setProperty('width', '800px'); /* 设置 papa 元素的宽度 */
这个不知道做什么用{:4_203:}

红影 发表于 2024-1-27 09:28

现在的快进还是依赖audio 标签,这应该是下一节的内容了吧{:4_187:}

红影 发表于 2024-1-27 09:30

黑黑辛苦了,这样拆分开来,循序渐进的讲解真的太棒了。属于考试包过的精品课程{:4_178:}

马黑黑 发表于 2024-1-27 12:15

红影 发表于 2024-1-27 09:30
黑黑辛苦了,这样拆分开来,循序渐进的讲解真的太棒了。属于考试包过的精品课程

没有,我的目标不是让学的人考试

樵歌 发表于 2024-1-27 14:29

就俺一个吃瓜的好孤单{:4_169:}

红影 发表于 2024-1-27 15:24

马黑黑 发表于 2024-1-27 12:15
没有,我的目标不是让学的人考试

我只是打个比方啊,这里虽然不考试,也都能过呢{:4_173:}

马黑黑 发表于 2024-1-27 17:47

红影 发表于 2024-1-27 15:24
我只是打个比方啊,这里虽然不考试,也都能过呢

考试考试,把好端端的人考成了只会做试卷不会别的了

马黑黑 发表于 2024-1-27 17:48

樵歌 发表于 2024-1-27 14:29
就俺一个吃瓜的好孤单
有瓜相伴,何来寂寞

起个网名好难 发表于 2024-1-27 21:10

红影 发表于 2024-1-27 09:25
在js介绍中的第4条里的这句:papa.style.setProperty('width', '800px'); /* 设置 papa 元素的宽度 */
这 ...

就是个例子,说明 width 可以这样设置。

樵歌 发表于 2024-1-27 21:34

马黑黑 发表于 2024-1-27 17:48
有瓜相伴,何来寂寞

一个人吃没对手呀{:4_173:}

红影 发表于 2024-1-27 21:52

起个网名好难 发表于 2024-1-27 21:10
就是个例子,说明 width 可以这样设置。

这个是谁的宽度呢?papa的宽度不是已经设置了,是这里进行修改么?

起个网名好难 发表于 2024-1-27 22:00

本帖最后由 起个网名好难 于 2024-1-27 22:07 编辑

红影 发表于 2024-1-27 21:52
这个是谁的宽度呢?papa的宽度不是已经设置了,是这里进行修改么?
只是说可以这么做不是一定要做(或一定要这么做)那注释也说得很清楚了
/*④ element.style.setProperty 方法 :改变CSS属性和变量值 */是方法不是具体的行为。

马黑黑 发表于 2024-1-27 22:11

樵歌 发表于 2024-1-27 21:34
一个人吃没对手呀

对手就是瓜呀:不是你吃瓜,就是瓜吃你,看谁吃谁

红影 发表于 2024-1-27 22:28

马黑黑 发表于 2024-1-27 17:47
考试考试,把好端端的人考成了只会做试卷不会别的了

但是人们也没别的办法甄别人群啊,就像单位人事部的人不懂怎么找有用的人,就只能看人家学历了。

红影 发表于 2024-1-27 22:29

起个网名好难 发表于 2024-1-27 22:00
只是说可以这么做不是一定要做(或一定要这么做)那注释也说得很清楚了
是方法不是具体的行为。

嗯嗯,明白了,谢谢难难{:4_187:}{:4_190:}

马黑黑 发表于 2024-1-28 12:21

红影 发表于 2024-1-27 22:28
但是人们也没别的办法甄别人群啊,就像单位人事部的人不懂怎么找有用的人,就只能看人家学历了。

反正受科考影响深重,除了考试成绩,我们没能力看到特定人的能力了

红影 发表于 2024-1-28 16:09

马黑黑 发表于 2024-1-28 12:21
反正受科考影响深重,除了考试成绩,我们没能力看到特定人的能力了

就算真的有能力,最后的成果也是集体的,弄得人没兴趣钻研。当然,向上爬的能力除外。

马黑黑 发表于 2024-1-28 17:52

红影 发表于 2024-1-28 16:09
就算真的有能力,最后的成果也是集体的,弄得人没兴趣钻研。当然,向上爬的能力除外。

所以只好躺平,卷
页: [1] 2 3
查看完整版本: 保姆级range进度条音频播放器开发教程(二)