跳到主要内容

css从0开始

· 阅读需 5 分钟

前言

一直苦于 css 的内容繁多,潜意识回避。但是对于初级前端岗位,重现页面是基本功。所以,决定花几天时间,重学 css。知乎上的回答建议将 css 分为选择器、样式、盒模型、定位四个部分。那么我就按这个路线学一遍,并记录自己容易出错的地方。

选择器

id,类自不必说。

  • 分组/后代/子元素区别
h1,
h2 {
} /*分组*/
h1 h2 {
} /*后代*/
h1 > h2 {
} /*子元素*/
  • 兄弟选择器
h1 + h2 {
} /*兄弟选择器有两种,这种是相邻兄弟选择器,只选择到了h2*/
h1 ~ h2 {
} /*通用兄弟选择器,选择h1所有的兄弟h2*/
  • 属性选择器
a[href] {
} /*模仿了其他语言对象属性的表达方式,选择有href属性的a标签*/
  • 伪类选择器
a:link {
} /*语法特点:单个冒号,后面表示标签的状态。常见的:p:first-child, nth-child(n)*/
  • 伪元素选择器
div::before{} /*指定元素的某一部分,一共5种伪元素选择器*/


选择器 例子 例子描述
::after p::after 在每个 <p> 元素之后插入内容。
::before p::before 在每个 <p> 元素之前插入内容。
::first-letter p::first-letter 选择每个 <p> 元素的首字母。
::first-line p::first-line 选择每个 <p> 元素的首行。
::selection p::selection 选择用户选择的元素部分。
  • 一个大坑
.class1.class2
同时属于两类的元素
.class1
.class2
属于class1的元素的后代里,属于class2的;
  • 总结 没什么,背住!

样式

这部分一般面试不问,使用时查找即可。

  • background 一种是颜色背景,一种是图片背景。后者需要设置一些属性,写法上应该都采取简写:
body {
background: #ffffff url("tree.png") no-repeat right top;
}
  • text 文本对齐
text-align:left\right\justify
vertical-align:top\middle\button
  • line-height 一张图说明

  • 一些坑

要实现文本的水平垂直居中对齐,可以分别设置

text-align: center;
line-height: //box height;;

盒模型

面试重点!应该牢牢掌握。

  • padding 内边距,空白透明,只能设置长度。顺便记录一下非常重要的浏览器长度单位: 可分为绝对单位和相对单位, 绝对:

    • px. 最基础的
    • in\cm\mm 计算机中都会转成 px。

    相对:

    • em: 相对于父元素字体大小的倍数, 百分号也是基于父元素
    • rem: 相对于根节点 html(16px).rem 用的更多,因为它不需要层层换算。
    • vw/vh:基于可视区域,1vw=可视区宽度的 1%
  • border 牵涉到上下左右的问题,出于简便的考虑,应该采用简写形式。

p {
border: 5px solid red; /**如果要设置某一侧边框的样式,应该写border-left: xxxx */
}
  • margin margin 和 padding 书写方式很像,但是操蛋的是 auto。auto 表示自动计算应得的空间。所以可以实现居中操作。

定位

最复杂和让人蛋疼的部分。

  • position 要想让元素移动,除了要设置 position, 还要设置 top\left 等数值

    position: relative/absolute/fixed;
    • relative 相对于其原来位置移动,不脱离文档流

    • absolute 相对于最近的有定位的祖先元素移动,脱离了文档流

    • 子绝父相:本质上是父元素不脱离文档流,而子元素可以在父元素内方便得改变位置

  • float

    float: left/right/none/inherit;

    浮动的框可以向左或向右移动,直到它的外边缘碰到包含框或另一个浮动框的边框为止。 由于浮动框不在文档的普通流中,所以文档的普通流中的块框表现得就像浮动框不存在一样。

  • flexbox flex 比 float+position 组合好用多了。

先写到这里吧,flex 另开一个新坑。

nodejs构建服务器

· 阅读需 2 分钟

从nodejs服务器想到的

服务器的定义是,监听请求,处理请求和做出响应。除了nodejs外,其他语言也有对应的web server框架,比如java的tomcat。

用下列代码实现一个简单的服务器:

var http = require('http')
var fs = require('fs')
http.createServer(function (request, response) {
fs.readFile('1.txt', (err, data)=>{
response.setHeader("Access-Control-Allow-Origin", "*")
response.end(data)
})
}).listen(3000, function () {
console.log('running')
})

用node命令执行上述代码后,就可以发送请求了。我们总说请求,可是请求究竟有哪些类型呢?网上将http请求分为get\post等8种类型,我觉得,从另一个角度,可以分为全局型和局部型。全局型是浏览器输入框改变,则会发起请求,并刷新页面。而局部型如ajax,只更新dom树几个节点的内容,不刷新页面。

全局型请求,是通过更改末尾地址实现。而上面的代码对于所有请求的响应都相同。所以,可以通过路由分发来实现不同地址响应。

JS之Promise

· 阅读需 6 分钟

为什么需要 promise

首先,存在一次异步任务的需求。然后又有了多次异步任务的需求,而多次异步的书写存在函数瀑布问题,不利于阅读和维护:

setTimeout(function () {
console.log("First");
setTimeout(function () {
console.log("Second");
setTimeout(function () {
console.log("Third");
}, 3000);
}, 4000);
}, 1000);

所以,出现了 promise 对象,将多次异步代码写成顺序格式而非嵌套格式:

function print(delay, message) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
console.log(message);
resolve();
}, delay);
});
}
print(1000, "First")
.then(function () {
return print(4000, "Second");
})
.then(function () {
print(3000, "Third");
});

因此,异步是异步,promise 是 promise,异步任务的实现靠的是 javascript 的事件循环机制,而不是 promise,promise 仅是改变了需要按顺序执行的多个异步任务的书写格式。

promise 的本质

Promise 是一个构造函数,它接收一个函数作为形参,实例化一个 p 对象。相比于普通对象,p 对象有两个特殊属性:状态和结果。

状态

通过在形参函数中调用 resolve()和 reject()改变状态,并且只能改一次.状态有三种,分别是 pending/fullfilled/reject.没执行 resolve() or reject()之前的状态是 pending。

结果

通过 resolve/reject 函数传递参数,改变当前 promise 对象结果

const p = new Promise((resolve, reject) => {
resolve("homo");
});
console.log(p); // state:fullfilled, result:'homo'

构造函数和 then 方法

promise 是靠多个 then 完成多个异步任务的按顺序执行的。怎么实现的?then 可以注册 resolve 和 reject。若要嵌套,要写成下面这种形式,return 一个新的 promise,value 在异步代码中使用。

new Promise((resolve) => {
// setTimeout(()=>{
// resolve('1')
// },500)
})
.then((value) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(value + " 2");
});
});
})
.then((value) => {
// console.log(value);
});

把 promise 对象当作一个容器,里面装了一个异步事件,promise 对象保证了当前异步事件执行完毕才会执行下一个事件。

  1. 构造实例 构造函数接受一个函数作为参数 调用构造函数得到实例 p 的同时,作为参数的函数会立即执行 参数函数接受两个回调函数参数 resolve 和 reject 在参数函数被执行的过程中,如果在其内部调用 resolve,会将 p 的状态变成 fulfilled,或者调用 reject,会将 p 的状态变成 rejected

  2. 调用.then 调用.then 可以为实例 p 注册两种状态回调函数 当实例 p 的状态为 fulfilled,会触发第一个函数执行 当实例 p 的状态为 rejected,则触发第二个函数执行

如果代码执行出现错误,而没有 catch 或者 then 接受错误的话,控制台会报错。

下面的代码可以充分体现了,promise 对象解决了异步函数的多重回调问题。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
<script>
function getData(url, data={}){
return new Promise((resolve, reject)=>{
$.ajax({
type:'GET',
url:url,
data:data,
success:function(res){
const {result} = res
console.log(res);
resolve(result)
}
})
})
}

getData('data1.json').then((value)=>{
getData('data2.json', value)
} )
</script>
</body>
</html>

Promise.all()

作用:一次接受多个异步事件,并保证他们的都得到结果了,才会执行 then 输入参数:数组、map 等 输出:一个新的 promise 对象,根据数组中所有 promise 的执行结果而进入不同的函数。若数组中所有的 promise 都是 fullfilled,则会执行 then。

Promise.any()

作用:一次接受多个异步事件,其中有一个成功就行 输入参数:数组、map 等

Promise.resolve(p)/reject(p)

返回一个状态为 fullfilled/rejected,结果为 p 的 promise 对象。

Hello World!

· 阅读需 1 分钟

记录一下本网站的建立过程

首先,本网站是一个静态博客,基于 GitHub pages 提供的免费服务器,域名在 Namesilo 上购买,页面管理器为基于 nodejs 的 hexo, 总花费¥ 6.72/year. 建站第一天,感觉访问速度还可以。因为在国外买的域名,还不用备案,很爽,all for freedom.

日常管理上,需要发布新文章时,在 Git Bash 上执行下列流程:

    hexo new "title"
hexo g
hexo s
hexo d

如果后期网站外观固定下来,维护起来还是很省心的,nice。