Repository: SUNNERCMS/30daysJavascript Branch: master Commit: 445ddc452c5c Files: 112 Total size: 344.0 KB Directory structure: gitextract_hmq1lhif/ ├── .gitattributes ├── 01 - JavaScript Drum Kit/ │ ├── README.md │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 02 - JS and CSS Clock/ │ ├── README.md │ ├── click.css │ ├── clock.js │ ├── clock1.js │ ├── clock2.js │ ├── index.html │ └── style.css ├── 03 - CSS Variables/ │ ├── README.md │ ├── index.html │ ├── style.css │ └── variables.js ├── 04 - Array Cardio Day 1/ │ ├── README.md │ ├── index-FINISHED.html │ └── index-START.html ├── 05 - Flex Panel Gallery/ │ ├── README.md │ ├── animation.html │ ├── index-FINISHED.html │ └── index-START.html ├── 06 - Fetch、filter、正则表达式实现快速古诗匹配/ │ ├── .vscode/ │ │ └── launch.json │ ├── README.md │ └── index.html ├── 07 - Array Cardio Day 2/ │ ├── README.md │ └── index.html ├── 08 - HTML5 Canvas 实现彩虹画笔绘画板/ │ ├── README.md │ └── index.html ├── 09 - Console 调试各种姿势指南/ │ ├── README.md │ └── index-FINISHED.html ├── 10 - JS 实现 Checkbox 中按住 Shift 的多选功能/ │ ├── README.md │ ├── index-FINISHED.html │ ├── index-START.html │ └── sunzhaoxiang.html ├── 11 - 自定义视频播放器/ │ ├── README.md │ ├── index.html │ └── style.css ├── 12 - 键盘输入序列的验证指南/ │ ├── README.md │ └── index.html ├── 13 - 图片随屏幕滚动而滑入滑出的效果/ │ ├── README.md │ ├── index.html │ ├── index.js │ └── style.css ├── 14 - JavaScript 引用和值拷贝/ │ ├── README.md │ ├── index-FINISHED.html │ └── index-START.html ├── 15 - LocalStorage/ │ ├── README.md │ ├── demo.html │ ├── index.html │ └── style.css ├── 16 - 移动鼠标让字体呈现彩虹效果/ │ ├── README.md │ └── index.html ├── 17 - 数组排序/ │ ├── README.md │ └── index.html ├── 18 - Day18 - Reduce、Map混合使用计算时分秒/ │ ├── README.md │ └── index.html ├── 19 - Webcam Fun/ │ ├── README.md │ ├── index.html │ ├── package.json │ ├── scripts.js │ └── style.css ├── 20 - Speech Detection/ │ ├── README.md │ ├── index-FINISHED.html │ ├── index-START.html │ └── package.json ├── 21 - Geolocation/ │ ├── README.md │ ├── index.html │ └── package.json ├── 22 - Follow Along Link Highlighter/ │ ├── README.md │ ├── index.html │ └── style.css ├── 23 - Speech Synthesis/ │ ├── 23 - Speech Synthesis/ │ │ ├── README.md │ │ ├── index.html │ │ └── style.css │ └── speak-easy-synthesis/ │ ├── index.html │ ├── manifest.webapp │ ├── script.js │ └── style.css ├── 24 - Sticky Nav/ │ ├── README.md │ ├── index.html │ └── style.css ├── 25 - Event Capture, Propagation, Bubbling and Once/ │ ├── README.md │ └── index.html ├── 26 - Stripe Follow Along Nav/ │ ├── README.md │ └── index.html ├── 27 - Click and Drag/ │ ├── README.md │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 28 - Video Speed Controller/ │ ├── .vscode/ │ │ └── settings.json │ ├── README.md │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 29 - Countdown Timer/ │ ├── .vscode/ │ │ └── settings.json │ ├── README.md │ ├── index.html │ ├── scripts-FINISHED.js │ ├── scripts-START.js │ └── style.css ├── 30 - Whack A Mole/ │ ├── README.md │ ├── index-FINISHED.html │ ├── index-START.html │ └── style.css ├── 31 - Canvas CountClock/ │ ├── Countdown.html │ ├── Countdown.js │ ├── digit.js │ └── readme.md ├── LICENSE └── README.md ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ *.css linguist-language=javascript *.html linguist-language=javascript *.java linguist-language=javascript ================================================ FILE: 01 - JavaScript Drum Kit/README.md ================================================ # Day1 JavaScript Drum Kit 中文指南 ## 简介 第一天的练习是用JS制作一个爵士鼓的页面,通过敲击键盘上不同的字母,会发出不同的声音,并且页面上会伴随着敲击的动画。 效果如下:  想要实现以上效果,大致思路和解决方案如下: - 检测到键盘上什么键被按下--监听`keydown`事件 - 在按键被按下的时候,播放音效--`audio.play()` - 在按键被按下的同时,播放动画--`Element.classList.add('className')` - 在动画结束后,移除动画,不然之后再点击不会有任何效果--`Element.classList.remove('className')` ## 基础语法 ### 一些 ES6 语法 1. ``const`` :声明一个只读的常量,标识符的值只能赋值一次。 2. \`字符串 \${ 变量、属性名 } \`:模板字面量(Template literals)中用于表示模板字符串的标识。特点是字符串首尾用反引号(\`),内部的模板部分用 ${ } 括起来表示,具体请看[MDN文档]( https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/template_strings)。简单例子如下: ````javascript var a = 1; var b = 2; //不用模板的写法 console.log("三是" + (a + b) + "不是" + (2 * a + b)); //"三是3不是4" //使用模板字符串的写法 console.log(`三是${a + b}不是${2 * a + b}`); //"三是3不是4" ```` ### ``forEach`` 与箭头函数 使用 ``document.querySelector`` 获取一组符合 CSS 选择符的元素快照,类型为 NodeList(此对象是对于文档的实时运行的动态查询),对其进行遍历时可采用 ``forEach`` 方法。 ```javascript // Code from http://es6-features.org/#StatementBodies // ES6 nums.forEach(v => { if (v % 5 === 0) fives.push(v); }) // ES5 nums.forEach(function (v) { if (v % 5 === 0) five.push(v); }) ``` ## 页面基础布局 ```html
```
## CSS源码
```css
:root{
--spacing:10px;
--blur:10px;
--base:#ffc600;
--fontsize:10px;
}
html,body{
text-align:center;
background: #193549;
margin:0;
padding:0;
min-height: 100vh;
font-size:calc(3*var(--fontsize));
font-family:'helvetica neue', sans-serif; /*Helvetica是一种被广泛使用的的西文字体(铅字体),用于印刷行业,Helvetica是苹果电脑的默认字体,微软常用的Arial字体也来自于它*/
font-weight:900;/*设置字体粗细:100---900,400=normal,700=bolder*/
color:white;
}
.h1{
color:var(--base);
}
.controls{
font-weight:100;
margin-bottom:calc(5*var(--fontsize));
}
.controls .wrap{
display: inline-block;
margin:5px auto;
}
.controls .wrap label{
margin-left:20px;
}
.controls .wrap input{
position:relative;
top:3px;
width:calc(10*var(--fontsize));
}
.controls .wrap #base{
top:-3px;
}
img{
width:calc(60*var(--fontsize));
height:calc(40*var(--fontsize));
padding:var(--spacing);
filter:blur(var(--blur));
background-color:var(--base);/*背景颜色填充内容、内边距、边框,作为打底色*/
}
```
## JS源码
```js
function spacingchange(){
var spacing=document.querySelector("#spacing");
document.body.style.setProperty('--spacing', spacing.value+'px');
// var img=document.querySelector("#img");
// img.style.padding=spacing.value+'px';一个需要改变的元素可以将其取出,改变它的对应项,但有100个需要改变的元素时,改变根变量值最有效。
}
function blurchange(){
var blur=document.querySelector("#blur");
document.body.style.setProperty("--blur",blur.value+'px');
}
function basechange(){
var base=document.querySelector("#base");
document.body.style.setProperty("--base",base.value);
}
```
## 过程指南
### CSS 部分准备
1. 声明全局(`:root`)的 CSS 变量
2. 将变量应用到页面中对应元素 `
================================================
FILE: 03 - CSS Variables/style.css
================================================
/*
* @Author: Administrator
* @Date: 2018-11-30 20:09:15
* @Last Modified by: Administrator
* @Last Modified time: 2018-12-03 21:57:37
*/
:root{
--spacing:10px;
--blur:10px;
--base:#ffc600;
--fontsize:10px;
}
html,body{
text-align:center;
background: #193549;
margin:0;
padding:0;
min-height: 100vh;
font-size:calc(3*var(--fontsize));
font-family:'helvetica neue', sans-serif; /*Helvetica是一种被广泛使用的的西文字体(铅字体),用于印刷行业,Helvetica是苹果电脑的默认字体,微软常用的Arial字体也来自于它*/
font-weight:900;/*设置字体粗细:100---900,400=normal,700=bolder*/
color:white;
}
.h1{
color:var(--base);
}
.controls{
font-weight:100;
margin-bottom:calc(5*var(--fontsize));
}
.controls .wrap{
display: inline-block;
margin:5px auto;
}
.controls .wrap label{
margin-left:20px;
}
.controls .wrap input{
position:relative;
top:3px;
width:calc(10*var(--fontsize));
}
.controls .wrap #base{
top:-3px;
}
img{
width:calc(60*var(--fontsize));
height:calc(40*var(--fontsize));
padding:var(--spacing);
filter:blur(var(--blur));
background-color:var(--base);/*背景颜色填充内容、内边距、边框,作为打底色*/
}
================================================
FILE: 03 - CSS Variables/variables.js
================================================
/*
* @Author: Administrator
* @Date: 2018-11-30 20:09:45
* @Last Modified by: Administrator
* @Last Modified time: 2018-12-03 22:17:32
*/
function spacingchange(){
var spacing=document.querySelector("#spacing");
document.body.style.setProperty('--spacing', spacing.value+'px');
// var img=document.querySelector("#img");
// img.style.padding=spacing.value+'px';一个需要改变的元素可以将其取出,改变它的对应项,但有100个需要改变的元素时,改变根变量值最有效。
}
function blurchange(){
var blur=document.querySelector("#blur");
document.body.style.setProperty("--blur",blur.value+'px');
// document.documentElement.style.setProperty("--blur",blur.value+'px');
// 在 JavaScript 中 document.documentElement 即代表文档根元素。所以要改变全局的 CSS 变量,可以这样写
}
function basechange(){
var base=document.querySelector("#base");
document.body.style.setProperty("--base",base.value);
}
================================================
FILE: 04 - Array Cardio Day 1/README.md
================================================
# Day04 - Array Cardio 指南一
## 实现效果
这一部分主要是熟悉 Array 的几个基本方法,其中有两个(filter、map)是 ES6 定义的迭代方法,这些迭代方法都有一个特点,就是对数组的每一项都运行给定函数,根据使用的迭代方法的不同,有不同的返回结果。
文档给出了一个初始操作的 `inventor` 数组,基于这个数组可以练习一下`Array`的各个方法,请用`Google Chrome`浏览器打开 `HTML` 后在`Console`面板中查看输出结果。
## 炫酷的调试技巧
在 Console 中我们常用到的可能是 `console.log()` ,但它还有一个很炫的输出,按照表格来输出,效果如下:
```js
console.table(thing)
```

## 原始数据
本节中我们将围绕如下数据进行相关操作以便快速掌握数组的相关方法的使用。
```js
const inventors = [{
first: 'Albert',
last: 'Einstein',
year: 1879,
passed: 1955
},
{
first: 'Isaac',
last: 'Newton',
year: 1643,
passed: 1727
},
{
first: 'Galileo',
last: 'Galilei',
year: 1564,
passed: 1642
},
{
first: 'Marie',
last: 'Curie',
year: 1867,
passed: 1934
},
{
first: 'Johannes',
last: 'Kepler',
year: 1571,
passed: 1630
},
{
first: 'Nicolaus',
last: 'Copernicus',
year: 1473,
passed: 1543
},
{
first: 'Max',
last: 'Planck',
year: 1858,
passed: 1947
},
{
first: 'Katherine',
last: 'Blodgett',
year: 1898,
passed: 1979
},
{
first: 'Ada',
last: 'Lovelace',
year: 1815,
passed: 1852
},
{
first: 'Sarah E.',
last: 'Goode',
year: 1855,
passed: 1905
},
{
first: 'Lise',
last: 'Meitner',
year: 1878,
passed: 1968
},
{
first: 'Hanna',
last: 'Hammarström',
year: 1829,
passed: 1909
}
];
const people = ['Beck, Glenn', 'Becker, Carl', 'Beckett, Samuel', 'Beddoes, Mick', 'Beecher, Henry',
'Beethoven, Ludwig', 'Begin, Menachem', 'Belloc, Hilaire', 'Bellow, Saul', 'Benchley, Robert',
'Benenson, Peter', 'Ben-Gurion, David', 'Benjamin, Walter', 'Benn, Tony', 'Bennington, Chester',
'Benson, Leana', 'Bent, Silas', 'Bentsen, Lloyd', 'Berger, Ric', 'Bergman, Ingmar', 'Berio, Luciano',
'Berle, Milton', 'Berlin, Irving', 'Berne, Eric', 'Bernhard, Sandra', 'Berra, Yogi', 'Berry, Halle',
'Berry, Wendell', 'Bethea, Erin', 'Bevan, Aneurin', 'Bevel, Ken', 'Biden, Joseph', 'Bierce, Ambrose',
'Biko, Steve', 'Billings, Josh', 'Biondo, Frank', 'Birrell, Augustine', 'Black Elk', 'Blair, Robert',
'Blair, Tony', 'Blake, William'
];
const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car',
'truck', 'pogostick'
];
```
## 筛选 16 世纪出生的发明家
[filter](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)
过滤操作,有点像 SQL 里面的 select 语句。筛出运行结果是 true 的组成数组返回。
````js
const __fifteen = inventors.filter(function(inventor) {
if (inventor.year >= 1500 && inventor.year < 1600 ) {
return true;
} else {
return false;
}
});
console.table(__fifteen);
````
前面几篇已经提到过箭头函数,这里可以简化一下,用箭头函数来写,而且由于 if 语句的存在并不是必要的,可以写成下面这样:
````js
const fifteen = inventors.filter(inventor =>(inventor.year >= 1500 && inventor.year < 1600));
console.table(fifteen);
````
控制台效果图:

## 展示他们的姓和名
[map](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map)
map 形象的理解就是,把数组中的每个元素进行处理后,返回一个新的数组。
例子如下:
````js
// Array.prototype.map()
// 2. 展示他们的姓和名
const fullNames = inventors.map(inventor => `${inventor.first} ${inventor.last}`);
console.log(fullNames);
````
控制台效果图:

## 把他们按照年龄从大到小进行排序
[sort](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
默认情况下,`Array.prototype.sort()` 会将数组以字符串的形式进行升序排列(10 会排在 2 之前),但 sort 也可以接受一个函数作为参数。所以需要对数字大小排序时需要自己设定一个比较函数,例子如下:
````js
// Array.prototype.sort()
// 3. 把他们按照年龄从大到小进行排序
const ordered = inventors.sort((a, b) => {
if(a.year > b.year) {
return 1;
} else {
return -1;
}
});
console.table(ordered);
````
上面的代码可以简写成:
```js
const ordered = inventors.sort((a, b) => a.year > b.year ? 1 : -1);
console.table(ordered);
```
控制台效果图:

## 计算所有的发明家加起来一共活了多少岁
[reduce](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)
```js
// Array.prototype.reduce()
// 4. 计算所有的发明家加起来一共活了多少岁
const totalYears = inventors.reduce((total, inventor) => {
return total + (inventor.passed - inventor.year);
}, 0);
console.log(totalYears);
```
控制台效果图:

## 按照他们活了多久来进行排序
```js
// 5. 按照他们活了多久来进行排序
const oldest = inventors.sort((a, b) => {
const lastInventor = a.passed - a.year;
const nextInventor = b.passed - b.year;
return lastInventor > nextInventor ? -1 : 1;
});
console.table(oldest);
```
控制台效果图:

## `map、filter`结合使用筛选出网页中含有`CSS`标题的数据名称
```js
const category = document.querySelectorAll('.subject-list h2 a');
const links = Array.from(category);
const CSS_BOOK = links
.map(link => link.textContent)
.filter(streetName => streetName.includes('CSS'));
```
由 `querySelectorAll()` 获取到的是一个 `NodeList` ,它并非是 Array 类型的数据,所以并不具有 map 和 filter 这样的方法,所以如果要进行筛选操作则需要把它转化成 Array 类型,使用下面示例之中的 `Array.from()` 来转化。
Google Chrome浏览球操作如下:
- 打开`https://book.douban.com/tag/web`网页。
- 在控制台按如下图操作即可

## 按照姓氏来对发明家进行排序
```js
const alpha = people.sort((lastOne, nextOne) => {
const [aLast, aFirst] = lastOne.split(', ');
const [bLast, bFirst] = nextOne.split(', ');
return aLast > bLast ? 1 : -1;
});
console.log(alpha);
```
控制台效果图:

## 统计给出数组中各个物品的数量
[reduce](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce)
这是一个归并数组的方法,它接受一个函数作为参数(这个函数可以理解成累加器),它会遍历数组的所有项,然后构建一个最终的返回值,这个值就是这个累加器的第一个参数。第二个参数中的`0`是`previousValue`的初始值,例子如下:
````js
[0,1,2,3,4].reduce((previousValue, currentValue, index, array) => {
return previousValue + currentValue;
},0);
````
而此处我们需要统计一个给定数组中各个项的值,恰好可以用到这个方法,在累加器之中,将统计信息存入一个新的对象,最后返回统计值。
```js
const data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car',
'truck', 'pogostick'
];
const transportation = data.reduce( (obj, item) => {
if (!obj[item]) {
obj[item] = 0;
}
obj[item]++;
return obj;
}, {});
console.log(transportation);
```
```JS
var data = ['car', 'car', 'truck', 'truck', 'bike', 'walk', 'car', 'van', 'bike', 'walk', 'car', 'van', 'car','truck', 'pogostick'
];
data.reduce((acc,cur)=>{
cur in acc ? acc[cur]++ : acc[cur]=1;
return acc;
},{});
```

================================================
FILE: 04 - Array Cardio Day 1/index-FINISHED.html
================================================
打开Google Chrome浏览器,查看JavaScript 控制台。 💁
================================================ FILE: 04 - Array Cardio Day 1/index-START.html ================================================打开Google Chrome浏览器,查看JavaScript 控制台。 💁
================================================ FILE: 05 - Flex Panel Gallery/README.md ================================================ # Day05 - Flex 实现可伸缩的图片墙 中文指南 ## 实现效果 点击任意一张图片,图片展开,同时从图片上下两方分别移入文字。点击已经展开的图片后,图片被压缩,同时该图片上下两端的文字被挤走。  ## HTML源码 ```htmlHey
Let's
Dance
Give
Take
Receive
Experience
It
Today
Give
All
You can
Life
In
Motion
` 中的文字垂直、水平居中(单独看每个 panel,其中的文字也可以用 flex 的思路来使其三等分后居中) 1. 设置为 `display:flex` 2. 设置 `flex` 值 2. 设置其子元素的布局方式:垂直水平居中(沿主轴、侧轴居中) 4. 设定点击图片后文字移动的样式 5. 设定点击图片展开后的图片的 `flex` 值 **重要:不了解CSS和Flex的童鞋必看。** - [CSS参考手册](http://www.css88.com/book/css/properties/flex/flex.htm) - [选择器(Selectors)](https://developer.mozilla.org/zh-CN/docs/Web/Guide/CSS/Getting_started/Selectors) - [CSS选择器笔记](http://www.ruanyifeng.com/blog/2009/03/css_selectors.html) - [flex布局完全入门教程](http://bbs.kongyixueyuan.com/topic/10/flex布局完全入门教程) ## JS源码 ```js ``` 1. 获取所有类名为 `panel` 的元素 2. 为其添加 `click` 事件监听,编写触发事件调用的函数(给触发的 DOM 元素添加/去掉样式,实现拉伸/压缩的效果) 3. 为其添加 `transitionend` 事件监听,编写调用的函数(添加/去掉样式,实现文字的飞入/飞出效果) ================================================ FILE: 05 - Flex Panel Gallery/animation.html ================================================
HEY
LET'S
DANCE
GIVE
TAKE
RECEIVE
WXPERE
IT
TODAY
GIVE
ALL
YOUCAN
UP
IN
FIGHT
Hey
Let's
Dance
Give
Take
Receive
Experience
It
Today
Give
All
You can
Life
In
Motion
Hey
Let's
Dance
Give
Take
Receive
Experience
It
Today
Give
All
You can
Life
In
Motion
Psst: have a look at the JavaScript Console 💁
================================================ FILE: 08 - HTML5 Canvas 实现彩虹画笔绘画板/README.md ================================================ # Day08 - HTML5 Canvas 实现彩虹画笔绘画板指南 ## 项目效果  > 用 HTML5 中的 Canvas 的路径绘制实现一个绘画板,可供鼠标画画,颜色呈彩虹色渐变,画笔大小同样呈渐变效果。这部分不涉及 CSS 内容,全部由 JS 来实现。 ## 涉及特性 Canvas: - 模板骨架 - 基本属性 - `getContext()` - `strokeStyle` - `lineCap` - `lineJoin` - 路径绘制 - `beginPath()` - `lineTo()` - `moveTo()` 鼠标事件处理: - `mousemove` - `mousedown` - `mouseup` - `mouseout` ## 过程指南 1. 获取 HTML 中的 `