diff --git a/23 - Speech Synthesis/README.md b/23 - Speech Synthesis/README.md
new file mode 100644
index 0000000..c0140e4
--- /dev/null
+++ b/23 - Speech Synthesis/README.md
@@ -0,0 +1,93 @@
+# 23 Speech Synthesis 中文指南
+
+> 本篇作者:©[大史快跑Dashrun](https://github.com/dashrun)——Chinasoft Frontend Developer
+
+> 简介:[JavaScript30](https://javascript30.com) 是 [Wes Bos](https://github.com/wesbos) 推出的一个 30 天挑战。项目免费提供了 30 个视频教程、30 个挑战的起始文档和 30 个挑战解决方案源代码。目的是帮助人们用纯 JavaScript 来写东西,不借助框架和库,也不使用编译器和引用。现在你看到的是这系列指南的第 23 篇。完整指南在 [GitHub](https://github.com/soyaine/JavaScript30),喜欢请 Star 哦♪(^∇^*)
+
+> 创建时间:2017-09-20
+最后更新:2017-09-22
+
+## 挑战任务
+初始文档`index-start.html`提供了一个阅读器,你需要完成如下编程任务:
+1.使用相应的WebAPI接口获得浏览器支持的语言种类列表,并填充至页面的下拉菜单中,选择中文;
+2.在文本域中输入对应语言的文字,点击`speak`按钮后浏览器会阅读输入的文字;
+3.在浏览器阅读时,点击`stop`按钮,浏览器会停止阅读;
+4.拖动`rate`和`pitch`滑块可改变阅读速度和音高。
+
+## 实现效果
+
+
+## 相关知识
+1.`SpeechSynthesisUtterance`接口
+ 本接口用于设置阅读器阅读的配置参数,包括语言,阅读速度,语调等,实例化`SpeechSynthesisUtterance`后,可以通过为其属性赋值来完成参数配置,详细信息请直接参考MDN中的[SpeechSynthesisUtterance接口说明](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesisUtterance)。
+2.`SpeechSynthesis`接口
+ 本接口用于控制阅读器行为,包括获取浏览器支持的朗读语言,文本朗读,暂停,停止等,接口属性中定义有paused,speaking等只读属性来表明当前的状态,详细使用方式请参考MDN中的[SpeechSynthesis接口说明](https://developer.mozilla.org/en-US/docs/Web/API/SpeechSynthesis)。
+
+## 编程思路
+ 本次编程任务使用相应接口的最基本功能即可实现,编程中根据挑战任务中的说明逐步实现即可。
+
+## 过程指南
+1.取得`speechSynthesis`对象,并取得浏览器支持的朗读语言,将所有支持的选项动态添加至下拉列表
+```js
+const synth = window.speechSynthesis;
+
+//将获取支持语言并添加至下拉列表的代码段封装在一个函数中
+function getSupportVoice() {
+ voices = synth.getVoices();//获取支持的语言
+ for(i = 0; i < voices.length ; i++) {
+ var option = document.createElement('option');
+ option.textContent = voices[i].name + ' (' + voices[i].lang + ')';
+
+ if(voices[i].default) {
+ option.textContent += ' -- DEFAULT';
+ }
+
+ option.setAttribute('data-lang', voices[i].lang);
+ option.setAttribute('data-name', voices[i].name);
+ voicesDropdown.appendChild(option);
+ }
+}
+
+//经测试直接执行getSupportVoice()时无法获得预期效果,须由事件触发该函数。
+synth.addEventListener('voiceschanged', getSupportVoice);
+```
+2.点击`speak`按钮后朗读(为方便说明,以下代码段与所提供的完成代码顺序不完全一致)
+```js
+//实例化配置对象
+const msg = new SpeechSynthesisUtterance();
+
+//定义一段默认朗读内容
+msg.text = '你能说中文吗';
+
+//点击speak按钮时阅读文字
+function speak() {
+ console.log(voicesDropdown.value);
+ synth.speak(msg);
+}
+
+//将阅读函数绑定至`speak`按钮的点击事件上
+speakButton.addEventListener('click', speak);
+```
+3.点击`stop`按钮停止朗读
+```js
+//停止朗读
+function stopSpeak(){
+ synth.cancel();
+}
+//将停止朗读函数绑定至`stop`按钮的点击事件上
+stopButton.addEventListener('click', stopSpeak);
+```
+4.参数配置可更改
+```js
+//index-start.html中提供的选择器将返回rate值,pitch值以及阅读内容对应的DOM元素
+ const options = document.querySelectorAll('[type="range"], [name="text"]');
+//将阅读参数赋值至msg的同名实例属性
+function paramChange(){
+ msg[this.name] = this.value;
+}
+options.forEach(opt => opt.addEventListener('change', paramChange));
+```
+
+
+
+
diff --git a/23 - Speech Synthesis/effects.png b/23 - Speech Synthesis/effects.png
new file mode 100644
index 0000000..d6f342a
Binary files /dev/null and b/23 - Speech Synthesis/effects.png differ
diff --git a/23 - Speech Synthesis/index-finished-Dashrun.html b/23 - Speech Synthesis/index-finished-Dashrun.html
new file mode 100644
index 0000000..56affc8
--- /dev/null
+++ b/23 - Speech Synthesis/index-finished-Dashrun.html
@@ -0,0 +1,82 @@
+
+
+
+
+ Speech Synthesis
+
+
+
+
+
+
+
听说 5000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/23 - Speech Synthesis/index-start.html b/23 - Speech Synthesis/index-start.html
new file mode 100644
index 0000000..b909453
--- /dev/null
+++ b/23 - Speech Synthesis/index-start.html
@@ -0,0 +1,40 @@
+
+
+
+
+ Speech Synthesis
+
+
+
+
+
+
+
The Voiceinator 5000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/23 - Speech Synthesis/style.css b/23 - Speech Synthesis/style.css
new file mode 100644
index 0000000..86bd48e
--- /dev/null
+++ b/23 - Speech Synthesis/style.css
@@ -0,0 +1,98 @@
+html {
+ font-size: 10px;
+ box-sizing: border-box;
+}
+
+*, *:before, *:after {
+ box-sizing: inherit;
+}
+
+body {
+ margin: 0;
+ padding: 0;
+ font-family: sans-serif;
+ background-color:#3BC1AC;
+ display:flex;
+ min-height: 100vh;
+ align-items: center;
+
+ background-image:
+ radial-gradient(circle at 100% 150%, #3BC1AC 24%, #42D2BB 25%, #42D2BB 28%, #3BC1AC 29%, #3BC1AC 36%, #42D2BB 36%, #42D2BB 40%, transparent 40%, transparent),
+ radial-gradient(circle at 0 150%, #3BC1AC 24%, #42D2BB 25%, #42D2BB 28%, #3BC1AC 29%, #3BC1AC 36%, #42D2BB 36%, #42D2BB 40%, transparent 40%, transparent),
+ radial-gradient(circle at 50% 100%, #42D2BB 10%, #3BC1AC 11%, #3BC1AC 23%, #42D2BB 24%, #42D2BB 30%, #3BC1AC 31%, #3BC1AC 43%, #42D2BB 44%, #42D2BB 50%, #3BC1AC 51%, #3BC1AC 63%, #42D2BB 64%, #42D2BB 71%, transparent 71%, transparent),
+ radial-gradient(circle at 100% 50%, #42D2BB 5%, #3BC1AC 6%, #3BC1AC 15%, #42D2BB 16%, #42D2BB 20%, #3BC1AC 21%, #3BC1AC 30%, #42D2BB 31%, #42D2BB 35%, #3BC1AC 36%, #3BC1AC 45%, #42D2BB 46%, #42D2BB 49%, transparent 50%, transparent),
+ radial-gradient(circle at 0 50%, #42D2BB 5%, #3BC1AC 6%, #3BC1AC 15%, #42D2BB 16%, #42D2BB 20%, #3BC1AC 21%, #3BC1AC 30%, #42D2BB 31%, #42D2BB 35%, #3BC1AC 36%, #3BC1AC 45%, #42D2BB 46%, #42D2BB 49%, transparent 50%, transparent);
+ background-size:100px 50px;
+}
+
+
+.voiceinator {
+ padding:2rem;
+ width:50rem;
+ margin:0 auto;
+ border-radius:1rem;
+ position: relative;
+ background:white;
+ overflow: hidden;
+ z-index: 1;
+ box-shadow:0 0 5px 5px rgba(0,0,0,0.1);
+}
+
+h1 {
+ width:calc(100% + 4rem);
+ margin: -2rem 0 2rem -2rem;
+ padding:.5rem;
+ background: #ffc600;
+ border-bottom: 5px solid #F3C010;
+ text-align: center;
+ font-size: 5rem;
+ font-weight: 100;
+ font-family: 'Pacifico', cursive;
+ text-shadow:3px 3px 0 #F3C010;
+
+}
+
+.voiceinator input,
+.voiceinator button,
+.voiceinator select,
+.voiceinator textarea {
+ width: 100%;
+ display: block;
+ margin:10px 0;
+ padding:10px;
+ border:0;
+ font-size: 2rem;
+ background:#353535;
+ color:white;
+ outline:0;
+}
+
+textarea {
+ height: 20rem;
+}
+
+input[type="select"] {
+
+}
+
+.voiceinator button {
+ background:#ffc600;
+ border:0;
+ width: 49%;
+ float:left;
+ font-family: 'Pacifico', cursive;
+ margin-bottom: 0;
+ font-size: 2rem;
+ border-bottom: 5px solid #F3C010;
+ cursor:pointer;
+ position: relative;
+}
+
+.voiceinator button:active {
+ top:2px;
+}
+
+.voiceinator button:nth-of-type(1) {
+ margin-right: 2%;
+}
+
diff --git a/README.md b/README.md
index 0d6d9a6..73a4b78 100644
--- a/README.md
+++ b/README.md
@@ -61,7 +61,7 @@ No | Guide | Demo
19 | [Webcam Fun 指南](https://github.com/soyaine/JavaScript30/blob/master/19%20-%20Webcam%20Fun/README.md) | [网络摄像头及图片处理在线效果](https://github.com/soyaine/JavaScript30/blob/master/19%20-%20Webcam%20Fun/index-finished-Dashrun.html)
20 | [Speech Detection指南](https://github.com/soyaine/JavaScript30/blob/master/20%20-%20Speech%20Detection/README.md) | [Speech Detection效果](https://github.com/soyaine/JavaScript30/blob/master/20%20-%20Speech%20Detection/index-finished-Dashrun.html)
21 | [Geolocation指南](https://github.com/soyaine/JavaScript30/blob/master/21%20-%20Geolocation/README.md) | [Geolocation效果](https://github.com/soyaine/JavaScript30/blob/master/21%20-%20Geolocation/index-finished-Dashrun.html)
-22 | Follow Along Link Highlighter | -
+22 | [Follow Along Link Highlighter指南](https://github.com/soyaine/JavaScript30/blob/master/22%20-%20Follow%20Along%20Link%20Highlighter/README.md) | [Follow Along Link Highlighter效果](https://github.com/soyaine/JavaScript30/blob/master/22%20-%20Follow%20Along%20Link%20Highlighter/index-finished-Dashrun.html)
23 | Speech Synthesis | -
24 | Sticky Nav | -
25 | Event Capture, Propagation, Bubbling, and Once | -
@@ -80,7 +80,7 @@ Name | Contribution
[@DrakeXiang](https://github.com/DrakeXiang) | No.[11](https://github.com/soyaine/JavaScript30/tree/master/11%20-%20Custom%20Video%20Player)
[@zzh466](http://github.com/zzh466) | Review
[@Xing Liu](https://github.com/S1ngS1ng) | Review
-[@大史快跑Dashrun](https://github.com/dashrun) | No.[16](https://github.com/soyaine/JavaScript30/tree/master/16%20-%20Mouse%20Move%20Shadow).[17](https://github.com/soyaine/JavaScript30/tree/master/17%20-%20Sort%20Without%20Articles).[18](https://github.com/soyaine/JavaScript30/tree/master/18%20-%20AddingUpTimesWithReduce).[19](https://github.com/soyaine/JavaScript30/blob/master/19%20-%20Webcam%20Fun).[20](https://github.com/soyaine/JavaScript30/tree/master/20%20-%20Speech%20Detection).[21](https://github.com/soyaine/JavaScript30/tree/master/21%20-%20Geolocation)
+[@大史快跑Dashrun](https://github.com/dashrun) | No.[16](https://github.com/soyaine/JavaScript30/tree/master/16%20-%20Mouse%20Move%20Shadow).[17](https://github.com/soyaine/JavaScript30/tree/master/17%20-%20Sort%20Without%20Articles).[18](https://github.com/soyaine/JavaScript30/tree/master/18%20-%20AddingUpTimesWithReduce).[19](https://github.com/soyaine/JavaScript30/blob/master/19%20-%20Webcam%20Fun).[20](https://github.com/soyaine/JavaScript30/tree/master/20%20-%20Speech%20Detection).[21](https://github.com/soyaine/JavaScript30/tree/master/21%20-%20Geolocation).[22](https://github.com/soyaine/JavaScript30/tree/master/22%20-%20Follow%20Along%20Link%20Highlighter)
[@缉熙Soyaine](https://github.com/soyaine) | No.[1](https://github.com/soyaine/JavaScript30/tree/master/01%20-%20JavaScript%20Drum%20Kit).[2](https://github.com/soyaine/JavaScript30/tree/master/02%20-%20JS%20%2B%20CSS%20Clock).[3](https://github.com/soyaine/JavaScript30/tree/master/03%20-%20CSS%20%Variables).[4](https://github.com/soyaine/JavaScript30/tree/master/04%20-%20Array%20Cardio%20Day%201).[5](https://github.com/soyaine/JavaScript30/blob/master/05%20-%20Flex%20Panel%20Gallery).[6](https://github.com/soyaine/JavaScript30/blob/master/06%20-%20Type%20Ahead).[7](https://github.com/soyaine/JavaScript30/tree/master/07%20-%20Array%20Cardio%20Day%202).[8](https://github.com/soyaine/JavaScript30/tree/master/08%20-%20Fun%20with%20HTML5%20Canvas).[9](https://github.com/soyaine/JavaScript30/blob/master/09%20-%20Dev%20Tools%20Domination).[10](https://github.com/soyaine/JavaScript30/blob/master/10%20-%20Hold%20Shift%20and%20Check%20Checkboxes/README.md).[12](https://github.com/soyaine/JavaScript30/tree/master/12%20-%20Key%20Sequence%20Detection/README.md).[13](https://github.com/soyaine/JavaScript30/blob/master/13%20-%20Slide%20in%20on%20Scroll/README.md).[14](https://github.com/soyaine/JavaScript30/tree/master/14%20-%20JavaScript%20References%20VS%20Copying)
## JOIN US