技术遐想(一)
从昨天开始,就决定手写一个 Cheatsheet 网站,仿照 OverAPI。起因是想找到一个页面,能够看到 JS 相关所有理论知识,一搜索就找到了它,很喜欢这种样式。于是仿写的想法就产生了。
有三点需要记录下来:
一、怎样形成适合自己的解决问题的方法论?
最重要的一点:知道自己想要什么。比如说,我想知道怎样用 CSS 画一个正方形,我就会搜索"CSS square",搜索结果就是答案。再比如,我想知道 JavaScript 的基础概念都有哪些,我试过直接搜索"JS basic concepts",结果的确有哪些基础念,但这可能并非我真正需要的。
我在解决问题的时候,并没有对问题的本质进行思考。就用上一段的两个例子来说,前者很明确,就是想用 CSS 画个正方形;后者却不那么具体,"基础概念"一词,每个人的理解都不一样,所以我找到的答案都是 别人认为的基础概念 。刚开始学习一门语言的时候,我不知道哪些是基础概念,哪些只是需要了解,这个时候了解已经掌握这门语言的人,他们是怎样学习的,就很重要。之后再思考:掌握一门语言的关键在哪里(数据类型,函数)。
遇到问题,怎样进行分析?
- 你要知道,这个问题是否真的是个问题。因为有时,我们会误以为这是个很困难的问题,直到解决了那一刻才意识到,原来这么容易就能解决。为什么我们没有在最开始就想到这一点?可能的原因就是,没有对问题的本质进行探讨。还是上文想知道 JS 基本概念的例子,其实我并不只是想知道 JS 的基本概念,我还想了解语言的整体,我要知道它有哪些部分构成,分别都起什么作用。这就是在 What 层面上的思考,即它是否是一个问题。
- How 层面。这个问题是怎样产生的?代码层面,能不能做一个最小 demo 把问题复现。
- Why 层面。问题出现了,为什么会在这里出现这样的问题,是否了解了足够多的背景信息?官方文档是否逐字句阅读过?
- 还有其他需要思考之处:在解决问题的过程中,你能查阅哪些资料,我知道的有 MDN,GitHub,搜索引擎;你有没有找到更好的解决办法;为了不让自己重复解决相同或类似的问题,写成博客或是记笔记就是一个好办法;通过这次问题,学习到了哪些东西。
致谢:
二、给定一个颜色数组,如何让它和网页中的目标元素一一对应
1 const rgbas = [
2 "rgba(251,34,240,0.25)",
3 "rgba(214,17,21,0.25)",
4 "rgba(14,251,252,0.25)",
5 "rgba(158,134,255,0.25)",
6 "rgba(60,255,20,0.25)",
7 "rgba(44,158,52,0.25)",
8 "rgba(225,211,20,0.25)",
9 "rgba(100,117,121,0.25)",
10 ];
11 const boards = document.getElementsByClassName("board");
12
13 rgbas.forEach(() => {
14 for (let i = 0; i < boards.length; i++) {
15 boards[i].style.backgroundColor = rgbas[i];
16 }
17 })
- 定义了颜色数组 rgbas[8]
- 将第一个颜色分配给第一个 board 元素;第二个颜色分配给第二个 board 元素;以此类推
下面赋值的部分还有另一种写法:
1 for (let i = 0; i < rgbas.length; i++) {
2 for (let j = 0; j < boards.length; j++) {
3 ...
4 }
5 }
最开始想出的代码是这个样子:
1 for (let j = 0; j < rgbas.length; j++) {
2 for (let i = 0; i < boards.length; i++) {
3 boards[i].style.backgroundColor = rgbas[j];
4 }
5 }
想实现上述效果,但却发现:每一个 board 都有相同的背景色,思考一会儿才发现,如果这样写就会把颜色数组 rgbas 的最后一个颜色元素赋值给每一个 board。
致谢:main.js
三、怎样在多个页面应用相同的 HTML
我接触到一个概念——Web Components。在制作网站时,在很多页面都会共用同一个 header 和 footer,Web Components 就是帮助我们复用这些共同代码的。
index.html
:
<!DOCTYPE html> <html> <head> ... <script src="./components/header.js" defer></script> </head> <body> <header-component></header-component> </body> </html>
./components/header.js
:
1 const headerTemplate = document.createElement("template");
2
3 headerTemplate.innerHTML = `
4 <style>
5 header {
6 background: rgba(0, 0, 0, 0.6);
7 color: #999;
8 width: 100%;
9 z-index: 2;
10 display: flex;
11 }
12
13 header a {
14 text-decoration: none;
15 color: #fff;
16 outline: none;
17 }
18 header a:visited {
19 color: #999;
20 }
21 header a:hover {
22 color: #fff;
23 }
24
25 header a#logo {
26 color: #fff;
27 font-size: 18px;
28 font-weight: bold;
29 margin: 0;
30 padding: 15px;
31 text-align: center;
32 }
33
34 header ul {
35 display: flex;
36
37 }
38 ul li {
39 margin-right: 5px;
40 padding: 0 5px;
41 list-style-type: none;
42 }
43 ul li a {
44 display: block;
45 }
46 </style>
47 <header>
48 <a href="/" id="logo">Home</a>
49 <ul>
50 <li><a href="javascript.html">JavaScript</a></li>
51 <li><a href="css.html">CSS</a></li>
52 <li><a href="html.html">HTML</a></li>
53 <li><a href="developer-tools.html">Developer Tools</a></li>
54 </ul>
55 </header>
56 `;
57
58 class Header extends HTMLElement {
59 constructor() {
60 super();
61 }
62
63 connectedCallback() {
64 const shadowRoot = this.attachShadow({ mode: "closed" });
65
66 shadowRoot.appendChild(headerTemplate.content);
67 }
68 }
69
70 customElements.define("header-component", Header);
实现一个 Web Component 的一般步骤:
- 对现有 Class 的功能进行扩展,创建自己的 Class
- 使用 CustomElementRegistry.define() 方法注册你的自定义标签
- 如果需要,附加 shadow DOM 到自定义元素中
- 如果需要,使用 <template> 和 <slot> 定义 HTML 模板。再一次使用常规 DOM 方法克隆模板,并把它附加在你的 shadow DOM 下
- 你可以在任何你需要的页面使用你的自定义标签
致谢: