如何写好JavaScript | 青训营

68 阅读7分钟

写好代js代码的三原则

各司其职

让HTML、CSS和javaScript职能分离

具体案例:深夜食堂

image.png image.png

版本一:js操控css

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>深夜食堂</title>
</head>
<body>
  <header>
    <button id="modeBtn">🌞</button>
    <h1>深夜食堂</h1>
  </header>
  <main>
    <div class="pic">
      <img src="https://p2.ssl.qhimg.com/t0120cc20854dc91c1e.jpg">
    </div>
    <div class="description">
      <p>
          这是一间营业时间从午夜十二点到早上七点的特殊食堂。这里的老板,不太爱说话,却总叫人吃得热泪盈
          眶。在这里,自卑的舞蹈演员偶遇隐退多年舞界前辈,前辈不惜讲述自己不堪回首的经历不断鼓舞年轻人,最终令其重拾自信;轻言绝交的闺蜜因为吃到共同喜爱的美食,回忆起从前的友谊,重归于好;乐观的绝症患者遇到同命相连的女孩,两人相爱并相互给予力量,陪伴彼此完美地走过了最后一程;一味追求事业成功的白领,在这里结交了真正暖心的朋友,发现真情比成功更有意义。食物、故事、真情,汇聚了整部剧的主题,教会人们坦然面对得失,对生活充满期许和热情。每一个故事背后都饱含深情,情节跌宕起伏,令人流连忘返 [6]。
      </p>
    </div>
  </main>
</body>
</html>
body, html {
  width: 100%;
  height: 100%;
  padding: 0;
  margin: 0;
  overflow: hidden;
}
body {
  padding: 10px;
  box-sizing: border-box;
}
div.pic img {
  width: 100%;
}
#modeBtn {
  font-size: 2rem;
  float: right;
  border: none;
  background: transparent;
}
const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
  const body = document.body;
  if(e.target.innerHTML === '🌞') {
    body.style.backgroundColor = 'black';
    body.style.color = 'white';
    e.target.innerHTML = '🌜';
  } else {
    body.style.backgroundColor = 'white';
    body.style.color = 'black';
    e.target.innerHTML = '🌞';
  }
});

对于以上这段代码,主要存在的问题:

  1. 让js去做了css应该做的事,样式和行为没有分离

版本二:使用className控制样式

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>深夜食堂</title>
</head>
<body>
  <header>
    <button id="modeBtn"></button>
    <h1>深夜食堂</h1>
  </header>
  <main>
    <div class="pic">
      <img src="https://p2.ssl.qhimg.com/t0120cc20854dc91c1e.jpg">
    </div>
    <div class="description">
      <p>
          这是一间营业时间从午夜十二点到早上七点的特殊食堂。这里的老板,不太爱说话,却总叫人吃得热泪盈
          眶。在这里,自卑的舞蹈演员偶遇隐退多年舞界前辈,前辈不惜讲述自己不堪回首的经历不断鼓舞年轻人,最终令其重拾自信;轻言绝交的闺蜜因为吃到共同喜爱的美食,回忆起从前的友谊,重归于好;乐观的绝症患者遇到同命相连的女孩,两人相爱并相互给予力量,陪伴彼此完美地走过了最后一程;一味追求事业成功的白领,在这里结交了真正暖心的朋友,发现真情比成功更有意义。食物、故事、真情,汇聚了整部剧的主题,教会人们坦然面对得失,对生活充满期许和热情。每一个故事背后都饱含深情,情节跌宕起伏,令人流连忘返 [6]  。
      </p>
    </div>
  </main>
</body>
</html>
});

body, html {
  width: 100%;
  height: 100%;
  max-width: 600px;
  padding: 0;
  margin: 0;
  overflow: hidden;
}
body {
  padding: 10px;
  box-sizing: border-box;
  transition: all 1s;
}
div.pic img {
  width: 100%;
}
#modeBtn {
  font-size: 2rem;
  float: right;
  border: none;
  outline: none;
  cursor: pointer;
  background: inherit;
}

body.night {
  background-color: black;
  color: white;
  transition: all 1s;
}

#modeBtn::after {
  content: '🌞';
}
body.night #modeBtn::after {
  content: '🌜';
}
const btn = document.getElementById('modeBtn');
btn.addEventListener('click', (e) => {
  const body = document.body;
  if(body.className !== 'night') {
    body.className = 'night';
  } else {
    body.className = '';
  }

版本三:使用纯CSS

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>深夜食堂</title>
</head>
<body>
<input id="modeCheckBox" type="checkbox"
<div class="content">
  <header>
    <label id="modeBtn" for="modeCheckBox"></label>
    <h1>深夜食堂</h1>
  </header>
  <main>
    <div class="pic">
      <img src="https://p2.ssl.qhimg.com/t0120cc20854dc91c1e.jpg">
    </div>
    <div class="description">
      <p>
          这是一间营业时间从午夜十二点到早上七点的特殊食堂。这里的老板,不太爱说话,却总叫人吃得热泪盈
          眶。在这里,自卑的舞蹈演员偶遇隐退多年舞界前辈,前辈不惜讲述自己不堪回首的经历不断鼓舞年轻人,最终令其重拾自信;轻言绝交的闺蜜因为吃到共同喜爱的美食,回忆起从前的友谊,重归于好;乐观的绝症患者遇到同命相连的女孩,两人相爱并相互给予力量,陪伴彼此完美地走过了最后一程;一味追求事业成功的白领,在这里结交了真正暖心的朋友,发现真情比成功更有意义。食物、故事、真情,汇聚了整部剧的主题,教会人们坦然面对得失,对生活充满期许和热情。每一个故事背后都饱含深情,情节跌宕起伏,令人流连忘返 [6]  。
      </p>
    </div>
  </main>
 </div>
</body>
</html>
});
body, html {
  width: 100%;
  height: 100%;
  max-width: 600px;
  padding: 0;
  margin: 0;
  overflow: hidden;
}

body {
  box-sizing: border-box;
}

.content {
  padding: 10px;
  transition: background-color 1s, color 1s;
}

div.pic img {
  width: 100%;
}

#modeCheckBox {
  display: none;
}

/* 当选中时,给其再加个content类 */
#modeCheckBox:checked + .content {
  background-color: black;
  color: white;
  transition: all 1s;
}

#modeBtn {
  font-size: 2rem;
  float: right;
}

#modeBtn::after {
  content: '🌞';
}

/* 当选中时,对content类的内容进行修改 */
#modeCheckBox:checked + .content #modeBtn::after {
  content: '🌜';
}这里

这里#modeCheckBox:checked + .content的意思是当modeCheckBox这个表单被选中即checked的时候,+的意思是给他的兄弟元素(id为content的div)设置css

件封装

好的UI组件具备准确性、扩展性、复用性

什么是组件

组件是指Web页面上抽出来一个个包含模板(HTML)、功能(JS)、和样式(CSS)的单元,好的组件具备封装性、正确性、扩展性、复用性

具体案例:电商网站轮播图

  1. HTML-结构

image.png

image.png

image.png 2. CSS-样式

  • 使用CSS绝对定位将图片重叠在同一个位置
  • 轮播图切换的状态使用修饰符(modifier)
  • 轮播图的切换图片使用CSS transition image.png
  1. API-行为:控制流,使用自定义事件来解耦
  • getSelectedItem()——获取当前选中的图片元素
  • getSelectedItemIndex()——获取当前选中图片元素在列表中的下表
  • slideTo()——跳转到某一个元素
  • slideNex()——向前
  • slidePrevious()——向后 image.png

image.png

总结

组件设计的原则

  • 封装性
  • 正确性
  • 扩展性
  • 复用性

基本方法

  • 结构设计
  • 展现效果
  • 行为设计——API(功能)、Event(控制流)

三次重构

  • 插件化
  • 模板化
  • 抽象化

过程抽象

什么是过程抽象

过程抽象是指通过创建和使用函数来隐藏实现细节并抽象出一系列操作的能力

过程抽象的作用

  • 用来处理局部细节控制的一些方法
  • 函数式编程思想的基础应用

高阶函数

什么是高阶函数

高阶函数是指可以接受一个或多个函数作为参数,并/或返回一个函数的函数。换句话说,它们以函数作为输入或输出的函数被称为高阶函数。

常用高阶函数

  • 防抖函数:是指在一个函数被连续触发时,在一定的时间间隔内,只执行最后一次触发。换句话说,如果在设定的时间间隔内持续触发函数,则重新计时并等待最后一次触发后才执行函数。这可用于处理频繁触发的事件,如输入框的实时搜索,在用户停止输入一段时间后才进行搜索操作,减少不必要的请求或操作。
  • 节流函数:是指在一定的时间间隔内,限制函数的执行频率。节流会确保无论触发频率有多高,函数只会在固定的时间间隔后执行一次。例如,当用户持续滚动页面时,可以使用节流来限制处理滚动事件的操作,以减少处理次数,提高性能。
  • 消费函数consumer:接受一个或多个值作为输入,并执行某些操作、处理或消费这些值的函数。消费函数通常不返回任何结果,而是执行一些副作用,比如打印信息、修改状态、发送网络请求等。
  • 迭代器函数iterative

编程范式

编程方式分为命令式和声明式。命令式更关注怎么做,声明式更关注做什么。js编程既可以使用命令式编程也可以使用声明式编程,但是当代码逻辑较为复杂时,推荐使用声明式编程,这样抽象程度高,扩展性更强。

总结

今天是懵* 的一天,看JavaScript去了 O.o