三十天写三十个网站的挑战来自JavaScript30,连续三十天每天用原生的 JavaScript 写一个小网站或是一个特定主题的练习。

上个学期用 JavaScript 写了一些好玩的网站,但开始用 React 或其他框架的时候,总觉得有点不踏实,应该要对原生的 JavaScript(或称 Vanilla JS)下更多功夫才行。而也刚好看到 JS30 这个挑战,就决定回过头来练习用纯粹的 JS 写网页,顺便学习别人的代码。

这三十天的每个网站都有提供视频教学,关于视频的学习笔记我都放在 Github 上,欢迎在上面跟我交流。

以下分享三个自己在这三十天的想法。

1、学习“不知道自己不知道”的东西

JS30 的挑战是每天都会实现一个网站的功能,而这些功能很多都是在开始挑战前,从来都没有想过可以用纯 JS 实现的。

这样的学习体验跟一般线上学习”为了实现某个功能才去查要如何实现“很不一样,因为你不知道自己不知道这种功能是可以简单的用 JS 完成。换句话说,这些功能我们一般是不会主动去学的,而这些功能又可以分为两种:

没有尝试过的领域

没有尝试过的领域如:电脑的 Webcam 摄像头、网页原生的语音识别、 网页原生的地图定位等等。

这些领域的网页功能在没有做相关的项目时,通常比较难碰到。但透过别人指定给你功能的挑战,才会去研究发现这些功能原来都可以用原生的 JS 实现。

举例来说,想到地理定位也许很多人跟我一样,直觉就想到也许可以用 Google Map 的Api,但其实 JavaScript 可以简单使用一行代码:

navigator.geolocation.watchPosition();

就能取得地理定位,再搭配简单的判断就可以显示使用者移动的速度跟方位等。甚至还可以透过Xcode 内建的 Simulator,模拟使用者的各种运动方式,如:跑步、骑单车等,以方便Debug。

Nice-to-have 的功能

Nice-to-have 的功能则是一些非必要的,但能够发现可以额外附加的功能。虽然这些功能大部分炫酷成分居多,但用的好也许也能优化用户体验。

这些 Nice-to-have 的功能如搜索框的 Autocomplete、实现定制化的视频播放器、帮 Webcam 影像做色彩处理、在网页里埋彩蛋等。

而其中有一个自己还很喜欢的例子是实现 Stripe 官网上那个别出心裁的导航条。当然一般的导航条可以很简单用像网页书签资料夹的方式实现(鼠标移到资料夹上就把里面的网页书签吐出来),但用 Stripe 这样让导航条内容像是随着鼠标移动的方式显然是酷多了。

2、多看别人的代码

网页的功能通常都有不只一种实现的方式,而同一种实现的方式也可以用不同写法的代码完成。

举例来说:假设我们要在一个自制的视频播放器内提供一些参数让用户调整视频设定,例如在这个 播放器中 可以让使用者调整视频音量跟播放速度这两个参数。

要运用这两个参数去调整视频,直觉上当然可以直接实现两个 function 去分别处理 input 的变化。但这样其实让代码有部分重复又减少 function 复用的能力。

此时,如果我们在 input 的HTML 标签上把 name 属性好好对应到视频的 property 时,一个 function 就可以处理所有 input 的变化了。我们的HTML 写成:

<input type="range" name="volume" class="player__slider"> 
<input type="range" name="playbackRate" class="player__slider">

而 JS 监听每个input 的事件就只要一个function 处理即可:

function handleRangeUpdate() { 
    video[this.name] = this.value; 
}

在举另外一个简单的例子,同样的“在判断语句后执行一个 function 的逻辑” 可以用简单的 if statement 写,但也可以用更简洁但可能会降低一些可读性的方式,如:

isTrue && doSomething();

在实现三十个网站的过程中,可以发现有很多功能的写法跟自己原本想的不一样。虽然都可以达到目的,但多看别人的代码一方面可以比较不同写法在效率或是可读性上的差别,另一方面也可以学习别人的逻辑,方便训练自己在 trace 别人代码时能够更快适应。

3、找到自己舒服和不舒服的学习方式

先找自己舒服的学习方式

不管学习什么,找到属于自己的学习方式都是很重要的事情,而且自己的同一套学习方式也不一定适合每一个要学习的东西。所以在刚接触一个课程时,我觉得先从自己容易上手的内容开始是比较适合的。

举例来说,我刚开始在进行挑战的前几天,完成每天学习的方式通常是用 2 倍速看完视频,然后打开 VS code,把网站的功能一个个实现出来。如果有不熟的地方再回去看视频或 Google,最后把学到的东西纪录下来。

对我来说,这样的步骤就是舒服的学习方式,但很显然这样学花很多的时间,且遇到不熟再回去看视频的学习效果没那么好(毕竟平常写代码时也不会用这样的方式开发)。

强迫自己不舒服一点学习

所以找到自己舒服的学习方式后,下一步就是去找自己没那么舒服,但可以学得更快或更好的方法。而对我来说,用 2 倍速看完视频并不是那么不舒服,也跟自己平常喜欢边听课边记笔记的习惯不太一样。

所以我认为对自己比较好的方式反而是用1.5 倍速看视频,然后边看边把学习的笔记写完。看完视频就可以把网页关掉。接下来完全依靠自己的脑袋跟笔记,把网页写完。

因为 2 倍速实在手速跟不上(太不舒服有反效果),所以退而求其次让视频放慢一点,但强迫自己“有点不舒服地”边看视频边把笔记做完,这样不仅可以强迫自己完全专心看视频,也比较符合自己平常要写代码时,遇到学过但不熟东西时先查自己的笔记再上网查的习惯。

4、小结

以上就是关于这三十天挑战的一些想法,我觉得这个挑战下来最大的成长是:能够有自信可以用纯粹的 JavaScript 就快速实现出各种在别的网站上看到的各种功能。

但值得注意的是,在课程中其实对于底层 JS 的涉及不多(Closure、Prototype等),大多是对于写网页的功能还有 DOM、Window 的运用。

5、无用的题外话

在课程中了学到定制视频播放器的概念,最近在看其他课程时也刚好想到可以用来操作别的网页中的视频。例如大部分线上课程的视频播放速度上线通常都设在2 倍,但有时候课程的速度实在是太慢的时候,可以通过 dev tool 去调整视频速度。

叫出Chrome dev tool 中console 的方法为:

对网页按右键> 检查> 点选console

接下来在console 中贴上这段代码搭配你想要的速度就可以突破限制了!

document.querySelector('video').playbackRate = 数字倍数;

例如:三倍速

document.querySelector('video').playbackRate = 3;

但如果网页中的视频不只一个,可能就要先知道视频的 class name 才能做选取啰,祝学习愉快!